From 599c137fd3d522793dc022644b8b6566b75628cb Mon Sep 17 00:00:00 2001 From: Lorenz Kästle <12514511+RincewindsHat@users.noreply.github.com> Date: Thu, 20 Feb 2025 17:11:06 +0100 Subject: clang-format --- plugins/check_mysql.c | 603 +++++++++++++++++++++++--------------------------- 1 file changed, 282 insertions(+), 321 deletions(-) diff --git a/plugins/check_mysql.c b/plugins/check_mysql.c index 8a73772d..09c0b7dd 100644 --- a/plugins/check_mysql.c +++ b/plugins/check_mysql.c @@ -1,34 +1,34 @@ /***************************************************************************** -* -* Monitoring check_mysql plugin -* -* License: GPL -* Copyright (c) 1999 Didi Rieder (adrieder@sbox.tu-graz.ac.at) -* Copyright (c) 2000 Karl DeBisschop (kdebisschop@users.sourceforge.net) -* Copyright (c) 1999-2024 Monitoring Plugins Development Team -* -* Description: -* -* This file contains the check_mysql plugin -* -* This program tests connections to a mysql server -* -* -* This program is free software: you can redistribute it and/or modify -* it under the terms of the GNU General Public License as published by -* the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU General Public License for more details. -* -* You should have received a copy of the GNU General Public License -* along with this program. If not, see . -* -* -*****************************************************************************/ + * + * Monitoring check_mysql plugin + * + * License: GPL + * Copyright (c) 1999 Didi Rieder (adrieder@sbox.tu-graz.ac.at) + * Copyright (c) 2000 Karl DeBisschop (kdebisschop@users.sourceforge.net) + * Copyright (c) 1999-2024 Monitoring Plugins Development Team + * + * Description: + * + * This file contains the check_mysql plugin + * + * This program tests connections to a mysql server + * + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + * + *****************************************************************************/ const char *progname = "check_mysql"; const char *copyright = "1999-2024"; @@ -68,39 +68,24 @@ static double critical_time = 0; #define LENGTH_METRIC_UNIT 6 static const char *metric_unit[LENGTH_METRIC_UNIT] = { - "Open_files", - "Open_tables", - "Qcache_free_memory", - "Qcache_queries_in_cache", - "Threads_connected", - "Threads_running" -}; + "Open_files", "Open_tables", "Qcache_free_memory", "Qcache_queries_in_cache", "Threads_connected", "Threads_running"}; #define LENGTH_METRIC_COUNTER 9 static const char *metric_counter[LENGTH_METRIC_COUNTER] = { - "Connections", - "Qcache_hits", - "Qcache_inserts", - "Qcache_lowmem_prunes", - "Qcache_not_cached", - "Queries", - "Questions", - "Table_locks_waited", - "Uptime" -}; - -#define MYSQLDUMP_THREADS_QUERY "SELECT COUNT(1) mysqldumpThreads FROM information_schema.processlist WHERE info LIKE 'SELECT /*!40001 SQL_NO_CACHE */%'" + "Connections", "Qcache_hits", "Qcache_inserts", "Qcache_lowmem_prunes", "Qcache_not_cached", "Queries", + "Questions", "Table_locks_waited", "Uptime"}; + +#define MYSQLDUMP_THREADS_QUERY \ + "SELECT COUNT(1) mysqldumpThreads FROM information_schema.processlist WHERE info LIKE 'SELECT /*!40001 SQL_NO_CACHE */%'" static thresholds *my_threshold = NULL; -static int process_arguments (int, char **); -static int validate_arguments (void); -static void print_help (void); -void print_usage (void); +static int process_arguments(int, char **); +static int validate_arguments(void); +static void print_help(void); +void print_usage(void); -int -main (int argc, char **argv) -{ +int main(int argc, char **argv) { MYSQL mysql; MYSQL_RES *res; @@ -110,152 +95,152 @@ main (int argc, char **argv) char *result = NULL; char *error = NULL; - char slaveresult[SLAVERESULTSIZE] = { 0 }; - char* perf; + char slaveresult[SLAVERESULTSIZE] = {0}; + char *perf; - perf = strdup (""); + perf = strdup(""); - setlocale (LC_ALL, ""); - bindtextdomain (PACKAGE, LOCALEDIR); - textdomain (PACKAGE); + setlocale(LC_ALL, ""); + bindtextdomain(PACKAGE, LOCALEDIR); + textdomain(PACKAGE); /* Parse extra opts if any */ - argv=np_extra_opts (&argc, argv, progname); + argv = np_extra_opts(&argc, argv, progname); - if (process_arguments (argc, argv) == ERROR) - usage4 (_("Could not parse arguments")); + if (process_arguments(argc, argv) == ERROR) { + usage4(_("Could not parse arguments")); + } /* initialize mysql */ - mysql_init (&mysql); - - if (opt_file != NULL) - mysql_options(&mysql,MYSQL_READ_DEFAULT_FILE,opt_file); - - if (opt_group != NULL) - mysql_options(&mysql,MYSQL_READ_DEFAULT_GROUP,opt_group); - else - mysql_options(&mysql,MYSQL_READ_DEFAULT_GROUP,"client"); - - if (ssl) - mysql_ssl_set(&mysql,key,cert,ca_cert,ca_dir,ciphers); + mysql_init(&mysql); + + if (opt_file != NULL) { + mysql_options(&mysql, MYSQL_READ_DEFAULT_FILE, opt_file); + } + + if (opt_group != NULL) { + mysql_options(&mysql, MYSQL_READ_DEFAULT_GROUP, opt_group); + } else { + mysql_options(&mysql, MYSQL_READ_DEFAULT_GROUP, "client"); + } + + if (ssl) { + mysql_ssl_set(&mysql, key, cert, ca_cert, ca_dir, ciphers); + } /* establish a connection to the server and error checking */ - if (!mysql_real_connect(&mysql,db_host,db_user,db_pass,db,db_port,db_socket,0)) { + if (!mysql_real_connect(&mysql, db_host, db_user, db_pass, db, db_port, db_socket, 0)) { /* Depending on internally-selected auth plugin MySQL might return */ /* ER_ACCESS_DENIED_NO_PASSWORD_ERROR or ER_ACCESS_DENIED_ERROR. */ /* Semantically these errors are the same. */ - if (ignore_auth && (mysql_errno (&mysql) == ER_ACCESS_DENIED_ERROR || mysql_errno (&mysql) == ER_ACCESS_DENIED_NO_PASSWORD_ERROR)) - { - printf("MySQL OK - Version: %s (protocol %d)\n", - mysql_get_server_info(&mysql), - mysql_get_proto_info(&mysql) - ); - mysql_close (&mysql); + if (ignore_auth && (mysql_errno(&mysql) == ER_ACCESS_DENIED_ERROR || mysql_errno(&mysql) == ER_ACCESS_DENIED_NO_PASSWORD_ERROR)) { + printf("MySQL OK - Version: %s (protocol %d)\n", mysql_get_server_info(&mysql), mysql_get_proto_info(&mysql)); + mysql_close(&mysql); return STATE_OK; + } else if (mysql_errno(&mysql) == CR_UNKNOWN_HOST) { + die(STATE_WARNING, "%s\n", mysql_error(&mysql)); + } else if (mysql_errno(&mysql) == CR_VERSION_ERROR) { + die(STATE_WARNING, "%s\n", mysql_error(&mysql)); + } else if (mysql_errno(&mysql) == CR_OUT_OF_MEMORY) { + die(STATE_WARNING, "%s\n", mysql_error(&mysql)); + } else if (mysql_errno(&mysql) == CR_IPSOCK_ERROR) { + die(STATE_WARNING, "%s\n", mysql_error(&mysql)); + } else if (mysql_errno(&mysql) == CR_SOCKET_CREATE_ERROR) { + die(STATE_WARNING, "%s\n", mysql_error(&mysql)); + } else { + die(STATE_CRITICAL, "%s\n", mysql_error(&mysql)); } - else if (mysql_errno (&mysql) == CR_UNKNOWN_HOST) - die (STATE_WARNING, "%s\n", mysql_error (&mysql)); - else if (mysql_errno (&mysql) == CR_VERSION_ERROR) - die (STATE_WARNING, "%s\n", mysql_error (&mysql)); - else if (mysql_errno (&mysql) == CR_OUT_OF_MEMORY) - die (STATE_WARNING, "%s\n", mysql_error (&mysql)); - else if (mysql_errno (&mysql) == CR_IPSOCK_ERROR) - die (STATE_WARNING, "%s\n", mysql_error (&mysql)); - else if (mysql_errno (&mysql) == CR_SOCKET_CREATE_ERROR) - die (STATE_WARNING, "%s\n", mysql_error (&mysql)); - else - die (STATE_CRITICAL, "%s\n", mysql_error (&mysql)); } /* get the server stats */ - result = strdup (mysql_stat (&mysql)); + result = strdup(mysql_stat(&mysql)); /* error checking once more */ - if (mysql_error (&mysql)) { - if (mysql_errno (&mysql) == CR_SERVER_GONE_ERROR) - die (STATE_CRITICAL, "%s\n", mysql_error (&mysql)); - else if (mysql_errno (&mysql) == CR_SERVER_LOST) - die (STATE_CRITICAL, "%s\n", mysql_error (&mysql)); - else if (mysql_errno (&mysql) == CR_UNKNOWN_ERROR) - die (STATE_CRITICAL, "%s\n", mysql_error (&mysql)); + if (mysql_error(&mysql)) { + if (mysql_errno(&mysql) == CR_SERVER_GONE_ERROR) { + die(STATE_CRITICAL, "%s\n", mysql_error(&mysql)); + } else if (mysql_errno(&mysql) == CR_SERVER_LOST) { + die(STATE_CRITICAL, "%s\n", mysql_error(&mysql)); + } else if (mysql_errno(&mysql) == CR_UNKNOWN_ERROR) { + die(STATE_CRITICAL, "%s\n", mysql_error(&mysql)); + } } /* try to fetch some perf data */ - if (mysql_query (&mysql, "show global status") == 0) { - if ( (res = mysql_store_result (&mysql)) == NULL) { + if (mysql_query(&mysql, "show global status") == 0) { + if ((res = mysql_store_result(&mysql)) == NULL) { error = strdup(mysql_error(&mysql)); - mysql_close (&mysql); - die (STATE_CRITICAL, _("status store_result error: %s\n"), error); + mysql_close(&mysql); + die(STATE_CRITICAL, _("status store_result error: %s\n"), error); } - while ( (row = mysql_fetch_row (res)) != NULL) { + while ((row = mysql_fetch_row(res)) != NULL) { int i; - for(i = 0; i < LENGTH_METRIC_UNIT; i++) { + for (i = 0; i < LENGTH_METRIC_UNIT; i++) { if (strcmp(row[0], metric_unit[i]) == 0) { - xasprintf(&perf, "%s%s ", perf, perfdata(metric_unit[i], - atol(row[1]), "", false, 0, false, 0, false, 0, false, 0)); + xasprintf(&perf, "%s%s ", perf, perfdata(metric_unit[i], atol(row[1]), "", false, 0, false, 0, false, 0, false, 0)); continue; } } - for(i = 0; i < LENGTH_METRIC_COUNTER; i++) { + for (i = 0; i < LENGTH_METRIC_COUNTER; i++) { if (strcmp(row[0], metric_counter[i]) == 0) { - xasprintf(&perf, "%s%s ", perf, perfdata(metric_counter[i], - atol(row[1]), "c", false, 0, false, 0, false, 0, false, 0)); + xasprintf(&perf, "%s%s ", perf, perfdata(metric_counter[i], atol(row[1]), "c", false, 0, false, 0, false, 0, false, 0)); continue; } } } /* remove trailing space */ - if (strlen(perf) > 0) - perf[strlen(perf) - 1] = '\0'; + if (strlen(perf) > 0) { + perf[strlen(perf) - 1] = '\0'; + } } - if(check_slave) { + if (check_slave) { /* check the slave status */ - if (mysql_query (&mysql, "show slave status") != 0) { + if (mysql_query(&mysql, "show slave status") != 0) { error = strdup(mysql_error(&mysql)); - mysql_close (&mysql); - die (STATE_CRITICAL, _("slave query error: %s\n"), error); + mysql_close(&mysql); + die(STATE_CRITICAL, _("slave query error: %s\n"), error); } /* store the result */ - if ( (res = mysql_store_result (&mysql)) == NULL) { + if ((res = mysql_store_result(&mysql)) == NULL) { error = strdup(mysql_error(&mysql)); - mysql_close (&mysql); - die (STATE_CRITICAL, _("slave store_result error: %s\n"), error); + mysql_close(&mysql); + die(STATE_CRITICAL, _("slave store_result error: %s\n"), error); } /* Check there is some data */ if (mysql_num_rows(res) == 0) { mysql_close(&mysql); - die (STATE_WARNING, "%s\n", _("No slaves defined")); + die(STATE_WARNING, "%s\n", _("No slaves defined")); } /* fetch the first row */ - if ( (row = mysql_fetch_row (res)) == NULL) { + if ((row = mysql_fetch_row(res)) == NULL) { error = strdup(mysql_error(&mysql)); - mysql_free_result (res); - mysql_close (&mysql); - die (STATE_CRITICAL, _("slave fetch row error: %s\n"), error); + mysql_free_result(res); + mysql_close(&mysql); + die(STATE_CRITICAL, _("slave fetch row error: %s\n"), error); } - if (mysql_field_count (&mysql) == 12) { + if (mysql_field_count(&mysql) == 12) { /* mysql 3.23.x */ - snprintf (slaveresult, SLAVERESULTSIZE, _("Slave running: %s"), row[6]); - if (strcmp (row[6], "Yes") != 0) { - mysql_free_result (res); - mysql_close (&mysql); - die (STATE_CRITICAL, "%s\n", slaveresult); + snprintf(slaveresult, SLAVERESULTSIZE, _("Slave running: %s"), row[6]); + if (strcmp(row[6], "Yes") != 0) { + mysql_free_result(res); + mysql_close(&mysql); + die(STATE_CRITICAL, "%s\n", slaveresult); } } else { /* mysql 4.x.x and mysql 5.x.x */ - int slave_io_field = -1 , slave_sql_field = -1, seconds_behind_field = -1, i, num_fields; - MYSQL_FIELD* fields; + int slave_io_field = -1, slave_sql_field = -1, seconds_behind_field = -1, i, num_fields; + MYSQL_FIELD *fields; num_fields = mysql_num_fields(res); fields = mysql_fetch_fields(res); - for(i = 0; i < num_fields; i++) { + for (i = 0; i < num_fields; i++) { if (strcmp(fields[i].name, "Slave_IO_Running") == 0) { slave_io_field = i; continue; @@ -272,60 +257,59 @@ main (int argc, char **argv) /* Check if slave status is available */ if ((slave_io_field < 0) || (slave_sql_field < 0) || (num_fields == 0)) { - mysql_free_result (res); - mysql_close (&mysql); - die (STATE_CRITICAL, "Slave status unavailable\n"); + mysql_free_result(res); + mysql_close(&mysql); + die(STATE_CRITICAL, "Slave status unavailable\n"); } /* Save slave status in slaveresult */ - snprintf (slaveresult, SLAVERESULTSIZE, "Slave IO: %s Slave SQL: %s Seconds Behind Master: %s", row[slave_io_field], row[slave_sql_field], seconds_behind_field!=-1?row[seconds_behind_field]:"Unknown"); + snprintf(slaveresult, SLAVERESULTSIZE, "Slave IO: %s Slave SQL: %s Seconds Behind Master: %s", row[slave_io_field], + row[slave_sql_field], seconds_behind_field != -1 ? row[seconds_behind_field] : "Unknown"); /* Raise critical error if SQL THREAD or IO THREAD are stopped, but only if there are no mysqldump threads running */ - if (strcmp (row[slave_io_field], "Yes") != 0 || strcmp (row[slave_sql_field], "Yes") != 0) { + if (strcmp(row[slave_io_field], "Yes") != 0 || strcmp(row[slave_sql_field], "Yes") != 0) { MYSQL_RES *res_mysqldump; MYSQL_ROW row_mysqldump; unsigned int mysqldump_threads = 0; - if (mysql_query (&mysql, MYSQLDUMP_THREADS_QUERY) == 0) { + if (mysql_query(&mysql, MYSQLDUMP_THREADS_QUERY) == 0) { /* store the result */ - if ( (res_mysqldump = mysql_store_result (&mysql)) != NULL) { + if ((res_mysqldump = mysql_store_result(&mysql)) != NULL) { if (mysql_num_rows(res_mysqldump) == 1) { - if ( (row_mysqldump = mysql_fetch_row (res_mysqldump)) != NULL) { + if ((row_mysqldump = mysql_fetch_row(res_mysqldump)) != NULL) { mysqldump_threads = atoi(row_mysqldump[0]); } } /* free the result */ - mysql_free_result (res_mysqldump); + mysql_free_result(res_mysqldump); } - mysql_close (&mysql); + mysql_close(&mysql); } if (mysqldump_threads == 0) { - die (STATE_CRITICAL, "%s\n", slaveresult); + die(STATE_CRITICAL, "%s\n", slaveresult); } else { - strncat(slaveresult, " Mysqldump: in progress", SLAVERESULTSIZE-1); + strncat(slaveresult, " Mysqldump: in progress", SLAVERESULTSIZE - 1); } } - if (verbose >=3) { + if (verbose >= 3) { if (seconds_behind_field == -1) { printf("seconds_behind_field not found\n"); } else { - printf ("seconds_behind_field(index %d)=%s\n", seconds_behind_field, row[seconds_behind_field]); + printf("seconds_behind_field(index %d)=%s\n", seconds_behind_field, row[seconds_behind_field]); } } /* Check Seconds Behind against threshold */ - if ((seconds_behind_field != -1) && (row[seconds_behind_field] != NULL && strcmp (row[seconds_behind_field], "NULL") != 0)) { + if ((seconds_behind_field != -1) && (row[seconds_behind_field] != NULL && strcmp(row[seconds_behind_field], "NULL") != 0)) { double value = atof(row[seconds_behind_field]); int status; status = get_status(value, my_threshold); - xasprintf (&perf, "%s %s", perf, fperfdata ("seconds behind master", value, "s", - true, (double) warning_time, - true, (double) critical_time, - false, 0, - false, 0)); + xasprintf(&perf, "%s %s", perf, + fperfdata("seconds behind master", value, "s", true, (double)warning_time, true, (double)critical_time, false, 0, + false, 0)); if (status == STATE_WARNING) { printf("SLOW_SLAVE %s: %s|%s\n", _("WARNING"), slaveresult, perf); @@ -338,82 +322,66 @@ main (int argc, char **argv) } /* free the result */ - mysql_free_result (res); + mysql_free_result(res); } /* close the connection */ - mysql_close (&mysql); + mysql_close(&mysql); /* print out the result of stats */ if (check_slave) { - printf ("%s %s|%s\n", result, slaveresult, perf); + printf("%s %s|%s\n", result, slaveresult, perf); } else { - printf ("%s|%s\n", result, perf); + printf("%s|%s\n", result, perf); } return STATE_OK; } - /* process command-line arguments */ -int -process_arguments (int argc, char **argv) -{ +int process_arguments(int argc, char **argv) { int c; char *warning = NULL; char *critical = NULL; int option = 0; - static struct option longopts[] = { - {"hostname", required_argument, 0, 'H'}, - {"socket", required_argument, 0, 's'}, - {"database", required_argument, 0, 'd'}, - {"username", required_argument, 0, 'u'}, - {"password", required_argument, 0, 'p'}, - {"file", required_argument, 0, 'f'}, - {"group", required_argument, 0, 'g'}, - {"port", required_argument, 0, 'P'}, - {"critical", required_argument, 0, 'c'}, - {"warning", required_argument, 0, 'w'}, - {"check-slave", no_argument, 0, 'S'}, - {"ignore-auth", no_argument, 0, 'n'}, - {"verbose", no_argument, 0, 'v'}, - {"version", no_argument, 0, 'V'}, - {"help", no_argument, 0, 'h'}, - {"ssl", no_argument, 0, 'l'}, - {"ca-cert", optional_argument, 0, 'C'}, - {"key", required_argument,0,'k'}, - {"cert", required_argument,0,'a'}, - {"ca-dir", required_argument, 0, 'D'}, - {"ciphers", required_argument, 0, 'L'}, - {0, 0, 0, 0} - }; - - if (argc < 1) + static struct option longopts[] = {{"hostname", required_argument, 0, 'H'}, {"socket", required_argument, 0, 's'}, + {"database", required_argument, 0, 'd'}, {"username", required_argument, 0, 'u'}, + {"password", required_argument, 0, 'p'}, {"file", required_argument, 0, 'f'}, + {"group", required_argument, 0, 'g'}, {"port", required_argument, 0, 'P'}, + {"critical", required_argument, 0, 'c'}, {"warning", required_argument, 0, 'w'}, + {"check-slave", no_argument, 0, 'S'}, {"ignore-auth", no_argument, 0, 'n'}, + {"verbose", no_argument, 0, 'v'}, {"version", no_argument, 0, 'V'}, + {"help", no_argument, 0, 'h'}, {"ssl", no_argument, 0, 'l'}, + {"ca-cert", optional_argument, 0, 'C'}, {"key", required_argument, 0, 'k'}, + {"cert", required_argument, 0, 'a'}, {"ca-dir", required_argument, 0, 'D'}, + {"ciphers", required_argument, 0, 'L'}, {0, 0, 0, 0}}; + + if (argc < 1) { return ERROR; + } while (1) { - c = getopt_long (argc, argv, "hlvVnSP:p:u:d:H:s:c:w:a:k:C:D:L:f:g:", longopts, &option); + c = getopt_long(argc, argv, "hlvVnSP:p:u:d:H:s:c:w:a:k:C:D:L:f:g:", longopts, &option); - if (c == -1 || c == EOF) + if (c == -1 || c == EOF) { break; + } switch (c) { - case 'H': /* hostname */ - if (is_host (optarg)) { + case 'H': /* hostname */ + if (is_host(optarg)) { db_host = optarg; - } - else if (*optarg == '/') { + } else if (*optarg == '/') { db_socket = optarg; - } - else { - usage2 (_("Invalid hostname/address"), optarg); + } else { + usage2(_("Invalid hostname/address"), optarg); } break; - case 's': /* socket */ + case 's': /* socket */ db_socket = optarg; break; - case 'd': /* database */ + case 'd': /* database */ db = optarg; break; case 'l': @@ -434,10 +402,10 @@ process_arguments (int argc, char **argv) case 'L': ciphers = optarg; break; - case 'u': /* username */ + case 'u': /* username */ db_user = optarg; break; - case 'p': /* authentication information: password */ + case 'p': /* authentication information: password */ db_pass = strdup(optarg); /* Delete the password from process list */ @@ -446,40 +414,40 @@ process_arguments (int argc, char **argv) optarg++; } break; - case 'f': /* client options file */ + case 'f': /* client options file */ opt_file = optarg; break; - case 'g': /* client options group */ + case 'g': /* client options group */ opt_group = optarg; break; - case 'P': /* critical time threshold */ - db_port = atoi (optarg); + case 'P': /* critical time threshold */ + db_port = atoi(optarg); break; case 'S': - check_slave = true; /* check-slave */ + check_slave = true; /* check-slave */ break; case 'n': - ignore_auth = true; /* ignore-auth */ + ignore_auth = true; /* ignore-auth */ break; case 'w': warning = optarg; - warning_time = strtod (warning, NULL); + warning_time = strtod(warning, NULL); break; case 'c': critical = optarg; - critical_time = strtod (critical, NULL); + critical_time = strtod(critical, NULL); break; - case 'V': /* version */ - print_revision (progname, NP_VERSION); - exit (STATE_UNKNOWN); - case 'h': /* help */ - print_help (); - exit (STATE_UNKNOWN); + case 'V': /* version */ + print_revision(progname, NP_VERSION); + exit(STATE_UNKNOWN); + case 'h': /* help */ + print_help(); + exit(STATE_UNKNOWN); case 'v': verbose++; break; - case '?': /* help */ - usage5 (); + case '?': /* help */ + usage5(); } } @@ -487,126 +455,119 @@ process_arguments (int argc, char **argv) set_thresholds(&my_threshold, warning, critical); - while ( argc > c ) { + while (argc > c) { - if (db_host == NULL) - if (is_host (argv[c])) { + if (db_host == NULL) { + if (is_host(argv[c])) { db_host = argv[c++]; + } else { + usage2(_("Invalid hostname/address"), argv[c]); } - else { - usage2 (_("Invalid hostname/address"), argv[c]); - } - else if (db_user == NULL) + } else if (db_user == NULL) { db_user = argv[c++]; - else if (db_pass == NULL) + } else if (db_pass == NULL) { db_pass = argv[c++]; - else if (db == NULL) + } else if (db == NULL) { db = argv[c++]; - else if (is_intnonneg (argv[c])) - db_port = atoi (argv[c++]); - else + } else if (is_intnonneg(argv[c])) { + db_port = atoi(argv[c++]); + } else { break; + } } - return validate_arguments (); + return validate_arguments(); } - -int -validate_arguments (void) -{ - if (db_user == NULL) +int validate_arguments(void) { + if (db_user == NULL) { db_user = strdup(""); + } - if (db_host == NULL) + if (db_host == NULL) { db_host = strdup(""); + } - if (db == NULL) + if (db == NULL) { db = strdup(""); + } return OK; } - -void -print_help (void) -{ +void print_help(void) { char *myport; - xasprintf (&myport, "%d", MYSQL_PORT); - - print_revision (progname, NP_VERSION); - - printf (_(COPYRIGHT), copyright, email); - - printf ("%s\n", _("This program tests connections to a MySQL server")); - - printf ("\n\n"); - - print_usage (); - - printf (UT_HELP_VRSN); - printf (UT_EXTRA_OPTS); - - printf (UT_HOST_PORT, 'P', myport); - printf (" %s\n", "-n, --ignore-auth"); - printf (" %s\n", _("Ignore authentication failure and check for mysql connectivity only")); - - printf (" %s\n", "-s, --socket=STRING"); - printf (" %s\n", _("Use the specified socket (has no effect if -H is used)")); - - printf (" %s\n", "-d, --database=STRING"); - printf (" %s\n", _("Check database with indicated name")); - printf (" %s\n", "-f, --file=STRING"); - printf (" %s\n", _("Read from the specified client options file")); - printf (" %s\n", "-g, --group=STRING"); - printf (" %s\n", _("Use a client options group")); - printf (" %s\n", "-u, --username=STRING"); - printf (" %s\n", _("Connect using the indicated username")); - printf (" %s\n", "-p, --password=STRING"); - printf (" %s\n", _("Use the indicated password to authenticate the connection")); - printf (" ==> %s <==\n", _("IMPORTANT: THIS FORM OF AUTHENTICATION IS NOT SECURE!!!")); - printf (" %s\n", _("Your clear-text password could be visible as a process table entry")); - printf (" %s\n", "-S, --check-slave"); - printf (" %s\n", _("Check if the slave thread is running properly.")); - printf (" %s\n", "-w, --warning"); - printf (" %s\n", _("Exit with WARNING status if slave server is more than INTEGER seconds")); - printf (" %s\n", _("behind master")); - printf (" %s\n", "-c, --critical"); - printf (" %s\n", _("Exit with CRITICAL status if slave server is more then INTEGER seconds")); - printf (" %s\n", _("behind master")); - printf (" %s\n", "-l, --ssl"); - printf (" %s\n", _("Use ssl encryption")); - printf (" %s\n", "-C, --ca-cert=STRING"); - printf (" %s\n", _("Path to CA signing the cert")); - printf (" %s\n", "-a, --cert=STRING"); - printf (" %s\n", _("Path to SSL certificate")); - printf (" %s\n", "-k, --key=STRING"); - printf (" %s\n", _("Path to private SSL key")); - printf (" %s\n", "-D, --ca-dir=STRING"); - printf (" %s\n", _("Path to CA directory")); - printf (" %s\n", "-L, --ciphers=STRING"); - printf (" %s\n", _("List of valid SSL ciphers")); - - - printf ("\n"); - printf (" %s\n", _("There are no required arguments. By default, the local database is checked")); - printf (" %s\n", _("using the default unix socket. You can force TCP on localhost by using an")); - printf (" %s\n", _("IP address or FQDN ('localhost' will use the socket as well).")); - - printf ("\n"); - printf ("%s\n", _("Notes:")); - printf (" %s\n", _("You must specify -p with an empty string to force an empty password,")); - printf (" %s\n", _("overriding any my.cnf settings.")); - - printf (UT_SUPPORT); + xasprintf(&myport, "%d", MYSQL_PORT); + + print_revision(progname, NP_VERSION); + + printf(_(COPYRIGHT), copyright, email); + + printf("%s\n", _("This program tests connections to a MySQL server")); + + printf("\n\n"); + + print_usage(); + + printf(UT_HELP_VRSN); + printf(UT_EXTRA_OPTS); + + printf(UT_HOST_PORT, 'P', myport); + printf(" %s\n", "-n, --ignore-auth"); + printf(" %s\n", _("Ignore authentication failure and check for mysql connectivity only")); + + printf(" %s\n", "-s, --socket=STRING"); + printf(" %s\n", _("Use the specified socket (has no effect if -H is used)")); + + printf(" %s\n", "-d, --database=STRING"); + printf(" %s\n", _("Check database with indicated name")); + printf(" %s\n", "-f, --file=STRING"); + printf(" %s\n", _("Read from the specified client options file")); + printf(" %s\n", "-g, --group=STRING"); + printf(" %s\n", _("Use a client options group")); + printf(" %s\n", "-u, --username=STRING"); + printf(" %s\n", _("Connect using the indicated username")); + printf(" %s\n", "-p, --password=STRING"); + printf(" %s\n", _("Use the indicated password to authenticate the connection")); + printf(" ==> %s <==\n", _("IMPORTANT: THIS FORM OF AUTHENTICATION IS NOT SECURE!!!")); + printf(" %s\n", _("Your clear-text password could be visible as a process table entry")); + printf(" %s\n", "-S, --check-slave"); + printf(" %s\n", _("Check if the slave thread is running properly.")); + printf(" %s\n", "-w, --warning"); + printf(" %s\n", _("Exit with WARNING status if slave server is more than INTEGER seconds")); + printf(" %s\n", _("behind master")); + printf(" %s\n", "-c, --critical"); + printf(" %s\n", _("Exit with CRITICAL status if slave server is more then INTEGER seconds")); + printf(" %s\n", _("behind master")); + printf(" %s\n", "-l, --ssl"); + printf(" %s\n", _("Use ssl encryption")); + printf(" %s\n", "-C, --ca-cert=STRING"); + printf(" %s\n", _("Path to CA signing the cert")); + printf(" %s\n", "-a, --cert=STRING"); + printf(" %s\n", _("Path to SSL certificate")); + printf(" %s\n", "-k, --key=STRING"); + printf(" %s\n", _("Path to private SSL key")); + printf(" %s\n", "-D, --ca-dir=STRING"); + printf(" %s\n", _("Path to CA directory")); + printf(" %s\n", "-L, --ciphers=STRING"); + printf(" %s\n", _("List of valid SSL ciphers")); + + printf("\n"); + printf(" %s\n", _("There are no required arguments. By default, the local database is checked")); + printf(" %s\n", _("using the default unix socket. You can force TCP on localhost by using an")); + printf(" %s\n", _("IP address or FQDN ('localhost' will use the socket as well).")); + + printf("\n"); + printf("%s\n", _("Notes:")); + printf(" %s\n", _("You must specify -p with an empty string to force an empty password,")); + printf(" %s\n", _("overriding any my.cnf settings.")); + + printf(UT_SUPPORT); } - -void -print_usage (void) -{ - printf ("%s\n", _("Usage:")); - printf (" %s [-d database] [-H host] [-P port] [-s socket]\n",progname); - printf (" [-u user] [-p password] [-S] [-l] [-a cert] [-k key]\n"); - printf (" [-C ca-cert] [-D ca-dir] [-L ciphers] [-f optfile] [-g group]\n"); +void print_usage(void) { + printf("%s\n", _("Usage:")); + printf(" %s [-d database] [-H host] [-P port] [-s socket]\n", progname); + printf(" [-u user] [-p password] [-S] [-l] [-a cert] [-k key]\n"); + printf(" [-C ca-cert] [-D ca-dir] [-L ciphers] [-f optfile] [-g group]\n"); } -- cgit v1.2.3-74-g34f1 From b8f203ace7ed09ac97fb98da63e71da07efb7354 Mon Sep 17 00:00:00 2001 From: Lorenz Kästle <12514511+RincewindsHat@users.noreply.github.com> Date: Thu, 20 Feb 2025 18:05:36 +0100 Subject: Rename variable check_slave to check_replica --- plugins/check_mysql.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/plugins/check_mysql.c b/plugins/check_mysql.c index 09c0b7dd..6ba12feb 100644 --- a/plugins/check_mysql.c +++ b/plugins/check_mysql.c @@ -59,7 +59,7 @@ static bool ssl = false; static char *opt_file = NULL; static char *opt_group = NULL; static unsigned int db_port = MYSQL_PORT; -static bool check_slave = false; +static bool check_replica = false; static bool ignore_auth = false; static int verbose = 0; @@ -195,7 +195,7 @@ int main(int argc, char **argv) { } } - if (check_slave) { + if (check_replica) { /* check the slave status */ if (mysql_query(&mysql, "show slave status") != 0) { error = strdup(mysql_error(&mysql)); @@ -329,7 +329,7 @@ int main(int argc, char **argv) { mysql_close(&mysql); /* print out the result of stats */ - if (check_slave) { + if (check_replica) { printf("%s %s|%s\n", result, slaveresult, perf); } else { printf("%s|%s\n", result, perf); @@ -424,7 +424,7 @@ int process_arguments(int argc, char **argv) { db_port = atoi(optarg); break; case 'S': - check_slave = true; /* check-slave */ + check_replica = true; /* check-slave */ break; case 'n': ignore_auth = true; /* ignore-auth */ -- cgit v1.2.3-74-g34f1 From 97894cdd17962efe611c981de40eaab8c3b3e43a Mon Sep 17 00:00:00 2001 From: Lorenz Kästle <12514511+RincewindsHat@users.noreply.github.com> Date: Thu, 20 Feb 2025 18:09:24 +0100 Subject: Add check-replica option for check_mysql, deprecate check_slave This commit adds an option "check-replica" to check_mysql which replaces "check-slave" (which still works). The changes are introduced to follow the naming scheme of MySQL/MariaDB, since this was changed there in version 8 (MySQL) or 10.5.1 (MariaDB). --- plugins/check_mysql.c | 92 ++++++++++++++++++++++++++++++--------------------- 1 file changed, 55 insertions(+), 37 deletions(-) diff --git a/plugins/check_mysql.c b/plugins/check_mysql.c index 6ba12feb..039a42e5 100644 --- a/plugins/check_mysql.c +++ b/plugins/check_mysql.c @@ -34,7 +34,7 @@ const char *progname = "check_mysql"; const char *copyright = "1999-2024"; const char *email = "devel@monitoring-plugins.org"; -#define SLAVERESULTSIZE 96 +#define REPLICA_RESULTSIZE 96 #include "common.h" #include "utils.h" @@ -95,7 +95,7 @@ int main(int argc, char **argv) { char *result = NULL; char *error = NULL; - char slaveresult[SLAVERESULTSIZE] = {0}; + char replica_result[REPLICA_RESULTSIZE] = {0}; char *perf; perf = strdup(""); @@ -200,20 +200,20 @@ int main(int argc, char **argv) { if (mysql_query(&mysql, "show slave status") != 0) { error = strdup(mysql_error(&mysql)); mysql_close(&mysql); - die(STATE_CRITICAL, _("slave query error: %s\n"), error); + die(STATE_CRITICAL, _("replica query error: %s\n"), error); } /* store the result */ if ((res = mysql_store_result(&mysql)) == NULL) { error = strdup(mysql_error(&mysql)); mysql_close(&mysql); - die(STATE_CRITICAL, _("slave store_result error: %s\n"), error); + die(STATE_CRITICAL, _("replica store_result error: %s\n"), error); } /* Check there is some data */ if (mysql_num_rows(res) == 0) { mysql_close(&mysql); - die(STATE_WARNING, "%s\n", _("No slaves defined")); + die(STATE_WARNING, "%s\n", _("No replicas defined")); } /* fetch the first row */ @@ -221,32 +221,32 @@ int main(int argc, char **argv) { error = strdup(mysql_error(&mysql)); mysql_free_result(res); mysql_close(&mysql); - die(STATE_CRITICAL, _("slave fetch row error: %s\n"), error); + die(STATE_CRITICAL, _("replica fetch row error: %s\n"), error); } if (mysql_field_count(&mysql) == 12) { /* mysql 3.23.x */ - snprintf(slaveresult, SLAVERESULTSIZE, _("Slave running: %s"), row[6]); + snprintf(replica_result, REPLICA_RESULTSIZE, _("Replica running: %s"), row[6]); if (strcmp(row[6], "Yes") != 0) { mysql_free_result(res); mysql_close(&mysql); - die(STATE_CRITICAL, "%s\n", slaveresult); + die(STATE_CRITICAL, "%s\n", replica_result); } } else { /* mysql 4.x.x and mysql 5.x.x */ - int slave_io_field = -1, slave_sql_field = -1, seconds_behind_field = -1, i, num_fields; + int replica_io_field = -1, replica_sql_field = -1, seconds_behind_field = -1, i, num_fields; MYSQL_FIELD *fields; num_fields = mysql_num_fields(res); fields = mysql_fetch_fields(res); for (i = 0; i < num_fields; i++) { if (strcmp(fields[i].name, "Slave_IO_Running") == 0) { - slave_io_field = i; + replica_io_field = i; continue; } if (strcmp(fields[i].name, "Slave_SQL_Running") == 0) { - slave_sql_field = i; + replica_sql_field = i; continue; } if (strcmp(fields[i].name, "Seconds_Behind_Master") == 0) { @@ -255,19 +255,19 @@ int main(int argc, char **argv) { } } - /* Check if slave status is available */ - if ((slave_io_field < 0) || (slave_sql_field < 0) || (num_fields == 0)) { + /* Check if replica status is available */ + if ((replica_io_field < 0) || (replica_sql_field < 0) || (num_fields == 0)) { mysql_free_result(res); mysql_close(&mysql); - die(STATE_CRITICAL, "Slave status unavailable\n"); + die(STATE_CRITICAL, "Replica status unavailable\n"); } - /* Save slave status in slaveresult */ - snprintf(slaveresult, SLAVERESULTSIZE, "Slave IO: %s Slave SQL: %s Seconds Behind Master: %s", row[slave_io_field], - row[slave_sql_field], seconds_behind_field != -1 ? row[seconds_behind_field] : "Unknown"); + /* Save replica status in replica_result */ + snprintf(replica_result, REPLICA_RESULTSIZE, "Replica IO: %s Replica SQL: %s Seconds Behind Master: %s", row[replica_io_field], + row[replica_sql_field], seconds_behind_field != -1 ? row[seconds_behind_field] : "Unknown"); /* Raise critical error if SQL THREAD or IO THREAD are stopped, but only if there are no mysqldump threads running */ - if (strcmp(row[slave_io_field], "Yes") != 0 || strcmp(row[slave_sql_field], "Yes") != 0) { + if (strcmp(row[replica_io_field], "Yes") != 0 || strcmp(row[replica_sql_field], "Yes") != 0) { MYSQL_RES *res_mysqldump; MYSQL_ROW row_mysqldump; unsigned int mysqldump_threads = 0; @@ -286,9 +286,9 @@ int main(int argc, char **argv) { mysql_close(&mysql); } if (mysqldump_threads == 0) { - die(STATE_CRITICAL, "%s\n", slaveresult); + die(STATE_CRITICAL, "%s\n", replica_result); } else { - strncat(slaveresult, " Mysqldump: in progress", SLAVERESULTSIZE - 1); + strncat(replica_result, " Mysqldump: in progress", REPLICA_RESULTSIZE - 1); } } @@ -312,10 +312,10 @@ int main(int argc, char **argv) { false, 0)); if (status == STATE_WARNING) { - printf("SLOW_SLAVE %s: %s|%s\n", _("WARNING"), slaveresult, perf); + printf("SLOW_REPLICA %s: %s|%s\n", _("WARNING"), replica_result, perf); exit(STATE_WARNING); } else if (status == STATE_CRITICAL) { - printf("SLOW_SLAVE %s: %s|%s\n", _("CRITICAL"), slaveresult, perf); + printf("SLOW_REPLICA %s: %s|%s\n", _("CRITICAL"), replica_result, perf); exit(STATE_CRITICAL); } } @@ -330,7 +330,7 @@ int main(int argc, char **argv) { /* print out the result of stats */ if (check_replica) { - printf("%s %s|%s\n", result, slaveresult, perf); + printf("%s %s|%s\n", result, replica_result, perf); } else { printf("%s|%s\n", result, perf); } @@ -338,6 +338,8 @@ int main(int argc, char **argv) { return STATE_OK; } +#define CHECK_REPLICA_OPT CHAR_MAX + 1 + /* process command-line arguments */ int process_arguments(int argc, char **argv) { int c; @@ -345,17 +347,29 @@ int process_arguments(int argc, char **argv) { char *critical = NULL; int option = 0; - static struct option longopts[] = {{"hostname", required_argument, 0, 'H'}, {"socket", required_argument, 0, 's'}, - {"database", required_argument, 0, 'd'}, {"username", required_argument, 0, 'u'}, - {"password", required_argument, 0, 'p'}, {"file", required_argument, 0, 'f'}, - {"group", required_argument, 0, 'g'}, {"port", required_argument, 0, 'P'}, - {"critical", required_argument, 0, 'c'}, {"warning", required_argument, 0, 'w'}, - {"check-slave", no_argument, 0, 'S'}, {"ignore-auth", no_argument, 0, 'n'}, - {"verbose", no_argument, 0, 'v'}, {"version", no_argument, 0, 'V'}, - {"help", no_argument, 0, 'h'}, {"ssl", no_argument, 0, 'l'}, - {"ca-cert", optional_argument, 0, 'C'}, {"key", required_argument, 0, 'k'}, - {"cert", required_argument, 0, 'a'}, {"ca-dir", required_argument, 0, 'D'}, - {"ciphers", required_argument, 0, 'L'}, {0, 0, 0, 0}}; + static struct option longopts[] = {{"hostname", required_argument, 0, 'H'}, + {"socket", required_argument, 0, 's'}, + {"database", required_argument, 0, 'd'}, + {"username", required_argument, 0, 'u'}, + {"password", required_argument, 0, 'p'}, + {"file", required_argument, 0, 'f'}, + {"group", required_argument, 0, 'g'}, + {"port", required_argument, 0, 'P'}, + {"critical", required_argument, 0, 'c'}, + {"warning", required_argument, 0, 'w'}, + {"check-slave", no_argument, 0, 'S'}, + {"check-replica", no_argument, 0, CHECK_REPLICA_OPT}, + {"ignore-auth", no_argument, 0, 'n'}, + {"verbose", no_argument, 0, 'v'}, + {"version", no_argument, 0, 'V'}, + {"help", no_argument, 0, 'h'}, + {"ssl", no_argument, 0, 'l'}, + {"ca-cert", optional_argument, 0, 'C'}, + {"key", required_argument, 0, 'k'}, + {"cert", required_argument, 0, 'a'}, + {"ca-dir", required_argument, 0, 'D'}, + {"ciphers", required_argument, 0, 'L'}, + {0, 0, 0, 0}}; if (argc < 1) { return ERROR; @@ -424,6 +438,7 @@ int process_arguments(int argc, char **argv) { db_port = atoi(optarg); break; case 'S': + case CHECK_REPLICA_OPT: check_replica = true; /* check-slave */ break; case 'n': @@ -532,12 +547,15 @@ void print_help(void) { printf(" ==> %s <==\n", _("IMPORTANT: THIS FORM OF AUTHENTICATION IS NOT SECURE!!!")); printf(" %s\n", _("Your clear-text password could be visible as a process table entry")); printf(" %s\n", "-S, --check-slave"); - printf(" %s\n", _("Check if the slave thread is running properly.")); + printf(" %s\n", + _("Check if the slave thread is running properly. This option is deprecated in favour of check-replica, which does the same")); + printf(" %s\n", "--check-replica"); + printf(" %s\n", _("Check if the replica thread is running properly.")); printf(" %s\n", "-w, --warning"); - printf(" %s\n", _("Exit with WARNING status if slave server is more than INTEGER seconds")); + printf(" %s\n", _("Exit with WARNING status if replica server is more than INTEGER seconds")); printf(" %s\n", _("behind master")); printf(" %s\n", "-c, --critical"); - printf(" %s\n", _("Exit with CRITICAL status if slave server is more then INTEGER seconds")); + printf(" %s\n", _("Exit with CRITICAL status if replica server is more then INTEGER seconds")); printf(" %s\n", _("behind master")); printf(" %s\n", "-l, --ssl"); printf(" %s\n", _("Use ssl encryption")); -- cgit v1.2.3-74-g34f1 From a517dc614e44650a7e9204c4202feec7a40fd37f Mon Sep 17 00:00:00 2001 From: Lorenz Kästle <12514511+RincewindsHat@users.noreply.github.com> Date: Mon, 24 Feb 2025 19:52:08 +0100 Subject: Add MySQL server version dectection and adaptive replica query --- plugins/check_mysql.c | 52 +++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 50 insertions(+), 2 deletions(-) diff --git a/plugins/check_mysql.c b/plugins/check_mysql.c index 039a42e5..2b6cfeaf 100644 --- a/plugins/check_mysql.c +++ b/plugins/check_mysql.c @@ -196,8 +196,56 @@ int main(int argc, char **argv) { } if (check_replica) { - /* check the slave status */ - if (mysql_query(&mysql, "show slave status") != 0) { + + // Detect which version we are, on older version + // "show slave status" should work, on newer ones + // "show replica status" + // But first we have to find out whether this is + // MySQL or MariaDB since the version numbering scheme + // is different + bool use_deprecated_slave_status = false; + const char *server_version = mysql_get_server_info(&mysql); + unsigned long server_verion_int = mysql_get_server_version(&mysql); + unsigned long major_version = server_verion_int / 10000; + unsigned long minor_version = (server_verion_int % 10000) / 100; + unsigned long patch_version = (server_verion_int % 100); + if (verbose) { + printf("Found MariaDB: %s, main version: %lu, minor version: %lu, patch version: %lu\n", server_version, major_version, + minor_version, patch_version); + } + + if (strstr(server_version, "MariaDB") != NULL) { + // Looks like MariaDB, new commands should be available after 10.5.1 + if (major_version < 10) { + use_deprecated_slave_status = true; + } else if (major_version == 10) { + if (minor_version < 5) { + use_deprecated_slave_status = true; + } else if (minor_version == 5 && patch_version < 1) { + use_deprecated_slave_status = true; + } + } + } else if (strstr(server_version, "MySQL") != NULL) { + // Looks like MySQL + if (major_version < 8) { + use_deprecated_slave_status = true; + } else if (major_version == 10 && minor_version < 4) { + use_deprecated_slave_status = true; + } + } else { + printf("Not a known sever implementation: %s\n", server_version); + exit(STATE_UNKNOWN); + } + + char *replica_query = NULL; + if (use_deprecated_slave_status) { + replica_query = "show slave status"; + } else { + replica_query = "show replica status"; + } + + /* check the replica status */ + if (mysql_query(&mysql, replica_query) != 0) { error = strdup(mysql_error(&mysql)); mysql_close(&mysql); die(STATE_CRITICAL, _("replica query error: %s\n"), error); -- cgit v1.2.3-74-g34f1 From c08e2bc656dec032f6b56b0aa398c6cb40ade250 Mon Sep 17 00:00:00 2001 From: Lorenz Kästle <12514511+RincewindsHat@users.noreply.github.com> Date: Mon, 24 Feb 2025 20:18:55 +0100 Subject: Add libmysqlclient-dev to dependencies --- .github/prepare_debian.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/prepare_debian.sh b/.github/prepare_debian.sh index 3640e500..8b695d42 100755 --- a/.github/prepare_debian.sh +++ b/.github/prepare_debian.sh @@ -59,6 +59,7 @@ apt-get -y install perl \ mariadb-server \ mariadb-client \ libmariadb-dev \ + libmariadb-dev-compat \ cron \ iputils-ping \ iproute2 -- cgit v1.2.3-74-g34f1 From 3ed6b7cd3e99e328b9f34bfc4af8b2f8bd3b5231 Mon Sep 17 00:00:00 2001 From: Lorenz Kästle <12514511+RincewindsHat@users.noreply.github.com> Date: Mon, 24 Feb 2025 20:55:18 +0100 Subject: check_mysql tests: Also exchange slave for replica --- .github/NPTest.cache | 4 ++-- plugins/t/check_mysql.t | 32 ++++++++++++++++---------------- 2 files changed, 18 insertions(+), 18 deletions(-) diff --git a/.github/NPTest.cache b/.github/NPTest.cache index d488d1b9..6b463e74 100644 --- a/.github/NPTest.cache +++ b/.github/NPTest.cache @@ -38,8 +38,8 @@ 'NP_MYSQL_LOGIN_DETAILS' => '-u root -d test', 'NP_MYSQL_SERVER' => 'localhost', 'NP_MYSQL_SOCKET' => '/var/run/mysqld/mysqld.sock', - 'NP_MYSQL_WITH_SLAVE' => '', - 'NP_MYSQL_WITH_SLAVE_LOGIN' => '', + 'NP_MYSQL_WITH_REPLICA' => '', + 'NP_MYSQL_WITH_REPLICA_LOGIN' => '', 'NP_NO_NTP_SERVICE' => 'localhost', 'NP_PORT_TCP_PROXY' => '3128', 'NP_SMB_SHARE' => '', diff --git a/plugins/t/check_mysql.t b/plugins/t/check_mysql.t index baf3acc6..a383bc99 100644 --- a/plugins/t/check_mysql.t +++ b/plugins/t/check_mysql.t @@ -21,11 +21,11 @@ plan skip_all => "check_mysql not compiled" unless (-x "check_mysql"); plan tests => 15; my $bad_login_output = '/Access denied for user /'; -my $mysqlserver = getTestParameter("NP_MYSQL_SERVER", "A MySQL Server hostname or IP with no slaves setup"); -my $mysqlsocket = getTestParameter("NP_MYSQL_SOCKET", "Full path to a MySQL Server socket with no slaves setup"); +my $mysqlserver = getTestParameter("NP_MYSQL_SERVER", "A MySQL Server hostname or IP with no replica setup"); +my $mysqlsocket = getTestParameter("NP_MYSQL_SOCKET", "Full path to a MySQL Server socket with no replica setup"); my $mysql_login_details = getTestParameter("NP_MYSQL_LOGIN_DETAILS", "Command line parameters to specify login access (requires REPLICATION CLIENT privileges)", "-u test -ptest"); -my $with_slave = getTestParameter("NP_MYSQL_WITH_SLAVE", "MySQL server with slaves setup"); -my $with_slave_login = getTestParameter("NP_MYSQL_WITH_SLAVE_LOGIN", "Login details for server with slave (requires REPLICATION CLIENT privileges)", $mysql_login_details || "-u test -ptest"); +my $with_replica = getTestParameter("NP_MYSQL_WITH_REPLICA", "MySQL server with replica setup"); +my $with_replica_login = getTestParameter("NP_MYSQL_WITH_REPLICA_LOGIN", "Login details for server with replica (requires REPLICATION CLIENT privileges)", $mysql_login_details || "-u test -ptest"); my $result; @@ -39,8 +39,8 @@ SKIP: { like( $result->output, $bad_login_output, "Expected login failure message"); $result = NPTest->testCmd("./check_mysql -S -H $mysqlserver $mysql_login_details"); - cmp_ok( $result->return_code, "==", 1, "No slaves defined" ); - like( $result->output, "/No slaves defined/", "Correct error message"); + cmp_ok( $result->return_code, "==", 1, "No replicas defined" ); + like( $result->output, "/No replicas defined/", "Correct error message"); } SKIP: { @@ -53,22 +53,22 @@ SKIP: { like( $result->output, $bad_login_output, "Expected login failure message"); $result = NPTest->testCmd("./check_mysql -S -s $mysqlsocket $mysql_login_details"); - cmp_ok( $result->return_code, "==", 1, "No slaves defined" ); - like( $result->output, "/No slaves defined/", "Correct error message"); + cmp_ok( $result->return_code, "==", 1, "No replicas defined" ); + like( $result->output, "/No replicas defined/", "Correct error message"); } SKIP: { - skip "No mysql server with slaves defined", 5 unless $with_slave; - $result = NPTest->testCmd("./check_mysql -H $with_slave $with_slave_login"); + skip "No mysql server with replicas defined", 5 unless $with_replica; + $result = NPTest->testCmd("./check_mysql -H $with_replica $with_replica_login"); cmp_ok( $result->return_code, '==', 0, "Login okay"); - $result = NPTest->testCmd("./check_mysql -S -H $with_slave $with_slave_login"); - cmp_ok( $result->return_code, "==", 0, "Slaves okay" ); + $result = NPTest->testCmd("./check_mysql -S -H $with_replica $with_replica_login"); + cmp_ok( $result->return_code, "==", 0, "Replicas okay" ); - $result = NPTest->testCmd("./check_mysql -S -H $with_slave $with_slave_login -w 60"); - cmp_ok( $result->return_code, '==', 0, 'Slaves are not > 60 seconds behind'); + $result = NPTest->testCmd("./check_mysql -S -H $with_replica $with_replica_login -w 60"); + cmp_ok( $result->return_code, '==', 0, 'Replicas are not > 60 seconds behind'); - $result = NPTest->testCmd("./check_mysql -S -H $with_slave $with_slave_login -w 60:"); + $result = NPTest->testCmd("./check_mysql -S -H $with_replica $with_replica_login -w 60:"); cmp_ok( $result->return_code, '==', 1, 'Alert warning if < 60 seconds behind'); - like( $result->output, "/^SLOW_SLAVE WARNING:/", "Output okay"); + like( $result->output, "/^SLOW_REPLICA WARNING:/", "Output okay"); } -- cgit v1.2.3-74-g34f1 From eb1dd9fe2e0e965b4c9326195a778c3794492ef4 Mon Sep 17 00:00:00 2001 From: Lorenz Kästle <12514511+RincewindsHat@users.noreply.github.com> Date: Fri, 7 Mar 2025 09:14:37 +0100 Subject: check_dbi: clang_format --- plugins/check_dbi.c | 140 +++++++++++++++++++++++++++++++++------------------- 1 file changed, 89 insertions(+), 51 deletions(-) diff --git a/plugins/check_dbi.c b/plugins/check_dbi.c index 96575672..ae8ec952 100644 --- a/plugins/check_dbi.c +++ b/plugins/check_dbi.c @@ -128,8 +128,9 @@ int main(int argc, char **argv) { /* Parse extra opts if any */ argv = np_extra_opts(&argc, argv, progname); - if (process_arguments(argc, argv) == ERROR) + if (process_arguments(argc, argv) == ERROR) { usage4(_("Could not parse arguments")); + } /* Set signal handling and alarm */ if (signal(SIGALRM, timeout_alarm_handler) == SIG_ERR) { @@ -137,8 +138,9 @@ int main(int argc, char **argv) { } alarm(timeout_interval); - if (verbose > 2) + if (verbose > 2) { printf("Initializing DBI\n"); + } dbi_inst *instance_p = {0}; @@ -152,8 +154,9 @@ int main(int argc, char **argv) { return STATE_UNKNOWN; } - if (verbose) + if (verbose) { printf("Opening DBI driver '%s'\n", np_dbi_driver); + } driver = dbi_driver_open_r(np_dbi_driver, instance_p); if (!driver) { @@ -179,11 +182,13 @@ int main(int argc, char **argv) { for (i = 0; i < np_dbi_options_num; ++i) { const char *opt; - if (verbose > 1) + if (verbose > 1) { printf("Setting DBI driver option '%s' to '%s'\n", np_dbi_options[i].key, np_dbi_options[i].value); + } - if (!dbi_conn_set_option(conn, np_dbi_options[i].key, np_dbi_options[i].value)) + if (!dbi_conn_set_option(conn, np_dbi_options[i].key, np_dbi_options[i].value)) { continue; + } /* else: status != 0 */ np_dbi_print_error(conn, "UNKNOWN - failed to set option '%s' to '%s'", np_dbi_options[i].key, np_dbi_options[i].value); @@ -197,8 +202,9 @@ int main(int argc, char **argv) { } if (host) { - if (verbose > 1) + if (verbose > 1) { printf("Setting DBI driver option 'host' to '%s'\n", host); + } dbi_conn_set_option(conn, "host", host); } @@ -209,10 +215,12 @@ int main(int argc, char **argv) { dbname = dbi_conn_get_option(conn, "dbname"); host = dbi_conn_get_option(conn, "host"); - if (!dbname) + if (!dbname) { dbname = ""; - if (!host) + } + if (!host) { host = ""; + } printf("Connecting to database '%s' at host '%s'\n", dbname, host); } @@ -226,22 +234,27 @@ int main(int argc, char **argv) { conn_time = timediff(start_timeval, end_timeval); server_version = dbi_conn_get_engine_version(conn); - if (verbose) + if (verbose) { printf("Connected to server version %u\n", server_version); + } - if (metric == METRIC_SERVER_VERSION) + if (metric == METRIC_SERVER_VERSION) { status = get_status(server_version, dbi_thresholds); + } - if (verbose) + if (verbose) { printf("Time elapsed: %f\n", conn_time); + } - if (metric == METRIC_CONN_TIME) + if (metric == METRIC_CONN_TIME) { status = get_status(conn_time, dbi_thresholds); + } /* select a database */ if (np_dbi_database) { - if (verbose > 1) + if (verbose > 1) { printf("Selecting database '%s'\n", np_dbi_database); + } if (dbi_conn_select_db(conn, np_dbi_database)) { np_dbi_print_error(conn, "UNKNOWN - failed to select database '%s'", np_dbi_database); @@ -252,38 +265,43 @@ int main(int argc, char **argv) { if (np_dbi_query) { /* execute query */ status = do_query(conn, &query_val_str, &query_val, &query_time); - if (status != STATE_OK) + if (status != STATE_OK) { /* do_query prints an error message in this case */ return status; + } if (metric == METRIC_QUERY_RESULT) { if (expect) { - if ((!query_val_str) || strcmp(query_val_str, expect)) + if ((!query_val_str) || strcmp(query_val_str, expect)) { status = STATE_CRITICAL; - else + } else { status = STATE_OK; + } } else if (expect_re_str) { int err; err = regexec(&expect_re, query_val_str, 0, NULL, /* flags = */ 0); - if (!err) + if (!err) { status = STATE_OK; - else if (err == REG_NOMATCH) + } else if (err == REG_NOMATCH) { status = STATE_CRITICAL; - else { + } else { char errmsg[1024]; regerror(err, &expect_re, errmsg, sizeof(errmsg)); printf("ERROR - failed to execute regular expression: %s\n", errmsg); status = STATE_CRITICAL; } - } else + } else { status = get_status(query_val, dbi_thresholds); - } else if (metric == METRIC_QUERY_TIME) + } + } else if (metric == METRIC_QUERY_TIME) { status = get_status(query_time, dbi_thresholds); + } } - if (verbose) + if (verbose) { printf("Closing connection\n"); + } dbi_conn_close(conn); /* In case of METRIC_QUERY_RESULT, isnan(query_val) indicates an error @@ -299,15 +317,17 @@ int main(int argc, char **argv) { assert(expect || expect_re_str); printf(", '%s' returned '%s' in %fs", np_dbi_query, query_val_str ? query_val_str : "", query_time); if (status != STATE_OK) { - if (expect) + if (expect) { printf(" (expected '%s')", expect); - else if (expect_re_str) + } else if (expect_re_str) { printf(" (expected regex /%s/%s)", expect_re_str, ((expect_re_cflags & REG_ICASE) ? "i" : "")); + } } - } else if (isnan(query_val)) + } else if (isnan(query_val)) { printf(", '%s' query execution time: %fs", np_dbi_query, query_time); - else + } else { printf(", '%s' returned %f in %fs", np_dbi_query, query_val, query_time); + } } printf(" | conntime=%fs;%s;%s;0; server_version=%u;%s;%s;0;", conn_time, @@ -316,9 +336,10 @@ int main(int argc, char **argv) { ((metric == METRIC_SERVER_VERSION) && warning_range) ? warning_range : "", ((metric == METRIC_SERVER_VERSION) && critical_range) ? critical_range : ""); if (np_dbi_query) { - if (!isnan(query_val)) /* this is also true when -e is used */ + if (!isnan(query_val)) { /* this is also true when -e is used */ printf(" query=%f;%s;%s;;", query_val, ((metric == METRIC_QUERY_RESULT) && warning_range) ? warning_range : "", ((metric == METRIC_QUERY_RESULT) && critical_range) ? critical_range : ""); + } printf(" querytime=%fs;%s;%s;0;", query_time, ((metric == METRIC_QUERY_TIME) && warning_range) ? warning_range : "", ((metric == METRIC_QUERY_TIME) && critical_range) ? critical_range : ""); } @@ -346,8 +367,9 @@ int process_arguments(int argc, char **argv) { while (1) { c = getopt_long(argc, argv, "Vvht:c:w:e:r:R:m:H:d:o:q:D:", longopts, &option); - if (c == EOF) + if (c == EOF) { break; + } switch (c) { case '?': /* usage */ @@ -392,29 +414,32 @@ int process_arguments(int argc, char **argv) { } case 'm': - if (!strcasecmp(optarg, "CONN_TIME")) + if (!strcasecmp(optarg, "CONN_TIME")) { metric = METRIC_CONN_TIME; - else if (!strcasecmp(optarg, "SERVER_VERSION")) + } else if (!strcasecmp(optarg, "SERVER_VERSION")) { metric = METRIC_SERVER_VERSION; - else if (!strcasecmp(optarg, "QUERY_RESULT")) + } else if (!strcasecmp(optarg, "QUERY_RESULT")) { metric = METRIC_QUERY_RESULT; - else if (!strcasecmp(optarg, "QUERY_TIME")) + } else if (!strcasecmp(optarg, "QUERY_TIME")) { metric = METRIC_QUERY_TIME; - else + } else { usage2(_("Invalid metric"), optarg); + } break; case 't': /* timeout */ - if (!is_intnonneg(optarg)) + if (!is_intnonneg(optarg)) { usage2(_("Timeout interval must be a positive integer"), optarg); - else + } else { timeout_interval = atoi(optarg); + } break; case 'H': /* host */ - if (!is_host(optarg)) + if (!is_host(optarg)) { usage2(_("Invalid hostname/address"), optarg); - else + } else { host = optarg; + } break; case 'v': verbose++; @@ -432,8 +457,9 @@ int process_arguments(int argc, char **argv) { k = optarg; v = strchr(k, (int)'='); - if (!v) + if (!v) { usage2(_("Option must be '='"), optarg); + } *v = '\0'; ++v; @@ -466,27 +492,34 @@ int process_arguments(int argc, char **argv) { } int validate_arguments(void) { - if (!np_dbi_driver) + if (!np_dbi_driver) { usage("Must specify a DBI driver"); + } - if (((metric == METRIC_QUERY_RESULT) || (metric == METRIC_QUERY_TIME)) && (!np_dbi_query)) + if (((metric == METRIC_QUERY_RESULT) || (metric == METRIC_QUERY_TIME)) && (!np_dbi_query)) { usage("Must specify a query to execute (metric == QUERY_RESULT)"); + } if ((metric != METRIC_CONN_TIME) && (metric != METRIC_SERVER_VERSION) && (metric != METRIC_QUERY_RESULT) && - (metric != METRIC_QUERY_TIME)) + (metric != METRIC_QUERY_TIME)) { usage("Invalid metric specified"); + } - if (expect && (warning_range || critical_range || expect_re_str)) + if (expect && (warning_range || critical_range || expect_re_str)) { usage("Do not mix -e and -w/-c/-r/-R"); + } - if (expect_re_str && (warning_range || critical_range || expect)) + if (expect_re_str && (warning_range || critical_range || expect)) { usage("Do not mix -r/-R and -w/-c/-e"); + } - if (expect && (metric != METRIC_QUERY_RESULT)) + if (expect && (metric != METRIC_QUERY_RESULT)) { usage("Option -e requires metric QUERY_RESULT"); + } - if (expect_re_str && (metric != METRIC_QUERY_RESULT)) + if (expect_re_str && (metric != METRIC_QUERY_RESULT)) { usage("Options -r/-R require metric QUERY_RESULT"); + } return OK; } @@ -613,8 +646,9 @@ const char *get_field_str(dbi_conn conn, dbi_result res, unsigned short field_ty return NULL; } - if ((verbose && (type == TYPE_STRING)) || (verbose > 2)) + if ((verbose && (type == TYPE_STRING)) || (verbose > 2)) { printf("Query returned string '%s'\n", str); + } return str; } @@ -644,8 +678,9 @@ double get_field(dbi_conn conn, dbi_result res, unsigned short *field_type) { return NAN; } if ((endptr != NULL) && (*endptr != '\0')) { - if (verbose) + if (verbose) { printf("Garbage after value: %s\n", endptr); + } } } else { CHECK_IGNORE_ERROR(NAN); @@ -696,11 +731,12 @@ double get_query_result(dbi_conn conn, dbi_result res, const char **res_val_str, field_type = dbi_result_get_field_type_idx(res, 1); if (field_type != DBI_TYPE_ERROR) { - if (type == TYPE_STRING) + if (type == TYPE_STRING) { /* the value will be freed in dbi_result_free */ *res_val_str = strdup(get_field_str(conn, res, field_type)); - else + } else { val = get_field(conn, res, &field_type); + } } *res_val = val; @@ -726,8 +762,9 @@ int do_query(dbi_conn conn, const char **res_val_str, double *res_val, double *r assert(np_dbi_query); - if (verbose) + if (verbose) { printf("Executing query '%s'\n", np_dbi_query); + } gettimeofday(&timeval_start, NULL); @@ -742,8 +779,9 @@ int do_query(dbi_conn conn, const char **res_val_str, double *res_val, double *r gettimeofday(&timeval_end, NULL); *res_time = timediff(timeval_start, timeval_end); - if (verbose) + if (verbose) { printf("Time elapsed: %f\n", *res_time); + } return status; } -- cgit v1.2.3-74-g34f1 From 065ed65a870bd973c751940ef8e6f47f62d88d26 Mon Sep 17 00:00:00 2001 From: Lorenz Kästle <12514511+RincewindsHat@users.noreply.github.com> Date: Fri, 7 Mar 2025 15:57:46 +0100 Subject: Fix types in perfdata functions --- plugins/utils.c | 243 ++++++++++++++++++++++++++++++++++---------------------- plugins/utils.h | 141 ++++++++++++++++---------------- 2 files changed, 220 insertions(+), 164 deletions(-) diff --git a/plugins/utils.c b/plugins/utils.c index 09649429..34335c89 100644 --- a/plugins/utils.c +++ b/plugins/utils.c @@ -89,41 +89,46 @@ bool is_numeric(char *number) { char tmp[1]; float x; - if (!number) + if (!number) { return false; - else if (sscanf(number, "%f%c", &x, tmp) == 1) + } else if (sscanf(number, "%f%c", &x, tmp) == 1) { return true; - else + } else { return false; + } } bool is_positive(char *number) { - if (is_numeric(number) && atof(number) > 0.0) + if (is_numeric(number) && atof(number) > 0.0) { return true; - else + } else { return false; + } } bool is_negative(char *number) { - if (is_numeric(number) && atof(number) < 0.0) + if (is_numeric(number) && atof(number) < 0.0) { return true; - else + } else { return false; + } } bool is_nonnegative(char *number) { - if (is_numeric(number) && atof(number) >= 0.0) + if (is_numeric(number) && atof(number) >= 0.0) { return true; - else + } else { return false; + } } bool is_percentage(char *number) { int x; - if (is_numeric(number) && (x = atof(number)) >= 0 && x <= 100) + if (is_numeric(number) && (x = atof(number)) >= 0 && x <= 100) { return true; - else + } else { return false; + } } bool is_percentage_expression(const char str[]) { @@ -156,36 +161,41 @@ bool is_percentage_expression(const char str[]) { bool is_integer(char *number) { long int n; - if (!number || (strspn(number, "-0123456789 ") != strlen(number))) + if (!number || (strspn(number, "-0123456789 ") != strlen(number))) { return false; + } n = strtol(number, NULL, 10); - if (errno != ERANGE && n >= INT_MIN && n <= INT_MAX) + if (errno != ERANGE && n >= INT_MIN && n <= INT_MAX) { return true; - else + } else { return false; + } } bool is_intpos(char *number) { - if (is_integer(number) && atoi(number) > 0) + if (is_integer(number) && atoi(number) > 0) { return true; - else + } else { return false; + } } bool is_intneg(char *number) { - if (is_integer(number) && atoi(number) < 0) + if (is_integer(number) && atoi(number) < 0) { return true; - else + } else { return false; + } } bool is_intnonneg(char *number) { - if (is_integer(number) && atoi(number) >= 0) + if (is_integer(number) && atoi(number) >= 0) { return true; - else + } else { return false; + } } /* @@ -247,19 +257,21 @@ bool is_uint64(char *number, uint64_t *target) { bool is_intpercent(char *number) { int i; - if (is_integer(number) && (i = atoi(number)) >= 0 && i <= 100) + if (is_integer(number) && (i = atoi(number)) >= 0 && i <= 100) { return true; - else + } else { return false; + } } bool is_option(char *str) { - if (!str) + if (!str) { return false; - else if (strspn(str, "-") == 1 || strspn(str, "-") == 2) + } else if (strspn(str, "-") == 1 || strspn(str, "-") == 2) { return true; - else + } else { return false; + } } #ifdef NEED_GETTIMEOFDAY @@ -288,10 +300,11 @@ void strip(char *buffer) { for (x = strlen(buffer); x >= 1; x--) { i = x - 1; - if (buffer[i] == ' ' || buffer[i] == '\r' || buffer[i] == '\n' || buffer[i] == '\t') + if (buffer[i] == ' ' || buffer[i] == '\r' || buffer[i] == '\n' || buffer[i] == '\t') { buffer[i] = '\0'; - else + } else { break; + } } return; } @@ -309,8 +322,9 @@ void strip(char *buffer) { *****************************************************************************/ char *strscpy(char *dest, const char *src) { - if (src == NULL) + if (src == NULL) { return NULL; + } xasprintf(&dest, "%s", src); @@ -369,17 +383,21 @@ char *strscpy(char *dest, const char *src) { char *strnl(char *str) { size_t len; - if (str == NULL) + if (str == NULL) { return NULL; + } str = strpbrk(str, "\r\n"); - if (str == NULL) + if (str == NULL) { return NULL; + } len = strspn(str, "\r\n"); - if (str[len] == '\0') + if (str[len] == '\0') { return NULL; + } str += len; - if (strlen(str) == 0) + if (strlen(str) == 0) { return NULL; + } return str; } @@ -402,15 +420,18 @@ char *strnl(char *str) { char *strpcpy(char *dest, const char *src, const char *str) { size_t len; - if (src) + if (src) { len = strcspn(src, str); - else + } else { return NULL; + } - if (dest == NULL || strlen(dest) < len) + if (dest == NULL || strlen(dest) < len) { dest = realloc(dest, len + 1); - if (dest == NULL) + } + if (dest == NULL) { die(STATE_UNKNOWN, _("failed realloc in strpcpy\n")); + } strncpy(dest, src, len); dest[len] = '\0'; @@ -434,10 +455,11 @@ char *strpcpy(char *dest, const char *src, const char *str) { char *strpcat(char *dest, const char *src, const char *str) { size_t len, l2; - if (dest) + if (dest) { len = strlen(dest); - else + } else { len = 0; + } if (src) { l2 = strcspn(src, str); @@ -446,8 +468,9 @@ char *strpcat(char *dest, const char *src, const char *str) { } dest = realloc(dest, len + l2 + 1); - if (dest == NULL) + if (dest == NULL) { die(STATE_UNKNOWN, _("failed malloc in strscat\n")); + } strncpy(dest + len, src, l2); dest[len + l2] = '\0'; @@ -463,8 +486,9 @@ char *strpcat(char *dest, const char *src, const char *str) { int xvasprintf(char **strp, const char *fmt, va_list ap) { int result = vasprintf(strp, fmt, ap); - if (result == -1 || *strp == NULL) + if (result == -1 || *strp == NULL) { die(STATE_UNKNOWN, _("failed malloc in xvasprintf\n")); + } return result; } @@ -483,126 +507,145 @@ int xasprintf(char **strp, const char *fmt, ...) { * ******************************************************************************/ -char *perfdata(const char *label, long int val, const char *uom, int warnp, long int warn, int critp, long int crit, int minp, - long int minv, int maxp, long int maxv) { +char *perfdata(const char *label, long int val, const char *uom, bool warnp, long int warn, bool critp, long int crit, bool minp, + long int minv, bool maxp, long int maxv) { char *data = NULL; - if (strpbrk(label, "'= ")) + if (strpbrk(label, "'= ")) { xasprintf(&data, "'%s'=%ld%s;", label, val, uom); - else + } else { xasprintf(&data, "%s=%ld%s;", label, val, uom); + } - if (warnp) + if (warnp) { xasprintf(&data, "%s%ld;", data, warn); - else + } else { xasprintf(&data, "%s;", data); + } - if (critp) + if (critp) { xasprintf(&data, "%s%ld;", data, crit); - else + } else { xasprintf(&data, "%s;", data); + } - if (minp) + if (minp) { xasprintf(&data, "%s%ld;", data, minv); - else + } else { xasprintf(&data, "%s;", data); + } - if (maxp) + if (maxp) { xasprintf(&data, "%s%ld", data, maxv); + } return data; } -char *perfdata_uint64(const char *label, uint64_t val, const char *uom, int warnp, /* Warning present */ - uint64_t warn, int critp, /* Critical present */ - uint64_t crit, int minp, /* Minimum present */ - uint64_t minv, int maxp, /* Maximum present */ +char *perfdata_uint64(const char *label, uint64_t val, const char *uom, bool warnp, /* Warning present */ + uint64_t warn, bool critp, /* Critical present */ + uint64_t crit, bool minp, /* Minimum present */ + uint64_t minv, bool maxp, /* Maximum present */ uint64_t maxv) { char *data = NULL; - if (strpbrk(label, "'= ")) + if (strpbrk(label, "'= ")) { xasprintf(&data, "'%s'=%" PRIu64 "%s;", label, val, uom); - else + } else { xasprintf(&data, "%s=%" PRIu64 "%s;", label, val, uom); + } - if (warnp) + if (warnp) { xasprintf(&data, "%s%" PRIu64 ";", data, warn); - else + } else { xasprintf(&data, "%s;", data); + } - if (critp) + if (critp) { xasprintf(&data, "%s%" PRIu64 ";", data, crit); - else + } else { xasprintf(&data, "%s;", data); + } - if (minp) + if (minp) { xasprintf(&data, "%s%" PRIu64 ";", data, minv); - else + } else { xasprintf(&data, "%s;", data); + } - if (maxp) + if (maxp) { xasprintf(&data, "%s%" PRIu64, data, maxv); + } return data; } -char *perfdata_int64(const char *label, int64_t val, const char *uom, int warnp, /* Warning present */ - int64_t warn, int critp, /* Critical present */ - int64_t crit, int minp, /* Minimum present */ - int64_t minv, int maxp, /* Maximum present */ +char *perfdata_int64(const char *label, int64_t val, const char *uom, bool warnp, /* Warning present */ + int64_t warn, bool critp, /* Critical present */ + int64_t crit, bool minp, /* Minimum present */ + int64_t minv, bool maxp, /* Maximum present */ int64_t maxv) { char *data = NULL; - if (strpbrk(label, "'= ")) + if (strpbrk(label, "'= ")) { xasprintf(&data, "'%s'=%" PRId64 "%s;", label, val, uom); - else + } else { xasprintf(&data, "%s=%" PRId64 "%s;", label, val, uom); + } - if (warnp) + if (warnp) { xasprintf(&data, "%s%" PRId64 ";", data, warn); - else + } else { xasprintf(&data, "%s;", data); + } - if (critp) + if (critp) { xasprintf(&data, "%s%" PRId64 ";", data, crit); - else + } else { xasprintf(&data, "%s;", data); + } - if (minp) + if (minp) { xasprintf(&data, "%s%" PRId64 ";", data, minv); - else + } else { xasprintf(&data, "%s;", data); + } - if (maxp) + if (maxp) { xasprintf(&data, "%s%" PRId64, data, maxv); + } return data; } -char *fperfdata(const char *label, double val, const char *uom, int warnp, double warn, int critp, double crit, int minp, double minv, - int maxp, double maxv) { +char *fperfdata(const char *label, double val, const char *uom, bool warnp, double warn, bool critp, double crit, bool minp, double minv, + bool maxp, double maxv) { char *data = NULL; - if (strpbrk(label, "'= ")) + if (strpbrk(label, "'= ")) { xasprintf(&data, "'%s'=", label); - else + } else { xasprintf(&data, "%s=", label); + } xasprintf(&data, "%s%f", data, val); xasprintf(&data, "%s%s;", data, uom); - if (warnp) + if (warnp) { xasprintf(&data, "%s%f", data, warn); + } xasprintf(&data, "%s;", data); - if (critp) + if (critp) { xasprintf(&data, "%s%f", data, crit); + } xasprintf(&data, "%s;", data); - if (minp) + if (minp) { xasprintf(&data, "%s%f", data, minv); + } if (maxp) { xasprintf(&data, "%s;", data); @@ -612,28 +655,32 @@ char *fperfdata(const char *label, double val, const char *uom, int warnp, doubl return data; } -char *sperfdata(const char *label, double val, const char *uom, char *warn, char *crit, int minp, double minv, int maxp, double maxv) { +char *sperfdata(const char *label, double val, const char *uom, char *warn, char *crit, bool minp, double minv, bool maxp, double maxv) { char *data = NULL; - if (strpbrk(label, "'= ")) + if (strpbrk(label, "'= ")) { xasprintf(&data, "'%s'=", label); - else + } else { xasprintf(&data, "%s=", label); + } xasprintf(&data, "%s%f", data, val); xasprintf(&data, "%s%s;", data, uom); - if (warn != NULL) + if (warn != NULL) { xasprintf(&data, "%s%s", data, warn); + } xasprintf(&data, "%s;", data); - if (crit != NULL) + if (crit != NULL) { xasprintf(&data, "%s%s", data, crit); + } xasprintf(&data, "%s;", data); - if (minp) + if (minp) { xasprintf(&data, "%s%f", data, minv); + } if (maxp) { xasprintf(&data, "%s;", data); @@ -643,28 +690,32 @@ char *sperfdata(const char *label, double val, const char *uom, char *warn, char return data; } -char *sperfdata_int(const char *label, int val, const char *uom, char *warn, char *crit, int minp, int minv, int maxp, int maxv) { +char *sperfdata_int(const char *label, int val, const char *uom, char *warn, char *crit, bool minp, int minv, bool maxp, int maxv) { char *data = NULL; - if (strpbrk(label, "'= ")) + if (strpbrk(label, "'= ")) { xasprintf(&data, "'%s'=", label); - else + } else { xasprintf(&data, "%s=", label); + } xasprintf(&data, "%s%d", data, val); xasprintf(&data, "%s%s;", data, uom); - if (warn != NULL) + if (warn != NULL) { xasprintf(&data, "%s%s", data, warn); + } xasprintf(&data, "%s;", data); - if (crit != NULL) + if (crit != NULL) { xasprintf(&data, "%s%s", data, crit); + } xasprintf(&data, "%s;", data); - if (minp) + if (minp) { xasprintf(&data, "%s%d", data, minv); + } if (maxp) { xasprintf(&data, "%s;", data); diff --git a/plugins/utils.h b/plugins/utils.h index 029ae5a6..92a6c115 100644 --- a/plugins/utils.h +++ b/plugins/utils.h @@ -21,43 +21,43 @@ suite of plugins. */ #ifdef NP_EXTRA_OPTS /* Include extra-opts functions if compiled in */ -#include "extra_opts.h" +# include "extra_opts.h" #else /* else, fake np_extra_opts */ -#define np_extra_opts(acptr,av,pr) av +# define np_extra_opts(acptr, av, pr) av #endif /* Standardize version information, termination */ -void support (void); -void print_revision (const char *, const char *); +void support(void); +void print_revision(const char *, const char *); extern time_t start_time, end_time; /* Test input types */ -bool is_integer (char *); -bool is_intpos (char *); -bool is_intneg (char *); -bool is_intnonneg (char *); -bool is_intpercent (char *); +bool is_integer(char *); +bool is_intpos(char *); +bool is_intneg(char *); +bool is_intnonneg(char *); +bool is_intpercent(char *); bool is_uint64(char *number, uint64_t *target); bool is_int64(char *number, int64_t *target); -bool is_numeric (char *); -bool is_positive (char *); -bool is_negative (char *); -bool is_nonnegative (char *); -bool is_percentage (char *); -bool is_percentage_expression (const char[]); +bool is_numeric(char *); +bool is_positive(char *); +bool is_negative(char *); +bool is_nonnegative(char *); +bool is_percentage(char *); +bool is_percentage_expression(const char[]); -bool is_option (char *); +bool is_option(char *); /* Generalized timer that will do milliseconds if available */ #ifndef HAVE_STRUCT_TIMEVAL struct timeval { - long tv_sec; /* seconds */ - long tv_usec; /* microseconds */ + long tv_sec; /* seconds */ + long tv_usec; /* microseconds */ }; #endif @@ -65,137 +65,142 @@ struct timeval { int gettimeofday(struct timeval *, struct timezone *); #endif -double delta_time (struct timeval tv); -long deltime (struct timeval tv); +double delta_time(struct timeval tv); +long deltime(struct timeval tv); /* Handle strings safely */ -void strip (char *); -char *strscpy (char *, const char *); -char *strnl (char *); -char *strpcpy (char *, const char *, const char *); -char *strpcat (char *, const char *, const char *); -int xvasprintf (char **strp, const char *fmt, va_list ap); -int xasprintf (char **strp, const char *fmt, ...); +void strip(char *); +char *strscpy(char *, const char *); +char *strnl(char *); +char *strpcpy(char *, const char *, const char *); +char *strpcat(char *, const char *, const char *); +int xvasprintf(char **strp, const char *fmt, va_list ap); +int xasprintf(char **strp, const char *fmt, ...); -void usage (const char *) __attribute__((noreturn)); +void usage(const char *) __attribute__((noreturn)); void usage2(const char *, const char *) __attribute__((noreturn)); void usage3(const char *, int) __attribute__((noreturn)); void usage4(const char *) __attribute__((noreturn)); void usage5(void) __attribute__((noreturn)); void usage_va(const char *fmt, ...) __attribute__((noreturn)); -#define max(a,b) (((a)>(b))?(a):(b)) -#define min(a,b) (((a)<(b))?(a):(b)) +#define max(a, b) (((a) > (b)) ? (a) : (b)) +#define min(a, b) (((a) < (b)) ? (a) : (b)) -char *perfdata (const char *, long int, const char *, int, long int, - int, long int, int, long int, int, long int); +char *perfdata(const char *, long int, const char *, bool, long int, bool, long int, bool, long int, bool, long int); -char *perfdata_uint64 (const char *, uint64_t , const char *, int, uint64_t, - int, uint64_t, int, uint64_t, int, uint64_t); +char *perfdata_uint64(const char *, uint64_t, const char *, bool, uint64_t, bool, uint64_t, bool, uint64_t, bool, uint64_t); -char *perfdata_int64 (const char *, int64_t, const char *, int, int64_t, - int, int64_t, int, int64_t, int, int64_t); +char *perfdata_int64(const char *, int64_t, const char *, bool, int64_t, bool, int64_t, bool, int64_t, bool, int64_t); -char *fperfdata (const char *, double, const char *, int, double, - int, double, int, double, int, double); +char *fperfdata(const char *, double, const char *, bool, double, bool, double, bool, double, bool, double); -char *sperfdata (const char *, double, const char *, char *, char *, - int, double, int, double); +char *sperfdata(const char *, double, const char *, char *, char *, bool, double, bool, double); -char *sperfdata_int (const char *, int, const char *, char *, char *, - int, int, int, int); +char *sperfdata_int(const char *, int, const char *, char *, char *, bool, int, bool, int); -/* The idea here is that, although not every plugin will use all of these, - most will or should. Therefore, for consistency, these very common +/* The idea here is that, although not every plugin will use all of these, + most will or should. Therefore, for consistency, these very common options should have only these meanings throughout the overall suite */ -#define STD_LONG_OPTS \ -{"version",no_argument,0,'V'},\ -{"verbose",no_argument,0,'v'},\ -{"help",no_argument,0,'h'},\ -{"timeout",required_argument,0,'t'},\ -{"critical",required_argument,0,'c'},\ -{"warning",required_argument,0,'w'},\ -{"hostname",required_argument,0,'H'} +#define STD_LONG_OPTS \ + {"version", no_argument, 0, 'V'}, {"verbose", no_argument, 0, 'v'}, {"help", no_argument, 0, 'h'}, \ + {"timeout", required_argument, 0, 't'}, {"critical", required_argument, 0, 'c'}, {"warning", required_argument, 0, 'w'}, \ + {"hostname", required_argument, 0, 'H'} -#define COPYRIGHT "Copyright (c) %s Monitoring Plugins Development Team\n\ +#define COPYRIGHT \ + "Copyright (c) %s Monitoring Plugins Development Team\n\ \t<%s>\n\n" -#define UT_HLP_VRS _("\ +#define UT_HLP_VRS \ + _("\ %s (-h | --help) for detailed help\n\ %s (-V | --version) for version information\n") -#define UT_HELP_VRSN _("\ +#define UT_HELP_VRSN \ + _("\ \nOptions:\n\ -h, --help\n\ Print detailed help screen\n\ -V, --version\n\ Print version information\n") -#define UT_HOST_PORT _("\ +#define UT_HOST_PORT \ + _("\ -H, --hostname=ADDRESS\n\ Host name, IP Address, or unix socket (must be an absolute path)\n\ -%c, --port=INTEGER\n\ Port number (default: %s)\n") -#define UT_IPv46 _("\ +#define UT_IPv46 \ + _("\ -4, --use-ipv4\n\ Use IPv4 connection\n\ -6, --use-ipv6\n\ Use IPv6 connection\n") -#define UT_VERBOSE _("\ +#define UT_VERBOSE \ + _("\ -v, --verbose\n\ Show details for command-line debugging (output may be truncated by\n\ the monitoring system)\n") -#define UT_WARN_CRIT _("\ +#define UT_WARN_CRIT \ + _("\ -w, --warning=DOUBLE\n\ Response time to result in warning status (seconds)\n\ -c, --critical=DOUBLE\n\ Response time to result in critical status (seconds)\n") -#define UT_WARN_CRIT_RANGE _("\ +#define UT_WARN_CRIT_RANGE \ + _("\ -w, --warning=RANGE\n\ Warning range (format: start:end). Alert if outside this range\n\ -c, --critical=RANGE\n\ Critical range\n") -#define UT_CONN_TIMEOUT _("\ +#define UT_CONN_TIMEOUT \ + _("\ -t, --timeout=INTEGER\n\ Seconds before connection times out (default: %d)\n") -#define UT_PLUG_TIMEOUT _("\ +#define UT_PLUG_TIMEOUT \ + _("\ -t, --timeout=INTEGER\n\ Seconds before plugin times out (default: %d)\n") #ifdef NP_EXTRA_OPTS -#define UT_EXTRA_OPTS _("\ +# define UT_EXTRA_OPTS \ + _("\ --extra-opts=[section][@file]\n\ Read options from an ini file. See\n\ https://www.monitoring-plugins.org/doc/extra-opts.html\n\ for usage and examples.\n") #else -#define UT_EXTRA_OPTS " \b" +# define UT_EXTRA_OPTS " \b" #endif -#define UT_THRESHOLDS_NOTES _("\ +#define UT_THRESHOLDS_NOTES \ + _("\ See:\n\ https://www.monitoring-plugins.org/doc/guidelines.html#THRESHOLDFORMAT\n\ for THRESHOLD format and examples.\n") -#define UT_SUPPORT _("\n\ +#define UT_SUPPORT \ + _("\n\ Send email to help@monitoring-plugins.org if you have questions regarding\n\ use of this software. To submit patches or suggest improvements, send email\n\ to devel@monitoring-plugins.org\n\n") -#define UT_NOWARRANTY _("\n\ +#define UT_NOWARRANTY \ + _("\n\ The Monitoring Plugins come with ABSOLUTELY NO WARRANTY. You may redistribute\n\ copies of the plugins under the terms of the GNU General Public License.\n\ For more information about these matters, see the file named COPYING.\n") -#define UT_OUTPUT_FORMAT _("\ +#define UT_OUTPUT_FORMAT \ + _("\ --output-format=OUTPUT_FORMAT\n\ Select output format. Valid values: \"multi-line\", \"mp-test-json\"\n") -- cgit v1.2.3-74-g34f1 From 9f8a485744ba8de13c01cc48a4db0d8d73189c97 Mon Sep 17 00:00:00 2001 From: Lorenz Kästle <12514511+RincewindsHat@users.noreply.github.com> Date: Fri, 7 Mar 2025 15:58:30 +0100 Subject: Refactor check_game --- plugins/check_game.c | 211 ++++++++++++++++++++++-------------------- plugins/check_game.d/config.h | 30 ++++++ 2 files changed, 139 insertions(+), 102 deletions(-) create mode 100644 plugins/check_game.d/config.h 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 + +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; +} -- cgit v1.2.3-74-g34f1 From 4322bbf23b8f65cf070079aa024e04105e4ccf98 Mon Sep 17 00:00:00 2001 From: Lorenz Kästle <12514511+RincewindsHat@users.noreply.github.com> Date: Fri, 7 Mar 2025 16:08:46 +0100 Subject: Pack new check_game files into tarball --- plugins/Makefile.am | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/plugins/Makefile.am b/plugins/Makefile.am index d43c1971..fb689f87 100644 --- a/plugins/Makefile.am +++ b/plugins/Makefile.am @@ -46,7 +46,11 @@ SUBDIRS = picohttpparser np_test_scripts = tests/test_check_swap.t -EXTRA_DIST = t tests $(np_test_scripts) check_swap.d +EXTRA_DIST = t \ + tests \ + $(np_test_scripts) \ + check_swap.d \ + check_game.d PLUGINHDRS = common.h -- cgit v1.2.3-74-g34f1 From 61d3dc00cbba6ab10cb8a181294c120741a34882 Mon Sep 17 00:00:00 2001 From: Lorenz Kästle <12514511+RincewindsHat@users.noreply.github.com> Date: Fri, 7 Mar 2025 16:10:01 +0100 Subject: clang-format + add host option in usage --- plugins/check_game.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/plugins/check_game.c b/plugins/check_game.c index 58014c3e..d078e4b5 100644 --- a/plugins/check_game.c +++ b/plugins/check_game.c @@ -130,16 +130,17 @@ 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[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])), + 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)); } exit(result); } -#define players_field_index 129 +#define players_field_index 129 #define max_players_field_index 130 check_game_config_wrapper process_arguments(int argc, char **argv) { @@ -284,7 +285,8 @@ void print_help(void) { printf(UT_HELP_VRSN); printf(UT_EXTRA_OPTS); - + printf(" -H, --hostname=ADDRESS\n" + " Host name, IP Address, or unix socket (must be an absolute path)\n"); printf(" %s\n", "-p"); printf(" %s\n", _("Optional port of which to connect")); printf(" %s\n", "gf"); -- cgit v1.2.3-74-g34f1 From 5ad1c0e821a5aaafe47dbe79d5f69820fde798bd Mon Sep 17 00:00:00 2001 From: Lorenz Kästle <12514511+RincewindsHat@users.noreply.github.com> Date: Fri, 7 Mar 2025 09:09:45 +0100 Subject: Implement JSON output parsing for tests --- NPTest.pm | 4 ++++ plugins/t/check_swap.t | 35 ++++++++++++++--------------------- 2 files changed, 18 insertions(+), 21 deletions(-) diff --git a/NPTest.pm b/NPTest.pm index 9b25ac3e..47773acc 100644 --- a/NPTest.pm +++ b/NPTest.pm @@ -15,6 +15,8 @@ use warnings; use Cwd; use File::Basename; +use JSON; + use IO::File; use Data::Dumper; @@ -617,6 +619,8 @@ sub testCmd { chomp $output; $object->output($output); + $object->{'mp_test_result'} = decode_json($output); + alarm(0); my ($pkg, $file, $line) = caller(0); diff --git a/plugins/t/check_swap.t b/plugins/t/check_swap.t index 7e61b766..68946f6d 100644 --- a/plugins/t/check_swap.t +++ b/plugins/t/check_swap.t @@ -17,42 +17,35 @@ my $message = '/^[0-9]+\% free \([0-9]+MiB out of [0-9]+MiB\)/'; $result = NPTest->testCmd( "./check_swap $outputFormat" ); # Always OK cmp_ok( $result->return_code, "==", 0, "Always OK" ); -$output = decode_json($result->output); -is($output->{'state'}, "OK", "State was correct"); -like($output->{'checks'}->[0]->{'output'}, $message, "Output was correct"); +is($result->{'mp_test_result'}->{'state'}, "OK", "State was correct"); +like($result->{'mp_test_result'}->{'checks'}->[0]->{'output'}, $message, "Output was correct"); $result = NPTest->testCmd( "./check_swap -w 1048576 -c 1048576 $outputFormat" ); # 1 MB free cmp_ok( $result->return_code, "==", 0, "Always OK" ); -$output = decode_json($result->output); -is($output->{'state'}, "OK", "State was correct"); -like($output->{'checks'}->[0]->{'output'}, $message, "Output was correct"); +is($result->{'mp_test_result'}->{'state'}, "OK", "State was correct"); +like($result->{'mp_test_result'}->{'checks'}->[0]->{'output'}, $message, "Output was correct"); $result = NPTest->testCmd( "./check_swap -w 1% -c 1% $outputFormat" ); # 1% free cmp_ok( $result->return_code, "==", 0, "Always OK" ); -$output = decode_json($result->output); -is($output->{'state'}, "OK", "State was correct"); -like($output->{'checks'}->[0]->{'output'}, $message, "Output was correct"); +is($result->{'mp_test_result'}->{'state'}, "OK", "State was correct"); +like($result->{'mp_test_result'}->{'checks'}->[0]->{'output'}, $message, "Output was correct"); $result = NPTest->testCmd( "./check_swap -w 100% -c 100% $outputFormat" ); # 100% (always critical) cmp_ok( $result->return_code, "==", 0, "Always OK" ); -$output = decode_json($result->output); -is($output->{'state'}, "CRITICAL", "State was correct"); -like($output->{'checks'}->[0]->{'output'}, $message, "Output was correct"); +is($result->{'mp_test_result'}->{'state'}, "CRITICAL", "State was correct"); +like($result->{'mp_test_result'}->{'checks'}->[0]->{'output'}, $message, "Output was correct"); $result = NPTest->testCmd( "./check_swap -w 100% -c 1% $outputFormat" ); # 100% (always warn) cmp_ok( $result->return_code, "==", 0, "Always OK" ); -$output = decode_json($result->output); -is($output->{'state'}, "WARNING", "State was correct"); -like($output->{'checks'}->[0]->{'output'}, $message, "Output was correct"); +is($result->{'mp_test_result'}->{'state'}, "WARNING", "State was correct"); +like($result->{'mp_test_result'}->{'checks'}->[0]->{'output'}, $message, "Output was correct"); $result = NPTest->testCmd( "./check_swap -w 100% $outputFormat" ); # 100% (single threshold, always warn) cmp_ok( $result->return_code, "==", 0, "Always OK" ); -$output = decode_json($result->output); -is($output->{'state'}, "WARNING", "State was correct"); -like($output->{'checks'}->[0]->{'output'}, $message, "Output was correct"); +is($result->{'mp_test_result'}->{'state'}, "WARNING", "State was correct"); +like($result->{'mp_test_result'}->{'checks'}->[0]->{'output'}, $message, "Output was correct"); $result = NPTest->testCmd( "./check_swap -c 100% $outputFormat" ); # 100% (single threshold, always critical) cmp_ok( $result->return_code, "==", 0, "Always OK" ); -$output = decode_json($result->output); -is($output->{'state'}, "CRITICAL", "State was correct"); -like($output->{'checks'}->[0]->{'output'}, $message, "Output was correct"); +is($result->{'mp_test_result'}->{'state'}, "CRITICAL", "State was correct"); +like($result->{'mp_test_result'}->{'checks'}->[0]->{'output'}, $message, "Output was correct"); -- cgit v1.2.3-74-g34f1 From 18dedf3463534a9f6c8137628c482298dbb0459b Mon Sep 17 00:00:00 2001 From: Lorenz Kästle <12514511+RincewindsHat@users.noreply.github.com> Date: Fri, 7 Mar 2025 17:28:36 +0100 Subject: Do not die in tests if JSON Parsing fails --- NPTest.pm | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/NPTest.pm b/NPTest.pm index 47773acc..f9f18b5f 100644 --- a/NPTest.pm +++ b/NPTest.pm @@ -17,6 +17,8 @@ use File::Basename; use JSON; +use feature 'try'; + use IO::File; use Data::Dumper; @@ -619,7 +621,9 @@ sub testCmd { chomp $output; $object->output($output); - $object->{'mp_test_result'} = decode_json($output); + try { + $object->{'mp_test_result'} = decode_json($output); + } alarm(0); -- cgit v1.2.3-74-g34f1 From f2275431783a5aaed25c35b5deec37c244872a7a Mon Sep 17 00:00:00 2001 From: Lorenz Kästle <12514511+RincewindsHat@users.noreply.github.com> Date: Fri, 7 Mar 2025 17:48:27 +0100 Subject: Use Try::Tiny instead of experimental feature --- NPTest.pm | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/NPTest.pm b/NPTest.pm index f9f18b5f..987d3b71 100644 --- a/NPTest.pm +++ b/NPTest.pm @@ -17,7 +17,7 @@ use File::Basename; use JSON; -use feature 'try'; +use Try::Tiny; use IO::File; use Data::Dumper; @@ -623,7 +623,7 @@ sub testCmd { try { $object->{'mp_test_result'} = decode_json($output); - } + }; alarm(0); -- cgit v1.2.3-74-g34f1 From 2727f32f194233e9fdc333afa26a23d8759362ac Mon Sep 17 00:00:00 2001 From: Lorenz Kästle <12514511+RincewindsHat@users.noreply.github.com> Date: Fri, 7 Mar 2025 11:42:22 +0100 Subject: Refactor check_dbi --- plugins/Makefile.am | 2 +- plugins/check_dbi.c | 339 +++++++++++++++++++++---------------------- plugins/check_dbi.d/config.h | 63 ++++++++ 3 files changed, 231 insertions(+), 173 deletions(-) create mode 100644 plugins/check_dbi.d/config.h diff --git a/plugins/Makefile.am b/plugins/Makefile.am index d43c1971..a0e9cabf 100644 --- a/plugins/Makefile.am +++ b/plugins/Makefile.am @@ -46,7 +46,7 @@ SUBDIRS = picohttpparser np_test_scripts = tests/test_check_swap.t -EXTRA_DIST = t tests $(np_test_scripts) check_swap.d +EXTRA_DIST = t tests $(np_test_scripts) check_swap.d check_dbi.d PLUGINHDRS = common.h diff --git a/plugins/check_dbi.c b/plugins/check_dbi.c index ae8ec952..1f4a7def 100644 --- a/plugins/check_dbi.c +++ b/plugins/check_dbi.c @@ -33,6 +33,8 @@ const char *progname = "check_dbi"; const char *copyright = "2011-2024"; const char *email = "devel@monitoring-plugins.org"; +#include "../lib/monitoringplug.h" +#include "check_dbi.d/config.h" #include "common.h" #include "utils.h" #include "utils_cmd.h" @@ -53,55 +55,24 @@ const char *email = "devel@monitoring-plugins.org"; #include -typedef enum { - METRIC_CONN_TIME, - METRIC_SERVER_VERSION, - METRIC_QUERY_RESULT, - METRIC_QUERY_TIME, -} np_dbi_metric_t; - -typedef enum { - TYPE_NUMERIC, - TYPE_STRING, -} np_dbi_type_t; - -typedef struct { - char *key; - char *value; -} driver_option_t; - -static char *host = NULL; static int verbose = 0; -static char *warning_range = NULL; -static char *critical_range = NULL; -static thresholds *dbi_thresholds = NULL; - -static char *expect = NULL; - -static regex_t expect_re; -static char *expect_re_str = NULL; -static int expect_re_cflags = 0; - -static np_dbi_metric_t metric = METRIC_QUERY_RESULT; -static np_dbi_type_t type = TYPE_NUMERIC; - -static char *np_dbi_driver = NULL; -static driver_option_t *np_dbi_options = NULL; -static int np_dbi_options_num = 0; -static char *np_dbi_database = NULL; -static char *np_dbi_query = NULL; +typedef struct { + int errorcode; + check_dbi_config config; +} check_dbi_config_wrapper; -static int process_arguments(int, char **); -static int validate_arguments(void); +static check_dbi_config_wrapper process_arguments(int /*argc*/, char ** /*argv*/); +static check_dbi_config_wrapper validate_arguments(check_dbi_config_wrapper /*config_wrapper*/); void print_usage(void); static void print_help(void); -static double timediff(struct timeval, struct timeval); +static double timediff(struct timeval /*start*/, struct timeval /*end*/); -static void np_dbi_print_error(dbi_conn, char *, ...); +static void np_dbi_print_error(dbi_conn /*conn*/, char * /*fmt*/, ...); -static int do_query(dbi_conn, const char **, double *, double *); +static mp_state_enum do_query(dbi_conn /*conn*/, const char ** /*res_val_str*/, double * /*res_val*/, double * /*res_time*/, mp_dbi_metric /*metric*/, + mp_dbi_type /*type*/, char * /*np_dbi_query*/); int main(int argc, char **argv) { int status = STATE_UNKNOWN; @@ -119,8 +90,6 @@ int main(int argc, char **argv) { const char *query_val_str = NULL; double query_val = 0.0; - int i; - setlocale(LC_ALL, ""); bindtextdomain(PACKAGE, LOCALEDIR); textdomain(PACKAGE); @@ -128,10 +97,14 @@ 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_dbi_config_wrapper tmp = process_arguments(argc, argv); + + if (tmp.errorcode == ERROR) { usage4(_("Could not parse arguments")); } + check_dbi_config config = tmp.config; + /* Set signal handling and alarm */ if (signal(SIGALRM, timeout_alarm_handler) == SIG_ERR) { usage4(_("Cannot catch SIGALRM")); @@ -155,12 +128,12 @@ int main(int argc, char **argv) { } if (verbose) { - printf("Opening DBI driver '%s'\n", np_dbi_driver); + printf("Opening DBI driver '%s'\n", config.dbi_driver); } - driver = dbi_driver_open_r(np_dbi_driver, instance_p); + driver = dbi_driver_open_r(config.dbi_driver, instance_p); if (!driver) { - printf("UNKNOWN - failed to open DBI driver '%s'; possibly it's not installed.\n", np_dbi_driver); + printf("UNKNOWN - failed to open DBI driver '%s'; possibly it's not installed.\n", config.dbi_driver); printf("Known drivers:\n"); for (driver = dbi_driver_list_r(NULL, instance_p); driver; driver = dbi_driver_list_r(driver, instance_p)) { @@ -179,19 +152,19 @@ int main(int argc, char **argv) { return STATE_UNKNOWN; } - for (i = 0; i < np_dbi_options_num; ++i) { + for (size_t i = 0; i < config.dbi_options_num; ++i) { const char *opt; if (verbose > 1) { - printf("Setting DBI driver option '%s' to '%s'\n", np_dbi_options[i].key, np_dbi_options[i].value); + printf("Setting DBI driver option '%s' to '%s'\n", config.dbi_options[i].key, config.dbi_options[i].value); } - if (!dbi_conn_set_option(conn, np_dbi_options[i].key, np_dbi_options[i].value)) { + if (!dbi_conn_set_option(conn, config.dbi_options[i].key, config.dbi_options[i].value)) { continue; } /* else: status != 0 */ - np_dbi_print_error(conn, "UNKNOWN - failed to set option '%s' to '%s'", np_dbi_options[i].key, np_dbi_options[i].value); + np_dbi_print_error(conn, "UNKNOWN - failed to set option '%s' to '%s'", config.dbi_options[i].key, config.dbi_options[i].value); printf("Known driver options:\n"); for (opt = dbi_conn_get_option_list(conn, NULL); opt; opt = dbi_conn_get_option_list(conn, opt)) { @@ -201,11 +174,11 @@ int main(int argc, char **argv) { return STATE_UNKNOWN; } - if (host) { + if (config.host) { if (verbose > 1) { - printf("Setting DBI driver option 'host' to '%s'\n", host); + printf("Setting DBI driver option 'host' to '%s'\n", config.host); } - dbi_conn_set_option(conn, "host", host); + dbi_conn_set_option(conn, "host", config.host); } if (verbose) { @@ -238,48 +211,49 @@ int main(int argc, char **argv) { printf("Connected to server version %u\n", server_version); } - if (metric == METRIC_SERVER_VERSION) { - status = get_status(server_version, dbi_thresholds); + if (config.metric == METRIC_SERVER_VERSION) { + status = get_status(server_version, config.dbi_thresholds); } if (verbose) { printf("Time elapsed: %f\n", conn_time); } - if (metric == METRIC_CONN_TIME) { - status = get_status(conn_time, dbi_thresholds); + if (config.metric == METRIC_CONN_TIME) { + status = get_status(conn_time, config.dbi_thresholds); } /* select a database */ - if (np_dbi_database) { + if (config.dbi_database) { if (verbose > 1) { - printf("Selecting database '%s'\n", np_dbi_database); + printf("Selecting database '%s'\n", config.dbi_database); } - if (dbi_conn_select_db(conn, np_dbi_database)) { - np_dbi_print_error(conn, "UNKNOWN - failed to select database '%s'", np_dbi_database); + if (dbi_conn_select_db(conn, config.dbi_database)) { + np_dbi_print_error(conn, "UNKNOWN - failed to select database '%s'", config.dbi_database); return STATE_UNKNOWN; } } - if (np_dbi_query) { + if (config.dbi_query) { /* execute query */ - status = do_query(conn, &query_val_str, &query_val, &query_time); + status = do_query(conn, &query_val_str, &query_val, &query_time, config.metric, config.type, config.dbi_query); if (status != STATE_OK) { /* do_query prints an error message in this case */ return status; } - if (metric == METRIC_QUERY_RESULT) { - if (expect) { - if ((!query_val_str) || strcmp(query_val_str, expect)) { + if (config.metric == METRIC_QUERY_RESULT) { + if (config.expect) { + if ((!query_val_str) || strcmp(query_val_str, config.expect)) { status = STATE_CRITICAL; } else { status = STATE_OK; } - } else if (expect_re_str) { + } else if (config.expect_re_str) { int err; + regex_t expect_re = {}; err = regexec(&expect_re, query_val_str, 0, NULL, /* flags = */ 0); if (!err) { status = STATE_OK; @@ -292,10 +266,10 @@ int main(int argc, char **argv) { status = STATE_CRITICAL; } } else { - status = get_status(query_val, dbi_thresholds); + status = get_status(query_val, config.dbi_thresholds); } - } else if (metric == METRIC_QUERY_TIME) { - status = get_status(query_time, dbi_thresholds); + } else if (config.metric == METRIC_QUERY_TIME) { + status = get_status(query_time, config.dbi_thresholds); } } @@ -307,49 +281,48 @@ int main(int argc, char **argv) { /* In case of METRIC_QUERY_RESULT, isnan(query_val) indicates an error * which should have been reported and handled (abort) before * ... unless we expected a string to be returned */ - assert((metric != METRIC_QUERY_RESULT) || (!isnan(query_val)) || (type == TYPE_STRING)); + assert((config.metric != METRIC_QUERY_RESULT) || (!isnan(query_val)) || (config.type == TYPE_STRING)); - assert((type != TYPE_STRING) || (expect || expect_re_str)); + assert((config.type != TYPE_STRING) || (config.expect || config.expect_re_str)); printf("%s - connection time: %fs", state_text(status), conn_time); - if (np_dbi_query) { - if (type == TYPE_STRING) { - assert(expect || expect_re_str); - printf(", '%s' returned '%s' in %fs", np_dbi_query, query_val_str ? query_val_str : "", query_time); + if (config.dbi_query) { + if (config.type == TYPE_STRING) { + assert(config.expect || config.expect_re_str); + printf(", '%s' returned '%s' in %fs", config.dbi_query, query_val_str ? query_val_str : "", query_time); if (status != STATE_OK) { - if (expect) { - printf(" (expected '%s')", expect); - } else if (expect_re_str) { - printf(" (expected regex /%s/%s)", expect_re_str, ((expect_re_cflags & REG_ICASE) ? "i" : "")); + if (config.expect) { + printf(" (expected '%s')", config.expect); + } else if (config.expect_re_str) { + printf(" (expected regex /%s/%s)", config.expect_re_str, ((config.expect_re_cflags & REG_ICASE) ? "i" : "")); } } } else if (isnan(query_val)) { - printf(", '%s' query execution time: %fs", np_dbi_query, query_time); + printf(", '%s' query execution time: %fs", config.dbi_query, query_time); } else { - printf(", '%s' returned %f in %fs", np_dbi_query, query_val, query_time); + printf(", '%s' returned %f in %fs", config.dbi_query, query_val, query_time); } } printf(" | conntime=%fs;%s;%s;0; server_version=%u;%s;%s;0;", conn_time, - ((metric == METRIC_CONN_TIME) && warning_range) ? warning_range : "", - ((metric == METRIC_CONN_TIME) && critical_range) ? critical_range : "", server_version, - ((metric == METRIC_SERVER_VERSION) && warning_range) ? warning_range : "", - ((metric == METRIC_SERVER_VERSION) && critical_range) ? critical_range : ""); - if (np_dbi_query) { + ((config.metric == METRIC_CONN_TIME) && config.warning_range) ? config.warning_range : "", + ((config.metric == METRIC_CONN_TIME) && config.critical_range) ? config.critical_range : "", server_version, + ((config.metric == METRIC_SERVER_VERSION) && config.warning_range) ? config.warning_range : "", + ((config.metric == METRIC_SERVER_VERSION) && config.critical_range) ? config.critical_range : ""); + if (config.dbi_query) { if (!isnan(query_val)) { /* this is also true when -e is used */ - printf(" query=%f;%s;%s;;", query_val, ((metric == METRIC_QUERY_RESULT) && warning_range) ? warning_range : "", - ((metric == METRIC_QUERY_RESULT) && critical_range) ? critical_range : ""); + printf(" query=%f;%s;%s;;", query_val, ((config.metric == METRIC_QUERY_RESULT) && config.warning_range) ? config.warning_range : "", + ((config.metric == METRIC_QUERY_RESULT) && config.critical_range) ? config.critical_range : ""); } - printf(" querytime=%fs;%s;%s;0;", query_time, ((metric == METRIC_QUERY_TIME) && warning_range) ? warning_range : "", - ((metric == METRIC_QUERY_TIME) && critical_range) ? critical_range : ""); + printf(" querytime=%fs;%s;%s;0;", query_time, ((config.metric == METRIC_QUERY_TIME) && config.warning_range) ? config.warning_range : "", + ((config.metric == METRIC_QUERY_TIME) && config.critical_range) ? config.critical_range : ""); } printf("\n"); return status; } /* process command-line arguments */ -int process_arguments(int argc, char **argv) { - int c; +check_dbi_config_wrapper process_arguments(int argc, char **argv) { int option = 0; static struct option longopts[] = {STD_LONG_OPTS, @@ -364,14 +337,19 @@ int process_arguments(int argc, char **argv) { {"database", required_argument, 0, 'D'}, {0, 0, 0, 0}}; - while (1) { - c = getopt_long(argc, argv, "Vvht:c:w:e:r:R:m:H:d:o:q:D:", longopts, &option); + check_dbi_config_wrapper result = { + .config = check_dbi_config_init(), + .errorcode = OK, + }; + int option_char; + while (true) { + option_char = getopt_long(argc, argv, "Vvht:c:w:e:r:R:m:H:d:o:q:D:", longopts, &option); - if (c == EOF) { + if (option_char == EOF) { break; } - switch (c) { + switch (option_char) { case '?': /* usage */ usage5(); case 'h': /* help */ @@ -382,46 +360,49 @@ int process_arguments(int argc, char **argv) { exit(STATE_UNKNOWN); case 'c': /* critical range */ - critical_range = optarg; - type = TYPE_NUMERIC; + result.config.critical_range = optarg; + result.config.type = TYPE_NUMERIC; break; case 'w': /* warning range */ - warning_range = optarg; - type = TYPE_NUMERIC; + result.config.warning_range = optarg; + result.config.type = TYPE_NUMERIC; break; case 'e': - expect = optarg; - type = TYPE_STRING; + result.config.expect = optarg; + result.config.type = TYPE_STRING; break; case 'R': - expect_re_cflags = REG_ICASE; + result.config.expect_re_cflags = REG_ICASE; /* fall through */ case 'r': { int err; - expect_re_cflags |= REG_EXTENDED | REG_NOSUB | REG_NEWLINE; - expect_re_str = optarg; - type = TYPE_STRING; + result.config.expect_re_cflags |= REG_EXTENDED | REG_NOSUB | REG_NEWLINE; + result.config.expect_re_str = optarg; + result.config.type = TYPE_STRING; - err = regcomp(&expect_re, expect_re_str, expect_re_cflags); + regex_t expect_re = {}; + err = regcomp(&expect_re, result.config.expect_re_str, result.config.expect_re_cflags); if (err) { char errmsg[1024]; regerror(err, &expect_re, errmsg, sizeof(errmsg)); printf("ERROR - failed to compile regular expression: %s\n", errmsg); - return ERROR; + + result.errorcode = ERROR; + return result; } break; } case 'm': if (!strcasecmp(optarg, "CONN_TIME")) { - metric = METRIC_CONN_TIME; + result.config.metric = METRIC_CONN_TIME; } else if (!strcasecmp(optarg, "SERVER_VERSION")) { - metric = METRIC_SERVER_VERSION; + result.config.metric = METRIC_SERVER_VERSION; } else if (!strcasecmp(optarg, "QUERY_RESULT")) { - metric = METRIC_QUERY_RESULT; + result.config.metric = METRIC_QUERY_RESULT; } else if (!strcasecmp(optarg, "QUERY_TIME")) { - metric = METRIC_QUERY_TIME; + result.config.metric = METRIC_QUERY_TIME; } else { usage2(_("Invalid metric"), optarg); } @@ -438,7 +419,7 @@ int process_arguments(int argc, char **argv) { if (!is_host(optarg)) { usage2(_("Invalid hostname/address"), optarg); } else { - host = optarg; + result.config.host = optarg; } break; case 'v': @@ -446,82 +427,81 @@ int process_arguments(int argc, char **argv) { break; case 'd': - np_dbi_driver = optarg; + result.config.dbi_driver = optarg; break; case 'o': { - driver_option_t *new; + driver_option_t *new = NULL; - char *k; - char *v; + char *key = optarg; + char *value = strchr(key, '='); - k = optarg; - v = strchr(k, (int)'='); - - if (!v) { + if (!value) { usage2(_("Option must be '='"), optarg); } - *v = '\0'; - ++v; + *value = '\0'; + ++value; - new = realloc(np_dbi_options, (np_dbi_options_num + 1) * sizeof(*new)); + new = realloc(result.config.dbi_options, (result.config.dbi_options_num + 1) * sizeof(*new)); if (!new) { printf("UNKNOWN - failed to reallocate memory\n"); exit(STATE_UNKNOWN); } - np_dbi_options = new; - new = np_dbi_options + np_dbi_options_num; - ++np_dbi_options_num; + result.config.dbi_options = new; + new = result.config.dbi_options + result.config.dbi_options_num; + result.config.dbi_options_num++; - new->key = k; - new->value = v; + new->key = key; + new->value = value; } break; case 'q': - np_dbi_query = optarg; + result.config.dbi_query = optarg; break; case 'D': - np_dbi_database = optarg; + result.config.dbi_database = optarg; break; } } - set_thresholds(&dbi_thresholds, warning_range, critical_range); + set_thresholds(&result.config.dbi_thresholds, result.config.warning_range, result.config.critical_range); - return validate_arguments(); + return validate_arguments(result); } -int validate_arguments(void) { - if (!np_dbi_driver) { +check_dbi_config_wrapper validate_arguments(check_dbi_config_wrapper config_wrapper) { + if (!config_wrapper.config.dbi_driver) { usage("Must specify a DBI driver"); } - if (((metric == METRIC_QUERY_RESULT) || (metric == METRIC_QUERY_TIME)) && (!np_dbi_query)) { + if (((config_wrapper.config.metric == METRIC_QUERY_RESULT) || (config_wrapper.config.metric == METRIC_QUERY_TIME)) && + (!config_wrapper.config.dbi_query)) { usage("Must specify a query to execute (metric == QUERY_RESULT)"); } - if ((metric != METRIC_CONN_TIME) && (metric != METRIC_SERVER_VERSION) && (metric != METRIC_QUERY_RESULT) && - (metric != METRIC_QUERY_TIME)) { + if ((config_wrapper.config.metric != METRIC_CONN_TIME) && (config_wrapper.config.metric != METRIC_SERVER_VERSION) && + (config_wrapper.config.metric != METRIC_QUERY_RESULT) && (config_wrapper.config.metric != METRIC_QUERY_TIME)) { usage("Invalid metric specified"); } - if (expect && (warning_range || critical_range || expect_re_str)) { + if (config_wrapper.config.expect && (config_wrapper.config.warning_range || config_wrapper.config.critical_range || config_wrapper.config.expect_re_str)) { usage("Do not mix -e and -w/-c/-r/-R"); } - if (expect_re_str && (warning_range || critical_range || expect)) { + if (config_wrapper.config.expect_re_str && (config_wrapper.config.warning_range || config_wrapper.config.critical_range || config_wrapper.config.expect)) { usage("Do not mix -r/-R and -w/-c/-e"); } - if (expect && (metric != METRIC_QUERY_RESULT)) { + if (config_wrapper.config.expect && (config_wrapper.config.metric != METRIC_QUERY_RESULT)) { usage("Option -e requires metric QUERY_RESULT"); } - if (expect_re_str && (metric != METRIC_QUERY_RESULT)) { + if (config_wrapper.config.expect_re_str && (config_wrapper.config.metric != METRIC_QUERY_RESULT)) { usage("Options -r/-R require metric QUERY_RESULT"); } - return OK; + config_wrapper.errorcode = OK; + return config_wrapper; } void print_help(void) { @@ -551,6 +531,8 @@ void print_help(void) { printf(" %s\n", _("DBI driver options")); printf(" %s\n", "-q, --query=STRING"); printf(" %s\n", _("query to execute")); + printf(" %s\n", "-H STRING"); + printf(" %s\n", _("target database host")); printf("\n"); printf(UT_WARN_CRIT_RANGE); @@ -625,13 +607,7 @@ void print_usage(void) { printf(" [-e ] [-r|-R ]\n"); } -#define CHECK_IGNORE_ERROR(s) \ - do { \ - if (metric != METRIC_QUERY_RESULT) \ - return (s); \ - } while (0) - -const char *get_field_str(dbi_conn conn, dbi_result res, unsigned short field_type) { +const char *get_field_str(dbi_conn conn, dbi_result res, unsigned short field_type, mp_dbi_metric metric, mp_dbi_type type) { const char *str; if (field_type != DBI_TYPE_STRING) { @@ -641,7 +617,9 @@ const char *get_field_str(dbi_conn conn, dbi_result res, unsigned short field_ty str = dbi_result_get_string_idx(res, 1); if ((!str) || (strcmp(str, "ERROR") == 0)) { - CHECK_IGNORE_ERROR(NULL); + if (metric != METRIC_QUERY_RESULT) { + return NULL; + } np_dbi_print_error(conn, "CRITICAL - failed to fetch string value"); return NULL; } @@ -652,7 +630,7 @@ const char *get_field_str(dbi_conn conn, dbi_result res, unsigned short field_ty return str; } -double get_field(dbi_conn conn, dbi_result res, unsigned short *field_type) { +double get_field(dbi_conn conn, dbi_result res, unsigned short *field_type, mp_dbi_metric metric, mp_dbi_type type) { double val = NAN; if (*field_type == DBI_TYPE_INTEGER) { @@ -663,16 +641,20 @@ double get_field(dbi_conn conn, dbi_result res, unsigned short *field_type) { const char *val_str; char *endptr = NULL; - val_str = get_field_str(conn, res, *field_type); + val_str = get_field_str(conn, res, *field_type, metric, type); if (!val_str) { - CHECK_IGNORE_ERROR(NAN); + if (metric != METRIC_QUERY_RESULT) { + return NAN; + } *field_type = DBI_TYPE_ERROR; return NAN; } val = strtod(val_str, &endptr); if (endptr == val_str) { - CHECK_IGNORE_ERROR(NAN); + if (metric != METRIC_QUERY_RESULT) { + return NAN; + } printf("CRITICAL - result value is not a numeric: %s\n", val_str); *field_type = DBI_TYPE_ERROR; return NAN; @@ -683,7 +665,9 @@ double get_field(dbi_conn conn, dbi_result res, unsigned short *field_type) { } } } else { - CHECK_IGNORE_ERROR(NAN); + if (metric != METRIC_QUERY_RESULT) { + return NAN; + } printf("CRITICAL - cannot parse value of type %s (%i)\n", (*field_type == DBI_TYPE_BINARY) ? "BINARY" : (*field_type == DBI_TYPE_DATETIME) ? "DATETIME" @@ -695,36 +679,46 @@ double get_field(dbi_conn conn, dbi_result res, unsigned short *field_type) { return val; } -double get_query_result(dbi_conn conn, dbi_result res, const char **res_val_str, double *res_val) { +mp_state_enum get_query_result(dbi_conn conn, dbi_result res, const char **res_val_str, double *res_val, mp_dbi_metric metric, mp_dbi_type type) { unsigned short field_type; double val = NAN; if (dbi_result_get_numrows(res) == DBI_ROW_ERROR) { - CHECK_IGNORE_ERROR(STATE_OK); + if (metric != METRIC_QUERY_RESULT) { + return STATE_OK; + } np_dbi_print_error(conn, "CRITICAL - failed to fetch rows"); return STATE_CRITICAL; } if (dbi_result_get_numrows(res) < 1) { - CHECK_IGNORE_ERROR(STATE_OK); + if (metric != METRIC_QUERY_RESULT) { + return STATE_OK; + } printf("WARNING - no rows returned\n"); return STATE_WARNING; } if (dbi_result_get_numfields(res) == DBI_FIELD_ERROR) { - CHECK_IGNORE_ERROR(STATE_OK); + if (metric != METRIC_QUERY_RESULT) { + return STATE_OK; + } np_dbi_print_error(conn, "CRITICAL - failed to fetch fields"); return STATE_CRITICAL; } if (dbi_result_get_numfields(res) < 1) { - CHECK_IGNORE_ERROR(STATE_OK); + if (metric != METRIC_QUERY_RESULT) { + return STATE_OK; + } printf("WARNING - no fields returned\n"); return STATE_WARNING; } if (dbi_result_first_row(res) != 1) { - CHECK_IGNORE_ERROR(STATE_OK); + if (metric != METRIC_QUERY_RESULT) { + return STATE_OK; + } np_dbi_print_error(conn, "CRITICAL - failed to fetch first row"); return STATE_CRITICAL; } @@ -733,16 +727,18 @@ double get_query_result(dbi_conn conn, dbi_result res, const char **res_val_str, if (field_type != DBI_TYPE_ERROR) { if (type == TYPE_STRING) { /* the value will be freed in dbi_result_free */ - *res_val_str = strdup(get_field_str(conn, res, field_type)); + *res_val_str = strdup(get_field_str(conn, res, field_type, metric, type)); } else { - val = get_field(conn, res, &field_type); + val = get_field(conn, res, &field_type, metric, type); } } *res_val = val; if (field_type == DBI_TYPE_ERROR) { - CHECK_IGNORE_ERROR(STATE_OK); + if (metric != METRIC_QUERY_RESULT) { + return STATE_OK; + } np_dbi_print_error(conn, "CRITICAL - failed to fetch data"); return STATE_CRITICAL; } @@ -751,14 +747,13 @@ double get_query_result(dbi_conn conn, dbi_result res, const char **res_val_str, return STATE_OK; } -#undef CHECK_IGNORE_ERROR - -int do_query(dbi_conn conn, const char **res_val_str, double *res_val, double *res_time) { +mp_state_enum do_query(dbi_conn conn, const char **res_val_str, double *res_val, double *res_time, mp_dbi_metric metric, mp_dbi_type type, + char *np_dbi_query) { dbi_result res; struct timeval timeval_start; struct timeval timeval_end; - int status = STATE_OK; + mp_state_enum status = STATE_OK; assert(np_dbi_query); @@ -774,7 +769,7 @@ int do_query(dbi_conn conn, const char **res_val_str, double *res_val, double *r return STATE_CRITICAL; } - status = get_query_result(conn, res, res_val_str, res_val); + status = get_query_result(conn, res, res_val_str, res_val, metric, type); gettimeofday(&timeval_end, NULL); *res_time = timediff(timeval_start, timeval_end); diff --git a/plugins/check_dbi.d/config.h b/plugins/check_dbi.d/config.h new file mode 100644 index 00000000..f6f0d7b3 --- /dev/null +++ b/plugins/check_dbi.d/config.h @@ -0,0 +1,63 @@ +#pragma once + +#include "../../config.h" +#include +#include "../../lib/monitoringplug.h" + +typedef enum { + METRIC_CONN_TIME, + METRIC_SERVER_VERSION, + METRIC_QUERY_RESULT, + METRIC_QUERY_TIME, +} mp_dbi_metric; + +typedef enum { + TYPE_NUMERIC, + TYPE_STRING, +} mp_dbi_type; + +typedef struct { + char *key; + char *value; +} driver_option_t; + +typedef struct { + char *dbi_driver; + char *host; + driver_option_t *dbi_options; + size_t dbi_options_num; + char *dbi_database; + char *dbi_query; + + char *expect; + char *expect_re_str; + int expect_re_cflags; + mp_dbi_metric metric; + mp_dbi_type type; + char *warning_range; + char *critical_range; + thresholds *dbi_thresholds; + +} check_dbi_config; + +check_dbi_config check_dbi_config_init() { + check_dbi_config tmp = { + .dbi_driver = NULL, + .host = NULL, + .dbi_options = NULL, + .dbi_options_num = 0, + .dbi_database = NULL, + .dbi_query = NULL, + + .expect = NULL, + .expect_re_str = NULL, + .expect_re_cflags = 0, + .metric = METRIC_QUERY_RESULT, + .type = TYPE_NUMERIC, + + .warning_range = NULL, + .critical_range = NULL, + .dbi_thresholds = NULL, + }; + return tmp; +} -- cgit v1.2.3-74-g34f1 From 2036d29b34891415097c7d31c8e16bc0135577ad Mon Sep 17 00:00:00 2001 From: Lorenz Kästle <12514511+RincewindsHat@users.noreply.github.com> Date: Fri, 7 Mar 2025 18:42:37 +0100 Subject: Make config constant --- plugins/check_dbi.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/check_dbi.c b/plugins/check_dbi.c index 1f4a7def..9efcd1cb 100644 --- a/plugins/check_dbi.c +++ b/plugins/check_dbi.c @@ -103,7 +103,7 @@ int main(int argc, char **argv) { usage4(_("Could not parse arguments")); } - check_dbi_config config = tmp.config; + const check_dbi_config config = tmp.config; /* Set signal handling and alarm */ if (signal(SIGALRM, timeout_alarm_handler) == SIG_ERR) { -- cgit v1.2.3-74-g34f1 From 6928d9e9ad0eb279ab513e95e802daa43d8409dc Mon Sep 17 00:00:00 2001 From: Lorenz Kästle <12514511+RincewindsHat@users.noreply.github.com> Date: Fri, 7 Mar 2025 19:23:46 +0100 Subject: More local variables, less implicit boolean --- plugins/check_game.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/plugins/check_game.c b/plugins/check_game.c index d078e4b5..fc1afb42 100644 --- a/plugins/check_game.c +++ b/plugins/check_game.c @@ -144,7 +144,6 @@ int main(int argc, char **argv) { #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'}, {"verbose", no_argument, 0, 'v'}, @@ -179,7 +178,8 @@ check_game_config_wrapper process_arguments(int argc, char **argv) { } } - while (1) { + int opt_index = 0; + while (true) { int option_index = getopt_long(argc, argv, "hVvt:H:P:G:g:p:m:", long_opts, &opt_index); if (option_index == -1 || option_index == EOF) { -- cgit v1.2.3-74-g34f1 From e3d2fccade397bbd6b318495192b4ca346becef0 Mon Sep 17 00:00:00 2001 From: Lorenz Kästle <12514511+RincewindsHat@users.noreply.github.com> Date: Fri, 7 Mar 2025 19:25:14 +0100 Subject: check_game: Correct usage to only display the modern option variant --- plugins/check_game.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/plugins/check_game.c b/plugins/check_game.c index fc1afb42..c0193b03 100644 --- a/plugins/check_game.c +++ b/plugins/check_game.c @@ -287,13 +287,13 @@ void print_help(void) { printf(UT_EXTRA_OPTS); printf(" -H, --hostname=ADDRESS\n" " Host name, IP Address, or unix socket (must be an absolute path)\n"); - printf(" %s\n", "-p"); - printf(" %s\n", _("Optional port of which to connect")); - printf(" %s\n", "gf"); + printf(" %s\n", "-P"); + printf(" %s\n", _("Optional port to connect to")); + printf(" %s\n", "-g"); printf(" %s\n", _("Field number in raw qstat output that contains game name")); - printf(" %s\n", "-mf"); + printf(" %s\n", "-m"); printf(" %s\n", _("Field number in raw qstat output that contains map name")); - printf(" %s\n", "-pf"); + printf(" %s\n", "-p"); printf(" %s\n", _("Field number in raw qstat output that contains ping time")); printf(UT_CONN_TIMEOUT, DEFAULT_SOCKET_TIMEOUT); -- cgit v1.2.3-74-g34f1 From ff8aa20d0e42ca20184f67ec035d157c70ae7605 Mon Sep 17 00:00:00 2001 From: Lorenz Kästle <12514511+RincewindsHat@users.noreply.github.com> Date: Fri, 7 Mar 2025 19:29:24 +0100 Subject: Just use eval instead of Try::Tiny in tests --- NPTest.pm | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/NPTest.pm b/NPTest.pm index 987d3b71..1c008589 100644 --- a/NPTest.pm +++ b/NPTest.pm @@ -17,8 +17,6 @@ use File::Basename; use JSON; -use Try::Tiny; - use IO::File; use Data::Dumper; @@ -621,9 +619,7 @@ sub testCmd { chomp $output; $object->output($output); - try { - $object->{'mp_test_result'} = decode_json($output); - }; + eval { $object->{'mp_test_result'} = decode_json($output) }; alarm(0); -- cgit v1.2.3-74-g34f1 From 665e2f91306fa9b38044a382e4b7571a0c8c0c5f Mon Sep 17 00:00:00 2001 From: Lorenz Kästle <12514511+RincewindsHat@users.noreply.github.com> Date: Sat, 22 Feb 2025 22:14:17 +0100 Subject: clang-format --- plugins/check_ssh.c | 38 +++++++++++++++++++++++++------------- 1 file changed, 25 insertions(+), 13 deletions(-) diff --git a/plugins/check_ssh.c b/plugins/check_ssh.c index 42a88cf9..a50ca530 100644 --- a/plugins/check_ssh.c +++ b/plugins/check_ssh.c @@ -64,8 +64,9 @@ int main(int argc, char **argv) { /* Parse extra opts if any */ argv = np_extra_opts(&argc, argv, progname); - if (process_arguments(argc, argv) == ERROR) + if (process_arguments(argc, argv) == ERROR) { usage4(_("Could not parse arguments")); + } /* initialize alarm signal handling */ signal(SIGALRM, socket_timeout_alarm_handler); @@ -95,20 +96,24 @@ int process_arguments(int argc, char **argv) { {"remote-protocol", required_argument, 0, 'P'}, {0, 0, 0, 0}}; - if (argc < 2) + if (argc < 2) { return ERROR; + } - for (int i = 1; i < argc; i++) - if (strcmp("-to", argv[i]) == 0) + for (int i = 1; i < argc; i++) { + if (strcmp("-to", argv[i]) == 0) { strcpy(argv[i], "-t"); + } + } int option_char; while (true) { int option = 0; option_char = getopt_long(argc, argv, "+Vhv46t:r:H:p:P:", longopts, &option); - if (option_char == -1 || option_char == EOF) + if (option_char == -1 || option_char == EOF) { break; + } switch (option_char) { case '?': /* help */ @@ -123,10 +128,11 @@ int process_arguments(int argc, char **argv) { verbose = true; break; case 't': /* timeout period */ - if (!is_integer(optarg)) + if (!is_integer(optarg)) { usage2(_("Timeout interval must be a positive integer"), optarg); - else + } else { socket_timeout = atoi(optarg); + } break; case '4': address_family = AF_INET; @@ -145,8 +151,9 @@ int process_arguments(int argc, char **argv) { remote_protocol = optarg; break; case 'H': /* host */ - if (!is_host(optarg)) + if (!is_host(optarg)) { usage2(_("Invalid hostname/address"), optarg); + } server_name = optarg; break; case 'p': /* port */ @@ -178,10 +185,12 @@ int process_arguments(int argc, char **argv) { } int validate_arguments(void) { - if (server_name == NULL) + if (server_name == NULL) { return ERROR; - if (port == -1) /* funky, but allows -p to override stray integer in args */ + } + if (port == -1) { /* funky, but allows -p to override stray integer in args */ port = SSH_DFL_PORT; + } return OK; } @@ -198,8 +207,9 @@ int ssh_connect(char *haddr, int hport, char *remote_version, char *remote_proto int socket; int result = my_tcp_connect(haddr, hport, &socket); - if (result != STATE_OK) + if (result != STATE_OK) { return result; + } char *output = (char *)calloc(BUFF_SZ + 1, sizeof(char)); char *buffer = NULL; @@ -259,8 +269,9 @@ int ssh_connect(char *haddr, int hport, char *remote_version, char *remote_proto * - RFC 4253:4.2 */ strip(version_control_string); - if (verbose) + if (verbose) { printf("%s\n", version_control_string); + } char *ssh_proto = version_control_string + 4; @@ -297,8 +308,9 @@ int ssh_connect(char *haddr, int hport, char *remote_version, char *remote_proto static char *rev_no = VERSION; xasprintf(&buffer, "SSH-%s-check_ssh_%s\r\n", ssh_proto, rev_no); send(socket, buffer, strlen(buffer), MSG_DONTWAIT); - if (verbose) + if (verbose) { printf("%s\n", buffer); + } if (remote_version && strcmp(remote_version, ssh_server)) { printf(_("SSH CRITICAL - %s (protocol %s) version mismatch, expected '%s'\n"), ssh_server, ssh_proto, remote_version); -- cgit v1.2.3-74-g34f1 From fb4f46f93da4ac50654fdcc2f26b2f37c73a9230 Mon Sep 17 00:00:00 2001 From: Lorenz Kästle <12514511+RincewindsHat@users.noreply.github.com> Date: Sat, 22 Feb 2025 22:39:10 +0100 Subject: Migrate check_users to new ouput infrastructure --- plugins/Makefile.am | 1 + plugins/check_users.c | 249 ++++++++++++++++++++--------------------- plugins/check_users.d/config.h | 19 ++++ plugins/check_users.d/users.c | 166 +++++++++++++++++++++++++++ plugins/check_users.d/users.h | 18 +++ 5 files changed, 323 insertions(+), 130 deletions(-) create mode 100644 plugins/check_users.d/config.h create mode 100644 plugins/check_users.d/users.c create mode 100644 plugins/check_users.d/users.h diff --git a/plugins/Makefile.am b/plugins/Makefile.am index d43c1971..e0069653 100644 --- a/plugins/Makefile.am +++ b/plugins/Makefile.am @@ -125,6 +125,7 @@ check_time_LDADD = $(NETLIBS) check_ntp_time_LDADD = $(NETLIBS) $(MATHLIBS) check_ups_LDADD = $(NETLIBS) check_users_LDADD = $(BASEOBJS) $(WTSAPI32LIBS) $(SYSTEMDLIBS) +check_users_SOURCES = check_users.c check_users.d/users.c check_by_ssh_LDADD = $(NETLIBS) check_ide_smart_LDADD = $(BASEOBJS) negate_LDADD = $(BASEOBJS) diff --git a/plugins/check_users.c b/plugins/check_users.c index f1e1c39d..6ec87d21 100644 --- a/plugins/check_users.c +++ b/plugins/check_users.c @@ -3,7 +3,7 @@ * Monitoring check_users plugin * * License: GPL - * Copyright (c) 2000-2024 Monitoring Plugins Development Team + * Copyright (c) 2000-2025 Monitoring Plugins Development Team * * Description: * @@ -30,12 +30,19 @@ * *****************************************************************************/ +#include "check_users.d/config.h" +#include "thresholds.h" const char *progname = "check_users"; -const char *copyright = "2000-2024"; +const char *copyright = "2000-2025"; const char *email = "devel@monitoring-plugins.org"; -#include "common.h" -#include "utils.h" +#include "check_users.d/users.h" +#include "output.h" +#include "perfdata.h" +#include "states.h" +#include "utils_base.h" +#include "./common.h" +#include "./utils.h" #if HAVE_WTSAPI32_H # include @@ -53,29 +60,16 @@ const char *email = "devel@monitoring-plugins.org"; # include #endif -#define possibly_set(a, b) ((a) == 0 ? (b) : 0) +typedef struct process_argument_wrapper { + int errorcode; + check_users_config config; +} process_argument_wrapper; -static int process_arguments(int, char **); -static void print_help(void); +process_argument_wrapper process_arguments(int /*argc*/, char ** /*argv*/); +void print_help(void); void print_usage(void); -static char *warning_range = NULL; -static char *critical_range = NULL; -static thresholds *thlds = NULL; - int main(int argc, char **argv) { - int users = -1; - int result = STATE_UNKNOWN; -#if HAVE_WTSAPI32_H - WTS_SESSION_INFO *wtsinfo; - DWORD wtscount; - DWORD index; -#elif HAVE_UTMPX_H - struct utmpx *putmpx; -#else - char input_buffer[MAX_INPUT_BUFFER]; -#endif - setlocale(LC_ALL, ""); bindtextdomain(PACKAGE, LOCALEDIR); textdomain(PACKAGE); @@ -83,121 +77,106 @@ int main(int argc, char **argv) { /* Parse extra opts if any */ argv = np_extra_opts(&argc, argv, progname); - if (process_arguments(argc, argv) == ERROR) - usage4(_("Could not parse arguments")); - - users = 0; - -#ifdef HAVE_LIBSYSTEMD - if (sd_booted() > 0) - users = sd_get_sessions(NULL); - else { -#endif -#if HAVE_WTSAPI32_H - if (!WTSEnumerateSessions(WTS_CURRENT_SERVER_HANDLE, 0, 1, &wtsinfo, &wtscount)) { - printf(_("Could not enumerate RD sessions: %d\n"), GetLastError()); - return STATE_UNKNOWN; - } - - for (index = 0; index < wtscount; index++) { - LPTSTR username; - DWORD size; - int len; - - if (!WTSQuerySessionInformation(WTS_CURRENT_SERVER_HANDLE, wtsinfo[index].SessionId, WTSUserName, &username, &size)) - continue; - - len = lstrlen(username); - - WTSFreeMemory(username); - - if (len == 0) - continue; - - if (wtsinfo[index].State == WTSActive || wtsinfo[index].State == WTSDisconnected) - users++; - } - - WTSFreeMemory(wtsinfo); -#elif HAVE_UTMPX_H - /* get currently logged users from utmpx */ - setutxent(); - - while ((putmpx = getutxent()) != NULL) - if (putmpx->ut_type == USER_PROCESS) - users++; - - endutxent(); -#else - /* run the command */ - child_process = spopen(WHO_COMMAND); - if (child_process == NULL) { - printf(_("Could not open pipe: %s\n"), WHO_COMMAND); - return STATE_UNKNOWN; - } - - child_stderr = fdopen(child_stderr_array[fileno(child_process)], "r"); - if (child_stderr == NULL) - printf(_("Could not open stderr for %s\n"), WHO_COMMAND); + process_argument_wrapper tmp = process_arguments(argc, argv); - while (fgets(input_buffer, MAX_INPUT_BUFFER - 1, child_process)) { - /* increment 'users' on all lines except total user count */ - if (input_buffer[0] != '#') { - users++; - continue; - } - - /* get total logged in users */ - if (sscanf(input_buffer, _("# users=%d"), &users) == 1) - break; + if (tmp.errorcode == ERROR) { + usage4(_("Could not parse arguments")); } - /* check STDERR */ - if (fgets(input_buffer, MAX_INPUT_BUFFER - 1, child_stderr)) - result = possibly_set(result, STATE_UNKNOWN); - (void)fclose(child_stderr); + check_users_config config = tmp.config; - /* close the pipe */ - if (spclose(child_process)) - result = possibly_set(result, STATE_UNKNOWN); -#endif -#ifdef HAVE_LIBSYSTEMD +#ifdef _WIN32 +# if HAVE_WTSAPI32_H + get_num_of_users_wrapper user_wrapper = get_num_of_users_windows(); +# else +# error Did not find WTSAPI32 +# endif // HAVE_WTSAPI32_H +#else +# ifdef HAVE_LIBSYSTEMD + get_num_of_users_wrapper user_wrapper = get_num_of_users_systemd(); +# elif HAVE_UTMPX_H + get_num_of_users_wrapper user_wrapper = get_num_of_users_utmp(); +# else // !HAVE_LIBSYSTEMD && !HAVE_UTMPX_H + get_num_of_users_wrapper user_wrapper = get_num_of_users_who_command(); +# endif // HAVE_LIBSYSTEMD +#endif // _WIN32 + + mp_check overall = mp_check_init(); + mp_subcheck sc_users = mp_subcheck_init(); + + if (user_wrapper.errorcode != 0) { + sc_users = mp_set_subcheck_state(sc_users, STATE_UNKNOWN); + sc_users.output = "Failed to retrieve number of users"; + mp_add_subcheck_to_check(&overall, sc_users); + mp_exit(overall); } -#endif - /* check the user count against warning and critical thresholds */ - result = get_status((double)users, thlds); - if (result == STATE_UNKNOWN) - printf("%s\n", _("Unable to read output")); - else { - printf(_("USERS %s - %d users currently logged in |%s\n"), state_text(result), users, - sperfdata_int("users", users, "", warning_range, critical_range, true, 0, false, 0)); + mp_perfdata users_pd = { + .label = "users", + .value = mp_create_pd_value(user_wrapper.users), + }; + + users_pd = mp_pd_set_thresholds(users_pd, config.thresholds); + mp_add_perfdata_to_subcheck(&sc_users, users_pd); + + int tmp_status = mp_get_pd_status(users_pd); + sc_users = mp_set_subcheck_state(sc_users, tmp_status); + + switch (tmp_status) { + case STATE_WARNING: + xasprintf(&sc_users.output, "%d users currently logged in. This violates the warning threshold", user_wrapper.users); + break; + case STATE_CRITICAL: + xasprintf(&sc_users.output, "%d users currently logged in. This violates the critical threshold", user_wrapper.users); + break; + default: + xasprintf(&sc_users.output, "%d users currently logged in", user_wrapper.users); } - return result; + mp_add_subcheck_to_check(&overall, sc_users); + mp_exit(overall); } +#define output_format_index CHAR_MAX + 1 + /* process command-line arguments */ -int process_arguments(int argc, char **argv) { +process_argument_wrapper process_arguments(int argc, char **argv) { static struct option longopts[] = {{"critical", required_argument, 0, 'c'}, {"warning", required_argument, 0, 'w'}, {"version", no_argument, 0, 'V'}, {"help", no_argument, 0, 'h'}, + {"output-format", required_argument, 0, output_format_index}, {0, 0, 0, 0}}; - if (argc < 2) + if (argc < 2) { usage("\n"); + } + + char *warning_range = NULL; + char *critical_range = NULL; + check_users_config config = check_users_config_init(); - int option_char; while (true) { - int option = 0; - option_char = getopt_long(argc, argv, "+hVvc:w:", longopts, &option); + int counter = getopt_long(argc, argv, "+hVvc:w:", longopts, NULL); - if (option_char == -1 || option_char == EOF || option_char == 1) + if (counter == -1 || counter == EOF || counter == 1) { break; + } - switch (option_char) { + switch (counter) { + case output_format_index: { + parsed_output_format parser = mp_parse_output_format(optarg); + if (!parser.parsing_success) { + // TODO List all available formats here, maybe add anothoer usage function + printf("Invalid output format: %s\n", optarg); + exit(STATE_UNKNOWN); + } + + config.output_format_is_set = true; + config.output_format = parser.output_format; + break; + } case '?': /* print short usage statement if args not parsable */ usage5(); case 'h': /* help */ @@ -215,26 +194,35 @@ int process_arguments(int argc, char **argv) { } } - option_char = optind; - - if (warning_range == NULL && argc > option_char) - warning_range = argv[option_char++]; - - if (critical_range == NULL && argc > option_char) - critical_range = argv[option_char++]; - - /* this will abort in case of invalid ranges */ - set_thresholds(&thlds, warning_range, critical_range); - - if (!thlds->warning) { - usage4(_("Warning threshold must be a valid range expression")); + // TODO add proper verification for ranges here! + if (warning_range) { + mp_range_parsed tmp = mp_parse_range_string(warning_range); + if (tmp.error == MP_PARSING_SUCCES) { + config.thresholds.warning = tmp.range; + config.thresholds.warning_is_set = true; + } else { + printf("Failed to parse warning range: %s", warning_range); + exit(STATE_UNKNOWN); + } } - if (!thlds->critical) { - usage4(_("Critical threshold must be a valid range expression")); + if (critical_range) { + mp_range_parsed tmp = mp_parse_range_string(critical_range); + if (tmp.error == MP_PARSING_SUCCES) { + config.thresholds.critical = tmp.range; + config.thresholds.critical_is_set = true; + } else { + printf("Failed to parse critical range: %s", critical_range); + exit(STATE_UNKNOWN); + } } - return OK; + process_argument_wrapper result = { + .errorcode = OK, + .config = config, + }; + + return result; } void print_help(void) { @@ -257,6 +245,7 @@ void print_help(void) { printf(" %s\n", _("Set WARNING status if number of logged in users violates RANGE_EXPRESSION")); printf(" %s\n", "-c, --critical=RANGE_EXPRESSION"); printf(" %s\n", _("Set CRITICAL status if number of logged in users violates RANGE_EXPRESSION")); + printf(UT_OUTPUT_FORMAT); printf(UT_SUPPORT); } diff --git a/plugins/check_users.d/config.h b/plugins/check_users.d/config.h new file mode 100644 index 00000000..35b7b7f8 --- /dev/null +++ b/plugins/check_users.d/config.h @@ -0,0 +1,19 @@ +#pragma once + +#include "output.h" +#include "thresholds.h" +typedef struct check_users_config { + mp_thresholds thresholds; + + bool output_format_is_set; + mp_output_format output_format; +} check_users_config; + +check_users_config check_users_config_init() { + check_users_config tmp = { + .thresholds = mp_thresholds_init(), + + .output_format_is_set = false, + }; + return tmp; +} diff --git a/plugins/check_users.d/users.c b/plugins/check_users.d/users.c new file mode 100644 index 00000000..7969ae79 --- /dev/null +++ b/plugins/check_users.d/users.c @@ -0,0 +1,166 @@ +#include "./users.h" + +#ifdef _WIN32 +# ifdef HAVE_WTSAPI32_H +# include +# include +# undef ERROR +# define ERROR -1 + +get_num_of_users_wrapper get_num_of_users_windows() { + WTS_SESSION_INFO *wtsinfo; + DWORD wtscount; + + get_num_of_users_wrapper result = {}; + + if (!WTSEnumerateSessions(WTS_CURRENT_SERVER_HANDLE, 0, 1, &wtsinfo, &wtscount)) { + // printf(_("Could not enumerate RD sessions: %d\n"), GetLastError()); + result.error = WINDOWS_COULD_NOT_ENUMERATE_SESSIONS; + return result; + } + + for (DWORD index = 0; index < wtscount; index++) { + LPTSTR username; + DWORD size; + + if (!WTSQuerySessionInformation(WTS_CURRENT_SERVER_HANDLE, wtsinfo[index].SessionId, WTSUserName, &username, &size)) { + continue; + } + + int len = lstrlen(username); + + WTSFreeMemory(username); + + if (len == 0) { + continue; + } + + if (wtsinfo[index].State == WTSActive || wtsinfo[index].State == WTSDisconnected) { + result.users++; + } + } + + WTSFreeMemory(wtsinfo); + return result; +} +# else // HAVE_WTSAPI32_H +# error On windows but without the WTSAPI32 lib +# endif // HAVE_WTSAPI32_H + +#else // _WIN32 + +# include "../../config.h" + +# ifdef HAVE_LIBSYSTEMD +# include +# include + +get_num_of_users_wrapper get_num_of_users_systemd() { + get_num_of_users_wrapper result = {}; + + // Test whether we booted with systemd + if (sd_booted() > 0) { + int users = sd_get_sessions(NULL); + if (users >= 0) { + // Success + result.users = users; + return result; + } + + // Failure! return the error code + result.errorcode = users; + return result; + } + + // Looks like we are not running systemd, + // return with error here + result.errorcode = NO_SYSTEMD_ERROR; + return result; +} +# endif + +# ifdef HAVE_UTMPX_H +# include + +get_num_of_users_wrapper get_num_of_users_utmp() { + int users = 0; + + /* get currently logged users from utmpx */ + setutxent(); + + struct utmpx *putmpx; + while ((putmpx = getutxent()) != NULL) { + if (putmpx->ut_type == USER_PROCESS) { + users++; + } + } + + endutxent(); + + get_num_of_users_wrapper result = { + .errorcode = 0, + .users = users, + }; + + return result; +} +# endif + +# ifndef HAVE_WTSAPI32_H +# ifndef HAVE_LIBSYSTEMD +# ifndef HAVE_UTMPX_H +// Fall back option here for the others (probably still not on windows) + +# include "../popen.h" +# include "../common.h" +# include "../utils.h" + +get_num_of_users_wrapper get_num_of_users_who_command() { + /* run the command */ + child_process = spopen(WHO_COMMAND); + if (child_process == NULL) { + // printf(_("Could not open pipe: %s\n"), WHO_COMMAND); + get_num_of_users_wrapper result = { + .errorcode = COULD_NOT_OPEN_PIPE, + }; + return result; + } + + child_stderr = fdopen(child_stderr_array[fileno(child_process)], "r"); + if (child_stderr == NULL) { + // printf(_("Could not open stderr for %s\n"), WHO_COMMAND); + // TODO this error should probably be reported + } + + get_num_of_users_wrapper result = {}; + char input_buffer[MAX_INPUT_BUFFER]; + while (fgets(input_buffer, MAX_INPUT_BUFFER - 1, child_process)) { + /* increment 'users' on all lines except total user count */ + if (input_buffer[0] != '#') { + result.users++; + continue; + } + + /* get total logged in users */ + if (sscanf(input_buffer, _("# users=%d"), &result.users) == 1) { + break; + } + } + + /* check STDERR */ + if (fgets(input_buffer, MAX_INPUT_BUFFER - 1, child_stderr)) { + // if this fails, something broke and the result can not be relied upon or so is the theorie here + result.errorcode = STDERR_COULD_NOT_BE_READ; + } + (void)fclose(child_stderr); + + /* close the pipe */ + spclose(child_process); + + return result; +} + +# endif +# endif +# endif +#endif diff --git a/plugins/check_users.d/users.h b/plugins/check_users.d/users.h new file mode 100644 index 00000000..aacba775 --- /dev/null +++ b/plugins/check_users.d/users.h @@ -0,0 +1,18 @@ +#pragma once + +typedef struct get_num_of_users_wrapper { + int errorcode; + int users; +} get_num_of_users_wrapper; + +enum { + NO_SYSTEMD_ERROR = 64, + WINDOWS_COULD_NOT_ENUMERATE_SESSIONS, + COULD_NOT_OPEN_PIPE, + STDERR_COULD_NOT_BE_READ, +}; + +get_num_of_users_wrapper get_num_of_users_systemd(); +get_num_of_users_wrapper get_num_of_users_utmp(); +get_num_of_users_wrapper get_num_of_users_windows(); +get_num_of_users_wrapper get_num_of_users_who_command(); -- cgit v1.2.3-74-g34f1 From c87bc7eee4b83571199ffd14b70bfca5418ec101 Mon Sep 17 00:00:00 2001 From: Lorenz Kästle <12514511+RincewindsHat@users.noreply.github.com> Date: Tue, 25 Feb 2025 10:14:29 +0100 Subject: check_ssh: centralize configuration in external header --- plugins/check_ssh.c | 62 +++++++++++++++++++++++++------------------- plugins/check_ssh.d/config.h | 21 +++++++++++++++ 2 files changed, 56 insertions(+), 27 deletions(-) create mode 100644 plugins/check_ssh.d/config.h diff --git a/plugins/check_ssh.c b/plugins/check_ssh.c index a50ca530..3745f799 100644 --- a/plugins/check_ssh.c +++ b/plugins/check_ssh.c @@ -35,6 +35,7 @@ const char *email = "devel@monitoring-plugins.org"; #include "./common.h" #include "./netutils.h" #include "utils.h" +#include "./check_ssh.d/config.h" #ifndef MSG_DONTWAIT # define MSG_DONTWAIT 0 @@ -43,14 +44,14 @@ const char *email = "devel@monitoring-plugins.org"; #define SSH_DFL_PORT 22 #define BUFF_SZ 256 -static int port = -1; -static char *server_name = NULL; -static char *remote_version = NULL; -static char *remote_protocol = NULL; static bool verbose = false; -static int process_arguments(int /*argc*/, char ** /*argv*/); -static int validate_arguments(void); +typedef struct process_arguments_wrapper { + int errorcode; + check_ssh_config config; +} process_arguments_wrapper; + +static process_arguments_wrapper process_arguments(int /*argc*/, char ** /*argv*/); static void print_help(void); void print_usage(void); @@ -64,17 +65,21 @@ int main(int argc, char **argv) { /* Parse extra opts if any */ argv = np_extra_opts(&argc, argv, progname); - if (process_arguments(argc, argv) == ERROR) { + process_arguments_wrapper tmp_config = process_arguments(argc, argv); + + if (tmp_config.errorcode == ERROR) { usage4(_("Could not parse arguments")); } + check_ssh_config config = tmp_config.config; + /* initialize alarm signal handling */ signal(SIGALRM, socket_timeout_alarm_handler); alarm(socket_timeout); /* ssh_connect exits if error is found */ - int result = ssh_connect(server_name, port, remote_version, remote_protocol); + int result = ssh_connect(config.server_name, config.port, config.remote_version, config.remote_protocol); alarm(0); @@ -82,7 +87,7 @@ int main(int argc, char **argv) { } /* process command-line arguments */ -int process_arguments(int argc, char **argv) { +process_arguments_wrapper process_arguments(int argc, char **argv) { static struct option longopts[] = {{"help", no_argument, 0, 'h'}, {"version", no_argument, 0, 'V'}, {"host", required_argument, 0, 'H'}, /* backward compatibility */ @@ -96,8 +101,14 @@ int process_arguments(int argc, char **argv) { {"remote-protocol", required_argument, 0, 'P'}, {0, 0, 0, 0}}; + process_arguments_wrapper result = { + .config = check_ssh_config_init(), + .errorcode = OK, + }; + if (argc < 2) { - return ERROR; + result.errorcode = ERROR; + return result; } for (int i = 1; i < argc; i++) { @@ -145,20 +156,20 @@ int process_arguments(int argc, char **argv) { #endif break; case 'r': /* remote version */ - remote_version = optarg; + result.config.remote_version = optarg; break; case 'P': /* remote version */ - remote_protocol = optarg; + result.config.remote_protocol = optarg; break; case 'H': /* host */ if (!is_host(optarg)) { usage2(_("Invalid hostname/address"), optarg); } - server_name = optarg; + result.config.server_name = optarg; break; case 'p': /* port */ if (is_intpos(optarg)) { - port = atoi(optarg); + result.config.port = atoi(optarg); } else { usage2(_("Port number must be a positive integer"), optarg); } @@ -166,32 +177,29 @@ int process_arguments(int argc, char **argv) { } option_char = optind; - if (server_name == NULL && option_char < argc) { + if (result.config.server_name == NULL && option_char < argc) { if (is_host(argv[option_char])) { - server_name = argv[option_char++]; + result.config.server_name = argv[option_char++]; } } - if (port == -1 && option_char < argc) { + if (result.config.port == -1 && option_char < argc) { if (is_intpos(argv[option_char])) { - port = atoi(argv[option_char++]); + result.config.port = atoi(argv[option_char++]); } else { print_usage(); exit(STATE_UNKNOWN); } } - return validate_arguments(); -} - -int validate_arguments(void) { - if (server_name == NULL) { - return ERROR; + if (result.config.server_name == NULL) { + result.errorcode = ERROR; + return result; } - if (port == -1) { /* funky, but allows -p to override stray integer in args */ - port = SSH_DFL_PORT; + if (result.config.port == -1) { /* funky, but allows -p to override stray integer in args */ + result.config.port = SSH_DFL_PORT; } - return OK; + return result; } /************************************************************************ diff --git a/plugins/check_ssh.d/config.h b/plugins/check_ssh.d/config.h new file mode 100644 index 00000000..05698d83 --- /dev/null +++ b/plugins/check_ssh.d/config.h @@ -0,0 +1,21 @@ +#pragma once + +#include + +typedef struct check_ssh_config { + int port; + char *server_name; + char *remote_version; + char *remote_protocol; +} check_ssh_config; + +check_ssh_config check_ssh_config_init(void) { + check_ssh_config tmp = { + .port = -1, + .server_name = NULL, + .remote_version = NULL, + .remote_protocol = NULL, + }; + + return tmp; +} -- cgit v1.2.3-74-g34f1 From ed06df7f34ad72439b2a0ebb0c0e527d2435050a Mon Sep 17 00:00:00 2001 From: Lorenz Kästle <12514511+RincewindsHat@users.noreply.github.com> Date: Tue, 25 Feb 2025 11:26:36 +0100 Subject: check_ssh: Migrate to new output infrastructure --- plugins/check_ssh.c | 99 ++++++++++++++++++++++++++++++++++---------- plugins/check_ssh.d/config.h | 6 +++ 2 files changed, 84 insertions(+), 21 deletions(-) diff --git a/plugins/check_ssh.c b/plugins/check_ssh.c index 3745f799..62c8b891 100644 --- a/plugins/check_ssh.c +++ b/plugins/check_ssh.c @@ -28,6 +28,9 @@ * *****************************************************************************/ +#include "output.h" +#include "perfdata.h" +#include "states.h" const char *progname = "check_ssh"; const char *copyright = "2000-2024"; const char *email = "devel@monitoring-plugins.org"; @@ -55,7 +58,7 @@ static process_arguments_wrapper process_arguments(int /*argc*/, char ** /*argv* static void print_help(void); void print_usage(void); -static int ssh_connect(char *haddr, int hport, char *remote_version, char *remote_protocol); +static int ssh_connect(mp_check *overall, char *haddr, int hport, char *remote_version, char *remote_protocol); int main(int argc, char **argv) { setlocale(LC_ALL, ""); @@ -78,14 +81,21 @@ int main(int argc, char **argv) { alarm(socket_timeout); + mp_check overall = mp_check_init(); + if (config.output_format_is_set) { + overall.format = config.output_format; + } + /* ssh_connect exits if error is found */ - int result = ssh_connect(config.server_name, config.port, config.remote_version, config.remote_protocol); + ssh_connect(&overall, config.server_name, config.port, config.remote_version, config.remote_protocol); alarm(0); - return (result); + mp_exit(overall); } +#define output_format_index CHAR_MAX + 1 + /* process command-line arguments */ process_arguments_wrapper process_arguments(int argc, char **argv) { static struct option longopts[] = {{"help", no_argument, 0, 'h'}, @@ -99,6 +109,7 @@ process_arguments_wrapper process_arguments(int argc, char **argv) { {"verbose", no_argument, 0, 'v'}, {"remote-version", required_argument, 0, 'r'}, {"remote-protocol", required_argument, 0, 'P'}, + {"output-format", required_argument, 0, output_format_index}, {0, 0, 0, 0}}; process_arguments_wrapper result = { @@ -173,6 +184,18 @@ process_arguments_wrapper process_arguments(int argc, char **argv) { } else { usage2(_("Port number must be a positive integer"), optarg); } + case output_format_index: { + parsed_output_format parser = mp_parse_output_format(optarg); + if (!parser.parsing_success) { + // TODO List all available formats here, maybe add anothoer usage function + printf("Invalid output format: %s\n", optarg); + exit(STATE_UNKNOWN); + } + + result.config.output_format_is_set = true; + result.config.output_format = parser.output_format; + break; + } } } @@ -208,7 +231,7 @@ process_arguments_wrapper process_arguments(int argc, char **argv) { * *-----------------------------------------------------------------------*/ -int ssh_connect(char *haddr, int hport, char *remote_version, char *remote_protocol) { +int ssh_connect(mp_check *overall, char *haddr, int hport, char *desired_remote_version, char *desired_remote_protocol) { struct timeval tv; gettimeofday(&tv, NULL); @@ -260,15 +283,25 @@ int ssh_connect(char *haddr, int hport, char *remote_version, char *remote_proto } } + mp_subcheck connection_sc = mp_subcheck_init(); if (recv_ret < 0) { - printf("SSH CRITICAL - %s", strerror(errno)); - exit(STATE_CRITICAL); + connection_sc = mp_set_subcheck_state(connection_sc, STATE_CRITICAL); + xasprintf(&connection_sc.output, "%s", "SSH CRITICAL - %s", strerror(errno)); + mp_add_subcheck_to_check(overall, connection_sc); + return OK; } if (version_control_string == NULL) { - printf("SSH CRITICAL - No version control string received"); - exit(STATE_CRITICAL); + connection_sc = mp_set_subcheck_state(connection_sc, STATE_CRITICAL); + xasprintf(&connection_sc.output, "%s", "SSH CRITICAL - No version control string received"); + mp_add_subcheck_to_check(overall, connection_sc); + return OK; } + + connection_sc = mp_set_subcheck_state(connection_sc, STATE_OK); + xasprintf(&connection_sc.output, "%s", "Initial connection succeded"); + mp_add_subcheck_to_check(overall, connection_sc); + /* * "When the connection has been established, both sides MUST send an * identification string. This identification string MUST be @@ -307,10 +340,19 @@ int ssh_connect(char *haddr, int hport, char *remote_version, char *remote_proto if (tmp) { ssh_server[tmp - ssh_server] = '\0'; } + + mp_subcheck protocol_validity_sc = mp_subcheck_init(); if (strlen(ssh_proto) == 0 || strlen(ssh_server) == 0) { - printf(_("SSH CRITICAL - Invalid protocol version control string %s\n"), version_control_string); - exit(STATE_CRITICAL); + protocol_validity_sc = mp_set_subcheck_state(protocol_validity_sc, STATE_CRITICAL); + xasprintf(&protocol_validity_sc.output, "Invalid protocol version control string %s", version_control_string); + mp_add_subcheck_to_check(overall, protocol_validity_sc); + return OK; } + + protocol_validity_sc = mp_set_subcheck_state(protocol_validity_sc, STATE_OK); + xasprintf(&protocol_validity_sc.output, "Valid protocol version control string %s", version_control_string); + mp_add_subcheck_to_check(overall, protocol_validity_sc); + ssh_proto[strspn(ssh_proto, "0123456789. ")] = 0; static char *rev_no = VERSION; @@ -320,24 +362,38 @@ int ssh_connect(char *haddr, int hport, char *remote_version, char *remote_proto printf("%s\n", buffer); } - if (remote_version && strcmp(remote_version, ssh_server)) { - printf(_("SSH CRITICAL - %s (protocol %s) version mismatch, expected '%s'\n"), ssh_server, ssh_proto, remote_version); + if (desired_remote_version && strcmp(desired_remote_version, ssh_server)) { + mp_subcheck remote_version_sc = mp_subcheck_init(); + remote_version_sc = mp_set_subcheck_state(remote_version_sc, STATE_CRITICAL); + xasprintf(&remote_version_sc.output, _("%s (protocol %s) version mismatch, expected '%s'"), ssh_server, ssh_proto, + desired_remote_version); close(socket); - exit(STATE_CRITICAL); + mp_add_subcheck_to_check(overall, remote_version_sc); + return OK; } double elapsed_time = (double)deltime(tv) / 1.0e6; - if (remote_protocol && strcmp(remote_protocol, ssh_proto)) { - printf(_("SSH CRITICAL - %s (protocol %s) protocol version mismatch, expected '%s' | %s\n"), ssh_server, ssh_proto, remote_protocol, - fperfdata("time", elapsed_time, "s", false, 0, false, 0, true, 0, true, (int)socket_timeout)); - close(socket); - exit(STATE_CRITICAL); + mp_perfdata time_pd = perfdata_init(); + time_pd.value = mp_create_pd_value(elapsed_time); + time_pd.label = "time"; + time_pd.max_present = true; + time_pd.max = mp_create_pd_value(socket_timeout); + + mp_subcheck protocol_version_sc = mp_subcheck_init(); + mp_add_perfdata_to_subcheck(&protocol_version_sc, time_pd); + + if (desired_remote_protocol && strcmp(desired_remote_protocol, ssh_proto)) { + protocol_version_sc = mp_set_subcheck_state(protocol_version_sc, STATE_CRITICAL); + xasprintf(&protocol_version_sc.output, _("%s (protocol %s) protocol version mismatch, expected '%s'"), ssh_server, ssh_proto, + desired_remote_protocol); + } else { + protocol_version_sc = mp_set_subcheck_state(protocol_version_sc, STATE_OK); + xasprintf(&protocol_version_sc.output, "SSH server verison: %s (protocol version: %s)", ssh_server, ssh_proto); } - printf(_("SSH OK - %s (protocol %s) | %s\n"), ssh_server, ssh_proto, - fperfdata("time", elapsed_time, "s", false, 0, false, 0, true, 0, true, (int)socket_timeout)); + mp_add_subcheck_to_check(overall, protocol_version_sc); close(socket); - exit(STATE_OK); + return OK; } void print_help(void) { @@ -369,6 +425,7 @@ void print_help(void) { printf(" %s\n", "-P, --remote-protocol=STRING"); printf(" %s\n", _("Alert if protocol doesn't match expected protocol version (ex: 2.0)")); + printf(UT_OUTPUT_FORMAT); printf(UT_VERBOSE); diff --git a/plugins/check_ssh.d/config.h b/plugins/check_ssh.d/config.h index 05698d83..d739c57c 100644 --- a/plugins/check_ssh.d/config.h +++ b/plugins/check_ssh.d/config.h @@ -1,12 +1,16 @@ #pragma once #include +#include "../../lib/monitoringplug.h" typedef struct check_ssh_config { int port; char *server_name; char *remote_version; char *remote_protocol; + + bool output_format_is_set; + mp_output_format output_format; } check_ssh_config; check_ssh_config check_ssh_config_init(void) { @@ -15,6 +19,8 @@ check_ssh_config check_ssh_config_init(void) { .server_name = NULL, .remote_version = NULL, .remote_protocol = NULL, + + .output_format_is_set = false, }; return tmp; -- cgit v1.2.3-74-g34f1 From 5ee9a5eadd7c9252fc4deb6cc502535d8e0e49d5 Mon Sep 17 00:00:00 2001 From: Lorenz Kästle <12514511+RincewindsHat@users.noreply.github.com> Date: Tue, 25 Feb 2025 11:28:29 +0100 Subject: check_ssh: modify usage string to avoid old call syntax --- plugins/check_ssh.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/check_ssh.c b/plugins/check_ssh.c index 62c8b891..0f1c0835 100644 --- a/plugins/check_ssh.c +++ b/plugins/check_ssh.c @@ -434,5 +434,5 @@ void print_help(void) { void print_usage(void) { printf("%s\n", _("Usage:")); - printf("%s [-4|-6] [-t ] [-r ] [-p ] \n", progname); + printf("%s [-4|-6] [-t ] [-r ] [-p ] --hostname \n", progname); } -- cgit v1.2.3-74-g34f1 From add5bfb1e4029e406f7f331407c9d0f28d6d789b Mon Sep 17 00:00:00 2001 From: Lorenz Kästle <12514511+RincewindsHat@users.noreply.github.com> Date: Tue, 25 Feb 2025 11:32:18 +0100 Subject: check_ssh: Move default SSH constant around a bit --- plugins/check_ssh.c | 7 ++----- plugins/check_ssh.d/config.h | 4 +++- 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/plugins/check_ssh.c b/plugins/check_ssh.c index 0f1c0835..b73cdf24 100644 --- a/plugins/check_ssh.c +++ b/plugins/check_ssh.c @@ -44,7 +44,6 @@ const char *email = "devel@monitoring-plugins.org"; # define MSG_DONTWAIT 0 #endif -#define SSH_DFL_PORT 22 #define BUFF_SZ 256 static bool verbose = false; @@ -219,9 +218,7 @@ process_arguments_wrapper process_arguments(int argc, char **argv) { result.errorcode = ERROR; return result; } - if (result.config.port == -1) { /* funky, but allows -p to override stray integer in args */ - result.config.port = SSH_DFL_PORT; - } + return result; } @@ -398,7 +395,7 @@ int ssh_connect(mp_check *overall, char *haddr, int hport, char *desired_remote_ void print_help(void) { char *myport; - xasprintf(&myport, "%d", SSH_DFL_PORT); + xasprintf(&myport, "%d", default_ssh_port); print_revision(progname, NP_VERSION); diff --git a/plugins/check_ssh.d/config.h b/plugins/check_ssh.d/config.h index d739c57c..c150fd30 100644 --- a/plugins/check_ssh.d/config.h +++ b/plugins/check_ssh.d/config.h @@ -3,6 +3,8 @@ #include #include "../../lib/monitoringplug.h" +const int default_ssh_port = 22; + typedef struct check_ssh_config { int port; char *server_name; @@ -15,7 +17,7 @@ typedef struct check_ssh_config { check_ssh_config check_ssh_config_init(void) { check_ssh_config tmp = { - .port = -1, + .port = default_ssh_port, .server_name = NULL, .remote_version = NULL, .remote_protocol = NULL, -- cgit v1.2.3-74-g34f1 From 9ea4dbc25352c7cb408e392e5ae9011b9b0ff3d6 Mon Sep 17 00:00:00 2001 From: Lorenz Kästle <12514511+RincewindsHat@users.noreply.github.com> Date: Tue, 25 Feb 2025 11:35:34 +0100 Subject: check_ssh: move only time relevant stuff in timeout area --- plugins/check_ssh.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/plugins/check_ssh.c b/plugins/check_ssh.c index b73cdf24..3e25910d 100644 --- a/plugins/check_ssh.c +++ b/plugins/check_ssh.c @@ -75,16 +75,15 @@ int main(int argc, char **argv) { check_ssh_config config = tmp_config.config; - /* initialize alarm signal handling */ - signal(SIGALRM, socket_timeout_alarm_handler); - - alarm(socket_timeout); - mp_check overall = mp_check_init(); if (config.output_format_is_set) { overall.format = config.output_format; } + /* initialize alarm signal handling */ + signal(SIGALRM, socket_timeout_alarm_handler); + alarm(socket_timeout); + /* ssh_connect exits if error is found */ ssh_connect(&overall, config.server_name, config.port, config.remote_version, config.remote_protocol); -- cgit v1.2.3-74-g34f1 From b48ec884be9ee0026c20575f06a799b2444e284b Mon Sep 17 00:00:00 2001 From: Lorenz Kästle <12514511+RincewindsHat@users.noreply.github.com> Date: Tue, 25 Feb 2025 11:36:54 +0100 Subject: check_ssh: Verify that timeout is a positive integer --- plugins/check_ssh.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/check_ssh.c b/plugins/check_ssh.c index 3e25910d..fe8681e2 100644 --- a/plugins/check_ssh.c +++ b/plugins/check_ssh.c @@ -148,7 +148,7 @@ process_arguments_wrapper process_arguments(int argc, char **argv) { verbose = true; break; case 't': /* timeout period */ - if (!is_integer(optarg)) { + if (!is_intpos(optarg)) { usage2(_("Timeout interval must be a positive integer"), optarg); } else { socket_timeout = atoi(optarg); -- cgit v1.2.3-74-g34f1 From ce3eff0908b33140c5a99ee21d1c10405cbe9030 Mon Sep 17 00:00:00 2001 From: Lorenz Kästle <12514511+RincewindsHat@users.noreply.github.com> Date: Tue, 25 Feb 2025 11:40:32 +0100 Subject: check_ssh: no more implicit conversion --- plugins/check_ssh.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/plugins/check_ssh.c b/plugins/check_ssh.c index fe8681e2..518950ec 100644 --- a/plugins/check_ssh.c +++ b/plugins/check_ssh.c @@ -151,7 +151,7 @@ process_arguments_wrapper process_arguments(int argc, char **argv) { if (!is_intpos(optarg)) { usage2(_("Timeout interval must be a positive integer"), optarg); } else { - socket_timeout = atoi(optarg); + socket_timeout = (unsigned int) atoi(optarg); } break; case '4': @@ -240,16 +240,16 @@ int ssh_connect(mp_check *overall, char *haddr, int hport, char *desired_remote_ char *output = (char *)calloc(BUFF_SZ + 1, sizeof(char)); char *buffer = NULL; - ssize_t recv_ret = 0; + size_t recv_ret = 0; char *version_control_string = NULL; - ssize_t byte_offset = 0; - while ((version_control_string == NULL) && (recv_ret = recv(socket, output + byte_offset, BUFF_SZ - byte_offset, 0) > 0)) { + size_t byte_offset = 0; + while ((version_control_string == NULL) && (recv_ret = recv(socket, output + byte_offset, (unsigned long)( BUFF_SZ - byte_offset), 0) > 0)) { if (strchr(output, '\n')) { /* we've got at least one full line, start parsing*/ byte_offset = 0; char *index = NULL; - int len = 0; + unsigned long len = 0; while ((index = strchr(output + byte_offset, '\n')) != NULL) { /*Partition the buffer so that this line is a separate string, * by replacing the newline with NUL*/ -- cgit v1.2.3-74-g34f1 From 46683da7b7a35a70dcb7dcb0e64160b78f84e965 Mon Sep 17 00:00:00 2001 From: Lorenz Kästle <12514511+RincewindsHat@users.noreply.github.com> Date: Tue, 25 Feb 2025 11:40:45 +0100 Subject: check_ssh: fix typo --- plugins/check_ssh.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/plugins/check_ssh.c b/plugins/check_ssh.c index 518950ec..ab4af352 100644 --- a/plugins/check_ssh.c +++ b/plugins/check_ssh.c @@ -295,7 +295,7 @@ int ssh_connect(mp_check *overall, char *haddr, int hport, char *desired_remote_ } connection_sc = mp_set_subcheck_state(connection_sc, STATE_OK); - xasprintf(&connection_sc.output, "%s", "Initial connection succeded"); + xasprintf(&connection_sc.output, "%s", "Initial connection succeeded"); mp_add_subcheck_to_check(overall, connection_sc); /* @@ -384,7 +384,7 @@ int ssh_connect(mp_check *overall, char *haddr, int hport, char *desired_remote_ desired_remote_protocol); } else { protocol_version_sc = mp_set_subcheck_state(protocol_version_sc, STATE_OK); - xasprintf(&protocol_version_sc.output, "SSH server verison: %s (protocol version: %s)", ssh_server, ssh_proto); + xasprintf(&protocol_version_sc.output, "SSH server version: %s (protocol version: %s)", ssh_server, ssh_proto); } mp_add_subcheck_to_check(overall, protocol_version_sc); -- cgit v1.2.3-74-g34f1 From 92fb0ec66218059589d0b6b0fed08735b2765d60 Mon Sep 17 00:00:00 2001 From: Lorenz Kästle <12514511+RincewindsHat@users.noreply.github.com> Date: Tue, 25 Feb 2025 13:02:30 +0100 Subject: check_ssh: add missing break statement --- plugins/check_ssh.c | 1 + 1 file changed, 1 insertion(+) diff --git a/plugins/check_ssh.c b/plugins/check_ssh.c index ab4af352..3d6a0710 100644 --- a/plugins/check_ssh.c +++ b/plugins/check_ssh.c @@ -182,6 +182,7 @@ process_arguments_wrapper process_arguments(int argc, char **argv) { } else { usage2(_("Port number must be a positive integer"), optarg); } + break; case output_format_index: { parsed_output_format parser = mp_parse_output_format(optarg); if (!parser.parsing_success) { -- cgit v1.2.3-74-g34f1 From 6428696f31289c2777a34f4c0f761aa038da6284 Mon Sep 17 00:00:00 2001 From: Lorenz Kästle <12514511+RincewindsHat@users.noreply.github.com> Date: Tue, 25 Feb 2025 13:03:00 +0100 Subject: check_ssh: exit properly if TCP connection fails --- plugins/check_ssh.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/plugins/check_ssh.c b/plugins/check_ssh.c index 3d6a0710..d06af3e7 100644 --- a/plugins/check_ssh.c +++ b/plugins/check_ssh.c @@ -235,7 +235,11 @@ int ssh_connect(mp_check *overall, char *haddr, int hport, char *desired_remote_ int socket; int result = my_tcp_connect(haddr, hport, &socket); + mp_subcheck connection_sc = mp_subcheck_init(); if (result != STATE_OK) { + connection_sc = mp_set_subcheck_state(connection_sc, STATE_CRITICAL); + xasprintf(&connection_sc.output, "Failed to establish TCP connection to Host %s and Port %d", haddr, hport); + mp_add_subcheck_to_check(overall, connection_sc); return result; } @@ -280,7 +284,6 @@ int ssh_connect(mp_check *overall, char *haddr, int hport, char *desired_remote_ } } - mp_subcheck connection_sc = mp_subcheck_init(); if (recv_ret < 0) { connection_sc = mp_set_subcheck_state(connection_sc, STATE_CRITICAL); xasprintf(&connection_sc.output, "%s", "SSH CRITICAL - %s", strerror(errno)); -- cgit v1.2.3-74-g34f1 From 2e9f9ebf7d477956c5cc1779c0fa9c89352d7ab7 Mon Sep 17 00:00:00 2001 From: Lorenz Kästle <12514511+RincewindsHat@users.noreply.github.com> Date: Tue, 25 Feb 2025 13:03:27 +0100 Subject: check_ssh.c: clang-format --- plugins/check_ssh.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/plugins/check_ssh.c b/plugins/check_ssh.c index d06af3e7..2ad7af66 100644 --- a/plugins/check_ssh.c +++ b/plugins/check_ssh.c @@ -44,7 +44,7 @@ const char *email = "devel@monitoring-plugins.org"; # define MSG_DONTWAIT 0 #endif -#define BUFF_SZ 256 +#define BUFF_SZ 256 static bool verbose = false; @@ -151,7 +151,7 @@ process_arguments_wrapper process_arguments(int argc, char **argv) { if (!is_intpos(optarg)) { usage2(_("Timeout interval must be a positive integer"), optarg); } else { - socket_timeout = (unsigned int) atoi(optarg); + socket_timeout = (unsigned int)atoi(optarg); } break; case '4': @@ -248,7 +248,8 @@ int ssh_connect(mp_check *overall, char *haddr, int hport, char *desired_remote_ size_t recv_ret = 0; char *version_control_string = NULL; size_t byte_offset = 0; - while ((version_control_string == NULL) && (recv_ret = recv(socket, output + byte_offset, (unsigned long)( BUFF_SZ - byte_offset), 0) > 0)) { + while ((version_control_string == NULL) && + (recv_ret = recv(socket, output + byte_offset, (unsigned long)(BUFF_SZ - byte_offset), 0) > 0)) { if (strchr(output, '\n')) { /* we've got at least one full line, start parsing*/ byte_offset = 0; -- cgit v1.2.3-74-g34f1 From 1ba8110da71abdccc9ee7f35cd0abefe78b8555b Mon Sep 17 00:00:00 2001 From: Lorenz Kästle <12514511+RincewindsHat@users.noreply.github.com> Date: Tue, 25 Feb 2025 13:04:04 +0100 Subject: check_ssh: adapt tests --- plugins/t/check_ssh.t | 114 ++++++++++++++++++++++++++++++++++++-------------- 1 file changed, 83 insertions(+), 31 deletions(-) diff --git a/plugins/t/check_ssh.t b/plugins/t/check_ssh.t index 907d33a8..8a20782e 100644 --- a/plugins/t/check_ssh.t +++ b/plugins/t/check_ssh.t @@ -5,10 +5,10 @@ # use strict; +use warnings; use Test::More; use NPTest; - -my $res; +use JSON; # Required parameters my $ssh_host = getTestParameter("NP_SSH_HOST", @@ -23,30 +23,38 @@ my $hostname_invalid = getTestParameter("NP_HOSTNAME_INVALID", "An invalid (not known to DNS) hostname", "nosuchhost" ); + my $outputFormat = '--output-format mp-test-json'; + +plan tests => 24; -plan tests => 14 + 6; +my $output; +my $result; SKIP: { skip "SSH_HOST must be defined", 6 unless $ssh_host; + + my $result = NPTest->testCmd( - "./check_ssh -H $ssh_host" + "./check_ssh -H $ssh_host" ." ". $outputFormat ); cmp_ok($result->return_code, '==', 0, "Exit with return code 0 (OK)"); - like($result->output, '/^SSH OK - /', "Status text if command returned none (OK)"); + $output = decode_json($result->output); + is($output->{'state'}, "OK", "State was correct"); $result = NPTest->testCmd( - "./check_ssh -H $host_nonresponsive -t 2" + "./check_ssh -H $host_nonresponsive -t 2" ." ". $outputFormat ); - cmp_ok($result->return_code, '==', 2, "Exit with return code 0 (OK)"); - like($result->output, '/^CRITICAL - Socket timeout after 2 seconds/', "Status text if command returned none (OK)"); + cmp_ok($result->return_code, '==', 0, "Exit with return code 0 (OK)"); + $output = decode_json($result->output); + is($output->{'state'}, "CRITICAL", "State was correct"); $result = NPTest->testCmd( - "./check_ssh -H $hostname_invalid -t 2" + "./check_ssh -H $hostname_invalid -t 2" ." ". $outputFormat ); - cmp_ok($result->return_code, '==', 3, "Exit with return code 0 (OK)"); + cmp_ok($result->return_code, '==', 3, "Exit with return code 3 (UNKNOWN)"); like($result->output, '/^check_ssh: Invalid hostname/', "Status text if command returned none (OK)"); @@ -63,46 +71,80 @@ SKIP: { # # where `comments` is optional, protoversion is the SSH protocol version and # softwareversion is an arbitrary string representing the server software version + + my $found_version = 0; + open(NC, "echo 'SSH-2.0-nagiosplug.ssh.0.1' | nc ${nc_flags}|"); sleep 0.1; - $res = NPTest->testCmd( "./check_ssh -H localhost -p 5003" ); - cmp_ok( $res->return_code, '==', 0, "Got SSH protocol version control string"); - like( $res->output, '/^SSH OK - nagiosplug.ssh.0.1 \(protocol 2.0\)/', "Output OK"); + $result = NPTest->testCmd( "./check_ssh -H localhost -p 5003" ." ". $outputFormat); + cmp_ok($result->return_code, '==', 0, "Exit with return code 0 (OK)"); + $output = decode_json($result->output); + is($output->{'state'}, "OK", "State was correct"); + + # looking for the version + for my $subcheck (@{$output->{'checks'}}) { + if ($subcheck->{'output'} =~ /.*nagiosplug.ssh.0.1 \(protocol version: 2.0\).*/ ){ + $found_version = 1; + } + } + cmp_ok($found_version, '==', 1, "Output OK"); close NC; open(NC, "echo 'SSH-2.0-3.2.9.1' | nc ${nc_flags}|"); sleep 0.1; - $res = NPTest->testCmd( "./check_ssh -H localhost -p 5003" ); - cmp_ok( $res->return_code, "==", 0, "Got SSH protocol version control string with non-alpha softwareversion string"); - like( $res->output, '/^SSH OK - 3.2.9.1 \(protocol 2.0\)/', "Output OK for non-alpha softwareversion string"); + $result = NPTest->testCmd( "./check_ssh -H localhost -p 5003" ." ". $outputFormat); + cmp_ok($result->return_code, '==', 0, "Exit with return code 0 (OK)"); + $output = decode_json($result->output); + is($output->{'state'}, "OK", "State was correct"); + + $found_version = 0; + for my $subcheck (@{$output->{'checks'}}) { + if ($subcheck->{'output'} =~ /3.2.9.1 \(protocol version: 2.0\)/ ){ + $found_version = 1; + } + } + cmp_ok($found_version, '==', 1, "Output OK"); close NC; open(NC, "echo 'SSH-2.0-nagiosplug.ssh.0.1 this is a comment' | nc ${nc_flags} |"); sleep 0.1; - $res = NPTest->testCmd( "./check_ssh -H localhost -p 5003 -r nagiosplug.ssh.0.1" ); - cmp_ok( $res->return_code, '==', 0, "Got SSH protocol version control string, and parsed comment appropriately"); - like( $res->output, '/^SSH OK - nagiosplug.ssh.0.1 \(protocol 2.0\)/', "Output OK"); + $result = NPTest->testCmd( "./check_ssh -H localhost -p 5003 -r nagiosplug.ssh.0.1" ." ". $outputFormat); + cmp_ok($result->return_code, '==', 0, "Exit with return code 0 (OK)"); + $output = decode_json($result->output); + is($output->{'state'}, "OK", "State was correct"); + + # looking for the version + $found_version = 0; + for my $subcheck (@{$output->{'checks'}}) { + if ($subcheck->{'output'} =~ /nagiosplug.ssh.0.1 \(protocol version: 2.0\)/ ){ + $found_version = 1; + } + } + cmp_ok($found_version, '==', 1, "Output OK"); close NC; open(NC, "echo 'SSH-' | nc ${nc_flags}|"); sleep 0.1; - $res = NPTest->testCmd( "./check_ssh -H localhost -p 5003" ); - cmp_ok( $res->return_code, '==', 2, "Got invalid SSH protocol version control string"); - like( $res->output, '/^SSH CRITICAL/', "Output OK"); + $result = NPTest->testCmd( "./check_ssh -H localhost -p 5003" ." ". $outputFormat); + cmp_ok($result->return_code, '==', 0, "Exit with return code 0 (OK)"); + $output = decode_json($result->output); + is($output->{'state'}, "CRITICAL", "Got invalid SSH protocol version control string"); close NC; open(NC, "echo '' | nc ${nc_flags}|"); sleep 0.1; - $res = NPTest->testCmd( "./check_ssh -H localhost -p 5003" ); - cmp_ok( $res->return_code, '==', 2, "No version control string received"); - like( $res->output, '/^SSH CRITICAL - No version control string received/', "Output OK"); + $result = NPTest->testCmd( "./check_ssh -H localhost -p 5003" ." ". $outputFormat); + cmp_ok($result->return_code, '==', 0, "Exit with return code 0 (OK)"); + $output = decode_json($result->output); + is($output->{'state'}, "CRITICAL", "No version control string received"); close NC; open(NC, "echo 'Not a version control string' | nc ${nc_flags}|"); sleep 0.1; - $res = NPTest->testCmd( "./check_ssh -H localhost -p 5003" ); - cmp_ok( $res->return_code, '==', 2, "No version control string received"); - like( $res->output, '/^SSH CRITICAL - No version control string received/', "Output OK"); + $result = NPTest->testCmd( "./check_ssh -H localhost -p 5003" ." ". $outputFormat); + cmp_ok($result->return_code, '==', 0, "Exit with return code 0 (OK)"); + $output = decode_json($result->output); + is($output->{'state'}, "CRITICAL", "No version control string received"); close NC; @@ -116,8 +158,18 @@ SKIP: { echo 'Some\nPrepended\nData\nLines\n'; sleep 0.2; echo 'SSH-2.0-nagiosplug.ssh.0.2';} | nc ${nc_flags}|"); sleep 0.1; - $res = NPTest->testCmd( "./check_ssh -H localhost -p 5003" ); - cmp_ok( $res->return_code, '==', 0, "Got delayed SSH protocol version control string"); - like( $res->output, '/^SSH OK - nagiosplug.ssh.0.2 \(protocol 2.0\)/', "Output OK"); + $result = NPTest->testCmd( "./check_ssh -H localhost -p 5003" ." ". $outputFormat); + cmp_ok($result->return_code, '==', 0, "Exit with return code 0 (OK)"); + $output = decode_json($result->output); + is($output->{'state'}, "OK", "State was correct"); + + # looking for the version + $found_version = 0; + for my $subcheck (@{$output->{'checks'}}) { + if ($subcheck->{'output'} =~ /nagiosplug.ssh.0.2 \(protocol version: 2.0\)/ ){ + $found_version = 1; + } + } + cmp_ok($found_version, '==', 1, "Output OK"); close NC; } -- cgit v1.2.3-74-g34f1 From 53247ae748174ddb639bb5fd9a19c8a6ad121717 Mon Sep 17 00:00:00 2001 From: Lorenz Kästle <12514511+RincewindsHat@users.noreply.github.com> Date: Tue, 25 Feb 2025 13:04:43 +0100 Subject: netutils.c: clang-format + do NOT print here --- plugins/netutils.c | 79 ++++++++++++++++++++++++++++++++---------------------- 1 file changed, 47 insertions(+), 32 deletions(-) diff --git a/plugins/netutils.c b/plugins/netutils.c index ee81912a..f5df7f3d 100644 --- a/plugins/netutils.c +++ b/plugins/netutils.c @@ -43,10 +43,11 @@ int address_family = AF_INET; /* handles socket timeouts */ void socket_timeout_alarm_handler(int sig) { - if (sig == SIGALRM) + if (sig == SIGALRM) { printf(_("%s - Socket timeout after %d seconds\n"), state_text(socket_timeout_state), socket_timeout); - else + } else { printf(_("%s - Abnormal timeout after %d seconds\n"), state_text(socket_timeout_state), socket_timeout); + } exit(socket_timeout_state); } @@ -65,12 +66,13 @@ int process_tcp_request2(const char *server_address, int server_port, const char int recv_length = 0; result = np_net_connect(server_address, server_port, &sd, IPPROTO_TCP); - if (result != STATE_OK) + if (result != STATE_OK) { return STATE_CRITICAL; + } send_result = send(sd, send_buffer, strlen(send_buffer), 0); if (send_result < 0 || (size_t)send_result != strlen(send_buffer)) { - printf("%s\n", _("Send failed")); + // printf("%s\n", _("Send failed")); result = STATE_WARNING; } @@ -87,7 +89,7 @@ int process_tcp_request2(const char *server_address, int server_port, const char if (!FD_ISSET(sd, &readfds)) { /* it hasn't */ if (!recv_length) { strcpy(recv_buffer, ""); - printf("%s\n", _("No data was received from host!")); + // printf("%s\n", _("No data was received from host!")); result = STATE_WARNING; } else { /* this one failed, but previous ones worked */ recv_buffer[recv_length] = 0; @@ -130,8 +132,9 @@ int process_request(const char *server_address, int server_port, int proto, cons result = STATE_OK; result = np_net_connect(server_address, server_port, &sd, proto); - if (result != STATE_OK) + if (result != STATE_OK) { return STATE_CRITICAL; + } result = send_request(sd, proto, send_buffer, recv_buffer, recv_size); @@ -169,15 +172,16 @@ int np_net_connect(const char *host_name, int port, int *sd, int proto) { host_name++; len -= 2; } - if (len >= sizeof(host)) + if (len >= sizeof(host)) { return STATE_UNKNOWN; + } memcpy(host, host_name, len); host[len] = '\0'; snprintf(port_str, sizeof(port_str), "%d", port); result = getaddrinfo(host, port_str, &hints, &res); if (result != 0) { - printf("%s\n", gai_strerror(result)); + // printf("%s\n", gai_strerror(result)); return STATE_UNKNOWN; } @@ -187,7 +191,7 @@ int np_net_connect(const char *host_name, int port, int *sd, int proto) { *sd = socket(r->ai_family, socktype, r->ai_protocol); if (*sd < 0) { - printf("%s\n", _("Socket creation failed")); + // printf("%s\n", _("Socket creation failed")); freeaddrinfo(r); return STATE_UNKNOWN; } @@ -226,21 +230,23 @@ int np_net_connect(const char *host_name, int port, int *sd, int proto) { die(STATE_UNKNOWN, _("Socket creation failed")); } result = connect(*sd, (struct sockaddr *)&su, sizeof(su)); - if (result < 0 && errno == ECONNREFUSED) + if (result < 0 && errno == ECONNREFUSED) { was_refused = true; + } } - if (result == 0) + if (result == 0) { return STATE_OK; - else if (was_refused) { + } else if (was_refused) { switch (econn_refuse_state) { /* a user-defined expected outcome */ case STATE_OK: case STATE_WARNING: /* user wants WARN or OK on refusal, or... */ case STATE_CRITICAL: /* user did not set econn_refuse_state, or wanted critical */ - if (is_socket) - printf("connect to file socket %s: %s\n", host_name, strerror(errno)); - else - printf("connect to address %s and port %d: %s\n", host_name, port, strerror(errno)); + if (is_socket) { + // printf("connect to file socket %s: %s\n", host_name, strerror(errno)); + } else { + // printf("connect to address %s and port %d: %s\n", host_name, port, strerror(errno)); + } return STATE_CRITICAL; break; default: /* it's a logic error if we do not end up in STATE_(OK|WARNING|CRITICAL) */ @@ -248,10 +254,11 @@ int np_net_connect(const char *host_name, int port, int *sd, int proto) { break; } } else { - if (is_socket) - printf("connect to file socket %s: %s\n", host_name, strerror(errno)); - else - printf("connect to address %s and port %d: %s\n", host_name, port, strerror(errno)); + if (is_socket) { + // printf("connect to file socket %s: %s\n", host_name, strerror(errno)); + } else { + // printf("connect to address %s and port %d: %s\n", host_name, port, strerror(errno)); + } return STATE_CRITICAL; } } @@ -265,7 +272,7 @@ int send_request(int sd, int proto, const char *send_buffer, char *recv_buffer, send_result = send(sd, send_buffer, strlen(send_buffer), 0); if (send_result < 0 || (size_t)send_result != strlen(send_buffer)) { - printf("%s\n", _("Send failed")); + // printf("%s\n", _("Send failed")); result = STATE_WARNING; } @@ -280,7 +287,7 @@ int send_request(int sd, int proto, const char *send_buffer, char *recv_buffer, /* make sure some data has arrived */ if (!FD_ISSET(sd, &readfds)) { strcpy(recv_buffer, ""); - printf("%s\n", _("No data was received from host!")); + // printf("%s\n", _("No data was received from host!")); result = STATE_WARNING; } @@ -288,11 +295,13 @@ int send_request(int sd, int proto, const char *send_buffer, char *recv_buffer, recv_result = recv(sd, recv_buffer, (size_t)recv_size - 1, 0); if (recv_result == -1) { strcpy(recv_buffer, ""); - if (proto != IPPROTO_TCP) - printf("%s\n", _("Receive failed")); + if (proto != IPPROTO_TCP) { + // printf("%s\n", _("Receive failed")); + } result = STATE_WARNING; - } else + } else { recv_buffer[recv_result] = 0; + } /* die returned string */ recv_buffer[recv_size - 1] = 0; @@ -301,26 +310,30 @@ int send_request(int sd, int proto, const char *send_buffer, char *recv_buffer, } bool is_host(const char *address) { - if (is_addr(address) || is_hostname(address)) + if (is_addr(address) || is_hostname(address)) { return (true); + } return (false); } void host_or_die(const char *str) { - if (!str || (!is_addr(str) && !is_hostname(str))) + if (!str || (!is_addr(str) && !is_hostname(str))) { usage_va(_("Invalid hostname/address - %s"), str); + } } bool is_addr(const char *address) { #ifdef USE_IPV6 - if (address_family == AF_INET && is_inet_addr(address)) + if (address_family == AF_INET && is_inet_addr(address)) { return true; - else if (address_family == AF_INET6 && is_inet6_addr(address)) + } else if (address_family == AF_INET6 && is_inet6_addr(address)) { return true; + } #else - if (is_inet_addr(address)) + if (is_inet_addr(address)) { return (true); + } #endif return (false); @@ -335,11 +348,13 @@ int dns_lookup(const char *in, struct sockaddr_storage *ss, int family) { hints.ai_family = family; retval = getaddrinfo(in, NULL, &hints, &res); - if (retval != 0) + if (retval != 0) { return false; + } - if (ss != NULL) + if (ss != NULL) { memcpy(ss, res->ai_addr, res->ai_addrlen); + } freeaddrinfo(res); return true; } -- cgit v1.2.3-74-g34f1 From d35c43e95f9efed3ef89bee288b8ec8f65ad2014 Mon Sep 17 00:00:00 2001 From: Lorenz Kästle <12514511+RincewindsHat@users.noreply.github.com> Date: Tue, 25 Feb 2025 15:02:55 +0100 Subject: Revert "Migrate check_users to new ouput infrastructure" This reverts commit 10086edbf03fd807794bcfb3fff626da69a9fdb2. --- plugins/Makefile.am | 1 - plugins/check_users.c | 249 +++++++++++++++++++++-------------------- plugins/check_users.d/config.h | 19 ---- plugins/check_users.d/users.c | 166 --------------------------- plugins/check_users.d/users.h | 18 --- 5 files changed, 130 insertions(+), 323 deletions(-) delete mode 100644 plugins/check_users.d/config.h delete mode 100644 plugins/check_users.d/users.c delete mode 100644 plugins/check_users.d/users.h diff --git a/plugins/Makefile.am b/plugins/Makefile.am index e0069653..d43c1971 100644 --- a/plugins/Makefile.am +++ b/plugins/Makefile.am @@ -125,7 +125,6 @@ check_time_LDADD = $(NETLIBS) check_ntp_time_LDADD = $(NETLIBS) $(MATHLIBS) check_ups_LDADD = $(NETLIBS) check_users_LDADD = $(BASEOBJS) $(WTSAPI32LIBS) $(SYSTEMDLIBS) -check_users_SOURCES = check_users.c check_users.d/users.c check_by_ssh_LDADD = $(NETLIBS) check_ide_smart_LDADD = $(BASEOBJS) negate_LDADD = $(BASEOBJS) diff --git a/plugins/check_users.c b/plugins/check_users.c index 6ec87d21..f1e1c39d 100644 --- a/plugins/check_users.c +++ b/plugins/check_users.c @@ -3,7 +3,7 @@ * Monitoring check_users plugin * * License: GPL - * Copyright (c) 2000-2025 Monitoring Plugins Development Team + * Copyright (c) 2000-2024 Monitoring Plugins Development Team * * Description: * @@ -30,19 +30,12 @@ * *****************************************************************************/ -#include "check_users.d/config.h" -#include "thresholds.h" const char *progname = "check_users"; -const char *copyright = "2000-2025"; +const char *copyright = "2000-2024"; const char *email = "devel@monitoring-plugins.org"; -#include "check_users.d/users.h" -#include "output.h" -#include "perfdata.h" -#include "states.h" -#include "utils_base.h" -#include "./common.h" -#include "./utils.h" +#include "common.h" +#include "utils.h" #if HAVE_WTSAPI32_H # include @@ -60,16 +53,29 @@ const char *email = "devel@monitoring-plugins.org"; # include #endif -typedef struct process_argument_wrapper { - int errorcode; - check_users_config config; -} process_argument_wrapper; +#define possibly_set(a, b) ((a) == 0 ? (b) : 0) -process_argument_wrapper process_arguments(int /*argc*/, char ** /*argv*/); -void print_help(void); +static int process_arguments(int, char **); +static void print_help(void); void print_usage(void); +static char *warning_range = NULL; +static char *critical_range = NULL; +static thresholds *thlds = NULL; + int main(int argc, char **argv) { + int users = -1; + int result = STATE_UNKNOWN; +#if HAVE_WTSAPI32_H + WTS_SESSION_INFO *wtsinfo; + DWORD wtscount; + DWORD index; +#elif HAVE_UTMPX_H + struct utmpx *putmpx; +#else + char input_buffer[MAX_INPUT_BUFFER]; +#endif + setlocale(LC_ALL, ""); bindtextdomain(PACKAGE, LOCALEDIR); textdomain(PACKAGE); @@ -77,106 +83,121 @@ int main(int argc, char **argv) { /* Parse extra opts if any */ argv = np_extra_opts(&argc, argv, progname); - process_argument_wrapper tmp = process_arguments(argc, argv); - - if (tmp.errorcode == ERROR) { + if (process_arguments(argc, argv) == ERROR) usage4(_("Could not parse arguments")); - } - check_users_config config = tmp.config; + users = 0; + +#ifdef HAVE_LIBSYSTEMD + if (sd_booted() > 0) + users = sd_get_sessions(NULL); + else { +#endif +#if HAVE_WTSAPI32_H + if (!WTSEnumerateSessions(WTS_CURRENT_SERVER_HANDLE, 0, 1, &wtsinfo, &wtscount)) { + printf(_("Could not enumerate RD sessions: %d\n"), GetLastError()); + return STATE_UNKNOWN; + } + + for (index = 0; index < wtscount; index++) { + LPTSTR username; + DWORD size; + int len; -#ifdef _WIN32 -# if HAVE_WTSAPI32_H - get_num_of_users_wrapper user_wrapper = get_num_of_users_windows(); -# else -# error Did not find WTSAPI32 -# endif // HAVE_WTSAPI32_H + if (!WTSQuerySessionInformation(WTS_CURRENT_SERVER_HANDLE, wtsinfo[index].SessionId, WTSUserName, &username, &size)) + continue; + + len = lstrlen(username); + + WTSFreeMemory(username); + + if (len == 0) + continue; + + if (wtsinfo[index].State == WTSActive || wtsinfo[index].State == WTSDisconnected) + users++; + } + + WTSFreeMemory(wtsinfo); +#elif HAVE_UTMPX_H + /* get currently logged users from utmpx */ + setutxent(); + + while ((putmpx = getutxent()) != NULL) + if (putmpx->ut_type == USER_PROCESS) + users++; + + endutxent(); #else -# ifdef HAVE_LIBSYSTEMD - get_num_of_users_wrapper user_wrapper = get_num_of_users_systemd(); -# elif HAVE_UTMPX_H - get_num_of_users_wrapper user_wrapper = get_num_of_users_utmp(); -# else // !HAVE_LIBSYSTEMD && !HAVE_UTMPX_H - get_num_of_users_wrapper user_wrapper = get_num_of_users_who_command(); -# endif // HAVE_LIBSYSTEMD -#endif // _WIN32 - - mp_check overall = mp_check_init(); - mp_subcheck sc_users = mp_subcheck_init(); - - if (user_wrapper.errorcode != 0) { - sc_users = mp_set_subcheck_state(sc_users, STATE_UNKNOWN); - sc_users.output = "Failed to retrieve number of users"; - mp_add_subcheck_to_check(&overall, sc_users); - mp_exit(overall); + /* run the command */ + child_process = spopen(WHO_COMMAND); + if (child_process == NULL) { + printf(_("Could not open pipe: %s\n"), WHO_COMMAND); + return STATE_UNKNOWN; } + + child_stderr = fdopen(child_stderr_array[fileno(child_process)], "r"); + if (child_stderr == NULL) + printf(_("Could not open stderr for %s\n"), WHO_COMMAND); + + while (fgets(input_buffer, MAX_INPUT_BUFFER - 1, child_process)) { + /* increment 'users' on all lines except total user count */ + if (input_buffer[0] != '#') { + users++; + continue; + } + + /* get total logged in users */ + if (sscanf(input_buffer, _("# users=%d"), &users) == 1) + break; + } + + /* check STDERR */ + if (fgets(input_buffer, MAX_INPUT_BUFFER - 1, child_stderr)) + result = possibly_set(result, STATE_UNKNOWN); + (void)fclose(child_stderr); + + /* close the pipe */ + if (spclose(child_process)) + result = possibly_set(result, STATE_UNKNOWN); +#endif +#ifdef HAVE_LIBSYSTEMD + } +#endif + /* check the user count against warning and critical thresholds */ + result = get_status((double)users, thlds); - mp_perfdata users_pd = { - .label = "users", - .value = mp_create_pd_value(user_wrapper.users), - }; - - users_pd = mp_pd_set_thresholds(users_pd, config.thresholds); - mp_add_perfdata_to_subcheck(&sc_users, users_pd); - - int tmp_status = mp_get_pd_status(users_pd); - sc_users = mp_set_subcheck_state(sc_users, tmp_status); - - switch (tmp_status) { - case STATE_WARNING: - xasprintf(&sc_users.output, "%d users currently logged in. This violates the warning threshold", user_wrapper.users); - break; - case STATE_CRITICAL: - xasprintf(&sc_users.output, "%d users currently logged in. This violates the critical threshold", user_wrapper.users); - break; - default: - xasprintf(&sc_users.output, "%d users currently logged in", user_wrapper.users); + if (result == STATE_UNKNOWN) + printf("%s\n", _("Unable to read output")); + else { + printf(_("USERS %s - %d users currently logged in |%s\n"), state_text(result), users, + sperfdata_int("users", users, "", warning_range, critical_range, true, 0, false, 0)); } - mp_add_subcheck_to_check(&overall, sc_users); - mp_exit(overall); + return result; } -#define output_format_index CHAR_MAX + 1 - /* process command-line arguments */ -process_argument_wrapper process_arguments(int argc, char **argv) { +int process_arguments(int argc, char **argv) { static struct option longopts[] = {{"critical", required_argument, 0, 'c'}, {"warning", required_argument, 0, 'w'}, {"version", no_argument, 0, 'V'}, {"help", no_argument, 0, 'h'}, - {"output-format", required_argument, 0, output_format_index}, {0, 0, 0, 0}}; - if (argc < 2) { + if (argc < 2) usage("\n"); - } - - char *warning_range = NULL; - char *critical_range = NULL; - check_users_config config = check_users_config_init(); + int option_char; while (true) { - int counter = getopt_long(argc, argv, "+hVvc:w:", longopts, NULL); + int option = 0; + option_char = getopt_long(argc, argv, "+hVvc:w:", longopts, &option); - if (counter == -1 || counter == EOF || counter == 1) { + if (option_char == -1 || option_char == EOF || option_char == 1) break; - } - switch (counter) { - case output_format_index: { - parsed_output_format parser = mp_parse_output_format(optarg); - if (!parser.parsing_success) { - // TODO List all available formats here, maybe add anothoer usage function - printf("Invalid output format: %s\n", optarg); - exit(STATE_UNKNOWN); - } - - config.output_format_is_set = true; - config.output_format = parser.output_format; - break; - } + switch (option_char) { case '?': /* print short usage statement if args not parsable */ usage5(); case 'h': /* help */ @@ -194,35 +215,26 @@ process_argument_wrapper process_arguments(int argc, char **argv) { } } - // TODO add proper verification for ranges here! - if (warning_range) { - mp_range_parsed tmp = mp_parse_range_string(warning_range); - if (tmp.error == MP_PARSING_SUCCES) { - config.thresholds.warning = tmp.range; - config.thresholds.warning_is_set = true; - } else { - printf("Failed to parse warning range: %s", warning_range); - exit(STATE_UNKNOWN); - } - } + option_char = optind; - if (critical_range) { - mp_range_parsed tmp = mp_parse_range_string(critical_range); - if (tmp.error == MP_PARSING_SUCCES) { - config.thresholds.critical = tmp.range; - config.thresholds.critical_is_set = true; - } else { - printf("Failed to parse critical range: %s", critical_range); - exit(STATE_UNKNOWN); - } + if (warning_range == NULL && argc > option_char) + warning_range = argv[option_char++]; + + if (critical_range == NULL && argc > option_char) + critical_range = argv[option_char++]; + + /* this will abort in case of invalid ranges */ + set_thresholds(&thlds, warning_range, critical_range); + + if (!thlds->warning) { + usage4(_("Warning threshold must be a valid range expression")); } - process_argument_wrapper result = { - .errorcode = OK, - .config = config, - }; + if (!thlds->critical) { + usage4(_("Critical threshold must be a valid range expression")); + } - return result; + return OK; } void print_help(void) { @@ -245,7 +257,6 @@ void print_help(void) { printf(" %s\n", _("Set WARNING status if number of logged in users violates RANGE_EXPRESSION")); printf(" %s\n", "-c, --critical=RANGE_EXPRESSION"); printf(" %s\n", _("Set CRITICAL status if number of logged in users violates RANGE_EXPRESSION")); - printf(UT_OUTPUT_FORMAT); printf(UT_SUPPORT); } diff --git a/plugins/check_users.d/config.h b/plugins/check_users.d/config.h deleted file mode 100644 index 35b7b7f8..00000000 --- a/plugins/check_users.d/config.h +++ /dev/null @@ -1,19 +0,0 @@ -#pragma once - -#include "output.h" -#include "thresholds.h" -typedef struct check_users_config { - mp_thresholds thresholds; - - bool output_format_is_set; - mp_output_format output_format; -} check_users_config; - -check_users_config check_users_config_init() { - check_users_config tmp = { - .thresholds = mp_thresholds_init(), - - .output_format_is_set = false, - }; - return tmp; -} diff --git a/plugins/check_users.d/users.c b/plugins/check_users.d/users.c deleted file mode 100644 index 7969ae79..00000000 --- a/plugins/check_users.d/users.c +++ /dev/null @@ -1,166 +0,0 @@ -#include "./users.h" - -#ifdef _WIN32 -# ifdef HAVE_WTSAPI32_H -# include -# include -# undef ERROR -# define ERROR -1 - -get_num_of_users_wrapper get_num_of_users_windows() { - WTS_SESSION_INFO *wtsinfo; - DWORD wtscount; - - get_num_of_users_wrapper result = {}; - - if (!WTSEnumerateSessions(WTS_CURRENT_SERVER_HANDLE, 0, 1, &wtsinfo, &wtscount)) { - // printf(_("Could not enumerate RD sessions: %d\n"), GetLastError()); - result.error = WINDOWS_COULD_NOT_ENUMERATE_SESSIONS; - return result; - } - - for (DWORD index = 0; index < wtscount; index++) { - LPTSTR username; - DWORD size; - - if (!WTSQuerySessionInformation(WTS_CURRENT_SERVER_HANDLE, wtsinfo[index].SessionId, WTSUserName, &username, &size)) { - continue; - } - - int len = lstrlen(username); - - WTSFreeMemory(username); - - if (len == 0) { - continue; - } - - if (wtsinfo[index].State == WTSActive || wtsinfo[index].State == WTSDisconnected) { - result.users++; - } - } - - WTSFreeMemory(wtsinfo); - return result; -} -# else // HAVE_WTSAPI32_H -# error On windows but without the WTSAPI32 lib -# endif // HAVE_WTSAPI32_H - -#else // _WIN32 - -# include "../../config.h" - -# ifdef HAVE_LIBSYSTEMD -# include -# include - -get_num_of_users_wrapper get_num_of_users_systemd() { - get_num_of_users_wrapper result = {}; - - // Test whether we booted with systemd - if (sd_booted() > 0) { - int users = sd_get_sessions(NULL); - if (users >= 0) { - // Success - result.users = users; - return result; - } - - // Failure! return the error code - result.errorcode = users; - return result; - } - - // Looks like we are not running systemd, - // return with error here - result.errorcode = NO_SYSTEMD_ERROR; - return result; -} -# endif - -# ifdef HAVE_UTMPX_H -# include - -get_num_of_users_wrapper get_num_of_users_utmp() { - int users = 0; - - /* get currently logged users from utmpx */ - setutxent(); - - struct utmpx *putmpx; - while ((putmpx = getutxent()) != NULL) { - if (putmpx->ut_type == USER_PROCESS) { - users++; - } - } - - endutxent(); - - get_num_of_users_wrapper result = { - .errorcode = 0, - .users = users, - }; - - return result; -} -# endif - -# ifndef HAVE_WTSAPI32_H -# ifndef HAVE_LIBSYSTEMD -# ifndef HAVE_UTMPX_H -// Fall back option here for the others (probably still not on windows) - -# include "../popen.h" -# include "../common.h" -# include "../utils.h" - -get_num_of_users_wrapper get_num_of_users_who_command() { - /* run the command */ - child_process = spopen(WHO_COMMAND); - if (child_process == NULL) { - // printf(_("Could not open pipe: %s\n"), WHO_COMMAND); - get_num_of_users_wrapper result = { - .errorcode = COULD_NOT_OPEN_PIPE, - }; - return result; - } - - child_stderr = fdopen(child_stderr_array[fileno(child_process)], "r"); - if (child_stderr == NULL) { - // printf(_("Could not open stderr for %s\n"), WHO_COMMAND); - // TODO this error should probably be reported - } - - get_num_of_users_wrapper result = {}; - char input_buffer[MAX_INPUT_BUFFER]; - while (fgets(input_buffer, MAX_INPUT_BUFFER - 1, child_process)) { - /* increment 'users' on all lines except total user count */ - if (input_buffer[0] != '#') { - result.users++; - continue; - } - - /* get total logged in users */ - if (sscanf(input_buffer, _("# users=%d"), &result.users) == 1) { - break; - } - } - - /* check STDERR */ - if (fgets(input_buffer, MAX_INPUT_BUFFER - 1, child_stderr)) { - // if this fails, something broke and the result can not be relied upon or so is the theorie here - result.errorcode = STDERR_COULD_NOT_BE_READ; - } - (void)fclose(child_stderr); - - /* close the pipe */ - spclose(child_process); - - return result; -} - -# endif -# endif -# endif -#endif diff --git a/plugins/check_users.d/users.h b/plugins/check_users.d/users.h deleted file mode 100644 index aacba775..00000000 --- a/plugins/check_users.d/users.h +++ /dev/null @@ -1,18 +0,0 @@ -#pragma once - -typedef struct get_num_of_users_wrapper { - int errorcode; - int users; -} get_num_of_users_wrapper; - -enum { - NO_SYSTEMD_ERROR = 64, - WINDOWS_COULD_NOT_ENUMERATE_SESSIONS, - COULD_NOT_OPEN_PIPE, - STDERR_COULD_NOT_BE_READ, -}; - -get_num_of_users_wrapper get_num_of_users_systemd(); -get_num_of_users_wrapper get_num_of_users_utmp(); -get_num_of_users_wrapper get_num_of_users_windows(); -get_num_of_users_wrapper get_num_of_users_who_command(); -- cgit v1.2.3-74-g34f1 From 3cbd84ce754b1f7ce1ac8f9bc46059da62392ffe Mon Sep 17 00:00:00 2001 From: Lorenz Kästle <12514511+RincewindsHat@users.noreply.github.com> Date: Tue, 25 Feb 2025 16:35:51 +0100 Subject: Switch timeout handler to new output infrastructure --- plugins/netutils.c | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/plugins/netutils.c b/plugins/netutils.c index f5df7f3d..e2916c65 100644 --- a/plugins/netutils.c +++ b/plugins/netutils.c @@ -28,6 +28,8 @@ *****************************************************************************/ #include "common.h" +#include "output.h" +#include "states.h" #include "netutils.h" unsigned int socket_timeout = DEFAULT_SOCKET_TIMEOUT; @@ -43,13 +45,19 @@ int address_family = AF_INET; /* handles socket timeouts */ void socket_timeout_alarm_handler(int sig) { + mp_subcheck timeout_sc = mp_subcheck_init(); + timeout_sc = mp_set_subcheck_state(timeout_sc, socket_timeout_state); + if (sig == SIGALRM) { - printf(_("%s - Socket timeout after %d seconds\n"), state_text(socket_timeout_state), socket_timeout); + xasprintf(&timeout_sc.output, _("Socket timeout after %d seconds\n"), socket_timeout); } else { - printf(_("%s - Abnormal timeout after %d seconds\n"), state_text(socket_timeout_state), socket_timeout); + xasprintf(&timeout_sc.output, _("Abnormal timeout after %d seconds\n"), socket_timeout); } - exit(socket_timeout_state); + mp_check overall = mp_check_init(); + mp_add_subcheck_to_check(&overall, timeout_sc); + + mp_exit(overall); } /* connects to a host on a specified tcp port, sends a string, and gets a -- cgit v1.2.3-74-g34f1 From 72fd885f4ff423d5351e3387867f2415f1ffc2d8 Mon Sep 17 00:00:00 2001 From: Lorenz Kästle <12514511+RincewindsHat@users.noreply.github.com> Date: Tue, 25 Feb 2025 17:20:05 +0100 Subject: Transform output format to a global state This commit removes the format parameter from the mp_check object and creates a module global variable instead. This prevents thread safe usage of different mp_check objects which should likely not present a big problem for now. The reason for this change is effectively the very same, the format was lost if an exit was triggered by a signal handler (timeout in this example). --- lib/output.c | 12 +++++++++--- lib/output.h | 7 ++++++- plugins/check_ssh.c | 2 +- plugins/check_swap.c | 2 +- 4 files changed, 17 insertions(+), 6 deletions(-) diff --git a/lib/output.c b/lib/output.c index 17919afc..61fbf832 100644 --- a/lib/output.c +++ b/lib/output.c @@ -11,6 +11,9 @@ #include "perfdata.h" #include "states.h" +// == Global variables +static mp_output_format output_format = MP_FORMAT_DEFAULT; + // == Prototypes == static char *fmt_subcheck_output(mp_output_format output_format, mp_subcheck check, unsigned int indentation); static inline cJSON *json_serialize_subcheck(mp_subcheck subcheck); @@ -55,7 +58,6 @@ static inline char *fmt_subcheck_perfdata(mp_subcheck check) { */ mp_check mp_check_init(void) { mp_check check = {0}; - check.format = MP_FORMAT_DEFAULT; return check; } @@ -234,7 +236,7 @@ mp_state_enum mp_compute_check_state(const mp_check check) { char *mp_fmt_output(mp_check check) { char *result = NULL; - switch (check.format) { + switch (output_format) { case MP_FORMAT_MULTI_LINE: { if (check.summary == NULL) { check.summary = get_subcheck_summary(check); @@ -482,7 +484,7 @@ void mp_print_output(mp_check check) { puts(mp_fmt_output(check)); } */ void mp_exit(mp_check check) { mp_print_output(check); - if (check.format == MP_FORMAT_TEST_JSON) { + if (output_format == MP_FORMAT_TEST_JSON) { exit(0); } @@ -533,3 +535,7 @@ parsed_output_format mp_parse_output_format(char *format_string) { return result; } + +void mp_set_format(mp_output_format format) { output_format = format; } + +mp_output_format mp_get_format(void) { return output_format; } diff --git a/lib/output.h b/lib/output.h index ffc36f53..2bdfa074 100644 --- a/lib/output.h +++ b/lib/output.h @@ -35,6 +35,12 @@ typedef enum output_format { #define MP_FORMAT_DEFAULT MP_FORMAT_MULTI_LINE +/* + * Format related functions + */ + void mp_set_format(mp_output_format format); + mp_output_format mp_get_format(void); + /* * The main state object of a plugin. Exists only ONCE per plugin. * This is the "root" of a tree of singular checks. @@ -42,7 +48,6 @@ typedef enum output_format { * in the first layer of subchecks */ typedef struct { - mp_output_format format; // The output format char *summary; // Overall summary, if not set a summary will be automatically generated mp_subcheck_list *subchecks; } mp_check; diff --git a/plugins/check_ssh.c b/plugins/check_ssh.c index 2ad7af66..9d0d7cde 100644 --- a/plugins/check_ssh.c +++ b/plugins/check_ssh.c @@ -77,7 +77,7 @@ int main(int argc, char **argv) { mp_check overall = mp_check_init(); if (config.output_format_is_set) { - overall.format = config.output_format; + mp_set_format(config.output_format); } /* initialize alarm signal handling */ diff --git a/plugins/check_swap.c b/plugins/check_swap.c index 4d3b6099..cb95949a 100644 --- a/plugins/check_swap.c +++ b/plugins/check_swap.c @@ -93,7 +93,7 @@ int main(int argc, char **argv) { double percent_used; mp_check overall = mp_check_init(); if (config.output_format_is_set) { - overall.format = config.output_format; + mp_set_format(config.output_format); } mp_subcheck sc1 = mp_subcheck_init(); sc1 = mp_set_subcheck_default_state(sc1, STATE_OK); -- cgit v1.2.3-74-g34f1 From 230054f94d8b6f90076c3cc25c9c36e7b3747c74 Mon Sep 17 00:00:00 2001 From: Lorenz Kästle <12514511+RincewindsHat@users.noreply.github.com> Date: Sat, 8 Mar 2025 10:55:21 +0100 Subject: clang-format --- plugins/check_dns.c | 117 +++++++++++++++++++++++++++++++++------------------- 1 file changed, 75 insertions(+), 42 deletions(-) diff --git a/plugins/check_dns.c b/plugins/check_dns.c index e1e7c00e..b3d4a6e5 100644 --- a/plugins/check_dns.c +++ b/plugins/check_dns.c @@ -107,8 +107,9 @@ int main(int argc, char **argv) { alarm(timeout_interval); gettimeofday(&tv, NULL); - if (verbose) + if (verbose) { printf("%s\n", command_line); + } /* run the command */ if ((np_runcmd(command_line, &chld_out, &chld_err, 0)) != 0) { @@ -118,18 +119,20 @@ int main(int argc, char **argv) { /* scan stdout */ for (size_t i = 0; i < chld_out.lines; i++) { - if (addresses == NULL) + if (addresses == NULL) { addresses = malloc(sizeof(*addresses) * 10); - else if (!(n_addresses % 10)) + } else if (!(n_addresses % 10)) { addresses = realloc(addresses, sizeof(*addresses) * (n_addresses + 10)); + } - if (verbose) + if (verbose) { puts(chld_out.line[i]); + } if (strcasestr(chld_out.line[i], ".in-addr.arpa") || strcasestr(chld_out.line[i], ".ip6.arpa")) { - if ((temp_buffer = strstr(chld_out.line[i], "name = "))) + if ((temp_buffer = strstr(chld_out.line[i], "name = "))) { addresses[n_addresses++] = strdup(temp_buffer + 7); - else { + } else { msg = (char *)_("Warning plugin error"); result = STATE_WARNING; } @@ -156,15 +159,16 @@ int main(int argc, char **argv) { } /* the server is responding, we just got the host name... */ - if (strstr(chld_out.line[i], "Name:")) + if (strstr(chld_out.line[i], "Name:")) { parse_address = true; - else if (parse_address && (strstr(chld_out.line[i], "Address:") || strstr(chld_out.line[i], "Addresses:"))) { + } else if (parse_address && (strstr(chld_out.line[i], "Address:") || strstr(chld_out.line[i], "Addresses:"))) { temp_buffer = index(chld_out.line[i], ':'); temp_buffer++; /* Strip leading spaces */ - while (*temp_buffer == ' ') + while (*temp_buffer == ' ') { temp_buffer++; + } strip(temp_buffer); if (temp_buffer == NULL || strlen(temp_buffer) == 0) { @@ -179,24 +183,27 @@ int main(int argc, char **argv) { result = error_scan(chld_out.line[i], &is_nxdomain); if (result != STATE_OK) { msg = strchr(chld_out.line[i], ':'); - if (msg) + if (msg) { msg++; + } break; } } /* scan stderr */ for (size_t i = 0; i < chld_err.lines; i++) { - if (verbose) + if (verbose) { puts(chld_err.line[i]); + } if (error_scan(chld_err.line[i], &is_nxdomain) != STATE_OK) { result = max_state(result, error_scan(chld_err.line[i], &is_nxdomain)); msg = strchr(input_buffer, ':'); - if (msg) + if (msg) { msg++; - else + } else { msg = input_buffer; + } } } @@ -214,14 +221,16 @@ int main(int argc, char **argv) { } adrp = address = malloc(slen); for (i = 0; i < n_addresses; i++) { - if (i) + if (i) { *adrp++ = ','; + } strcpy(adrp, addresses[i]); adrp += strlen(addresses[i]); } *adrp = 0; - } else + } else { die(STATE_CRITICAL, _("DNS CRITICAL - '%s' msg parsing exited with no address\n"), NSLOOKUP_COMMAND); + } /* compare to expected address */ if (result == STATE_OK && expected_address_cnt > 0) { @@ -245,8 +254,9 @@ int main(int argc, char **argv) { xasprintf(&temp_buffer, "%s%s; ", temp_buffer, expected_address[i]); } /* check if expected_address must cover all in addresses and none may be missing */ - if (all_match && (expect_match != 0 || addr_match != 0)) + if (all_match && (expect_match != 0 || addr_match != 0)) { result = STATE_CRITICAL; + } if (result == STATE_CRITICAL) { /* Strip off last semicolon... */ temp_buffer[strlen(temp_buffer) - 2] = '\0'; @@ -259,8 +269,9 @@ int main(int argc, char **argv) { result = STATE_CRITICAL; xasprintf(&msg, _("Domain '%s' was found by the server: '%s'\n"), query_address, address); } else { - if (address != NULL) + if (address != NULL) { free(address); + } address = "NXDOMAIN"; } } @@ -292,14 +303,16 @@ int main(int argc, char **argv) { printf("|%s\n", fperfdata("time", elapsed_time, "s", false, 0, true, time_thresholds->critical->end, true, 0, false, 0)); } else if ((time_thresholds->warning != NULL) && (time_thresholds->critical == NULL)) { printf("|%s\n", fperfdata("time", elapsed_time, "s", true, time_thresholds->warning->end, false, 0, true, 0, false, 0)); - } else + } else { printf("|%s\n", fperfdata("time", elapsed_time, "s", false, 0, false, 0, true, 0, false, 0)); - } else if (result == STATE_WARNING) + } + } else if (result == STATE_WARNING) { printf(_("DNS WARNING - %s\n"), !strcmp(msg, "") ? _(" Probably a non-existent host/domain") : msg); - else if (result == STATE_CRITICAL) + } else if (result == STATE_CRITICAL) { printf(_("DNS CRITICAL - %s\n"), !strcmp(msg, "") ? _(" Probably a non-existent host/domain") : msg); - else + } else { printf(_("DNS UNKNOWN - %s\n"), !strcmp(msg, "") ? _(" Probably a non-existent host/domain") : msg); + } return result; } @@ -333,49 +346,59 @@ int error_scan(char *input_buffer, bool *is_nxdomain) { const int nxdomain = strstr(input_buffer, "Non-existent") || strstr(input_buffer, "** server can't find") || strstr(input_buffer, "** Can't find") || strstr(input_buffer, "NXDOMAIN"); - if (nxdomain) + if (nxdomain) { *is_nxdomain = true; + } /* the DNS lookup timed out */ if (strstr(input_buffer, _("Note: nslookup is deprecated and may be removed from future releases.")) || strstr(input_buffer, _("Consider using the `dig' or `host' programs instead. Run nslookup with")) || - strstr(input_buffer, _("the `-sil[ent]' option to prevent this message from appearing."))) + strstr(input_buffer, _("the `-sil[ent]' option to prevent this message from appearing."))) { return STATE_OK; + } /* DNS server is not running... */ - else if (strstr(input_buffer, "No response from server")) + else if (strstr(input_buffer, "No response from server")) { die(STATE_CRITICAL, _("No response from DNS %s\n"), dns_server); - else if (strstr(input_buffer, "no servers could be reached")) + } else if (strstr(input_buffer, "no servers could be reached")) { die(STATE_CRITICAL, _("No response from DNS %s\n"), dns_server); + } /* Host name is valid, but server doesn't have records... */ - else if (strstr(input_buffer, "No records")) + else if (strstr(input_buffer, "No records")) { die(STATE_CRITICAL, _("DNS %s has no records\n"), dns_server); + } /* Connection was refused */ else if (strstr(input_buffer, "Connection refused") || strstr(input_buffer, "Couldn't find server") || - strstr(input_buffer, "Refused") || (strstr(input_buffer, "** server can't find") && strstr(input_buffer, ": REFUSED"))) + strstr(input_buffer, "Refused") || (strstr(input_buffer, "** server can't find") && strstr(input_buffer, ": REFUSED"))) { die(STATE_CRITICAL, _("Connection to DNS %s was refused\n"), dns_server); + } /* Query refused (usually by an ACL in the namserver) */ - else if (strstr(input_buffer, "Query refused")) + else if (strstr(input_buffer, "Query refused")) { die(STATE_CRITICAL, _("Query was refused by DNS server at %s\n"), dns_server); + } /* No information (e.g. nameserver IP has two PTR records) */ - else if (strstr(input_buffer, "No information")) + else if (strstr(input_buffer, "No information")) { die(STATE_CRITICAL, _("No information returned by DNS server at %s\n"), dns_server); + } /* Network is unreachable */ - else if (strstr(input_buffer, "Network is unreachable")) + else if (strstr(input_buffer, "Network is unreachable")) { die(STATE_CRITICAL, _("Network is unreachable\n")); + } /* Internal server failure */ - else if (strstr(input_buffer, "Server failure")) + else if (strstr(input_buffer, "Server failure")) { die(STATE_CRITICAL, _("DNS failure for %s\n"), dns_server); + } /* Request error or the DNS lookup timed out */ - else if (strstr(input_buffer, "Format error") || strstr(input_buffer, "Timed out")) + else if (strstr(input_buffer, "Format error") || strstr(input_buffer, "Timed out")) { return STATE_WARNING; + } return STATE_OK; } @@ -402,18 +425,22 @@ int process_arguments(int argc, char **argv) { {"critical", required_argument, 0, 'c'}, {0, 0, 0, 0}}; - if (argc < 2) + if (argc < 2) { return ERROR; + } - for (c = 1; c < argc; c++) - if (strcmp("-to", argv[c]) == 0) + for (c = 1; c < argc; c++) { + if (strcmp("-to", argv[c]) == 0) { strcpy(argv[c], "-t"); + } + } while (1) { c = getopt_long(argc, argv, "hVvALnt:H:s:r:a:w:c:", long_opts, &opt_index); - if (c == -1 || c == EOF) + if (c == -1 || c == EOF) { break; + } switch (c) { case 'h': /* help */ @@ -429,28 +456,32 @@ int process_arguments(int argc, char **argv) { timeout_interval = atoi(optarg); break; case 'H': /* hostname */ - if (strlen(optarg) >= ADDRESS_LENGTH) + if (strlen(optarg) >= ADDRESS_LENGTH) { die(STATE_UNKNOWN, _("Input buffer overflow\n")); + } strcpy(query_address, optarg); break; case 's': /* server name */ /* TODO: this host_or_die check is probably unnecessary. * Better to confirm nslookup response matches */ host_or_die(optarg); - if (strlen(optarg) >= ADDRESS_LENGTH) + if (strlen(optarg) >= ADDRESS_LENGTH) { die(STATE_UNKNOWN, _("Input buffer overflow\n")); + } strcpy(dns_server, optarg); break; case 'r': /* reverse server name */ /* TODO: Is this host_or_die necessary? */ host_or_die(optarg); - if (strlen(optarg) >= ADDRESS_LENGTH) + if (strlen(optarg) >= ADDRESS_LENGTH) { die(STATE_UNKNOWN, _("Input buffer overflow\n")); + } strcpy(ptr_server, optarg); break; case 'a': /* expected address */ - if (strlen(optarg) >= ADDRESS_LENGTH) + if (strlen(optarg) >= ADDRESS_LENGTH) { die(STATE_UNKNOWN, _("Input buffer overflow\n")); + } if (strchr(optarg, ',') != NULL) { char *comma = strchr(optarg, ','); while (comma != NULL) { @@ -491,16 +522,18 @@ int process_arguments(int argc, char **argv) { c = optind; if (strlen(query_address) == 0 && c < argc) { - if (strlen(argv[c]) >= ADDRESS_LENGTH) + if (strlen(argv[c]) >= ADDRESS_LENGTH) { die(STATE_UNKNOWN, _("Input buffer overflow\n")); + } strcpy(query_address, argv[c++]); } if (strlen(dns_server) == 0 && c < argc) { /* TODO: See -s option */ host_or_die(argv[c]); - if (strlen(argv[c]) >= ADDRESS_LENGTH) + if (strlen(argv[c]) >= ADDRESS_LENGTH) { die(STATE_UNKNOWN, _("Input buffer overflow\n")); + } strcpy(dns_server, argv[c++]); } -- cgit v1.2.3-74-g34f1 From f63d249984e33030c7e4b3fd97ebe3f034abce3c Mon Sep 17 00:00:00 2001 From: Lorenz Kästle <12514511+RincewindsHat@users.noreply.github.com> Date: Sat, 8 Mar 2025 23:42:06 +0100 Subject: Adapt further test to changed output --- plugins/t/check_http.t | 2 +- plugins/t/check_jabber.t | 2 +- plugins/t/check_ldap.t | 2 +- plugins/t/check_ntp.t | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/plugins/t/check_http.t b/plugins/t/check_http.t index 6ab4a5b6..bb1fd27d 100644 --- a/plugins/t/check_http.t +++ b/plugins/t/check_http.t @@ -45,7 +45,7 @@ $res = NPTest->testCmd( "./$plugin $host_nonresponsive -wt 1 -ct 2 -t 3" ); cmp_ok( $res->return_code, '==', 2, "Webserver $host_nonresponsive not responding" ); -cmp_ok( $res->output, 'eq', "CRITICAL - Socket timeout after 3 seconds", "Output OK"); +like( $res->output, "/Socket timeout after/", "Output OK"); $res = NPTest->testCmd( "./$plugin $hostname_invalid -wt 1 -ct 2" diff --git a/plugins/t/check_jabber.t b/plugins/t/check_jabber.t index fcdae179..08cadcbd 100644 --- a/plugins/t/check_jabber.t +++ b/plugins/t/check_jabber.t @@ -17,7 +17,7 @@ my $hostname_invalid = getTestParameter("NP_HOSTNAME_INVALID", "An invalid (no my $jabberOK = '/JABBER OK\s-\s\d+\.\d+\ssecond response time on '.$host_tcp_jabber.' port 5222/'; -my $jabberUnresponsive = '/CRITICAL\s-\sSocket timeout after\s\d+\sseconds/'; +my $jabberUnresponsive = '/Socket timeout after\s\d+\sseconds/'; my $jabberInvalid = '/JABBER CRITICAL - Invalid hostname, address or socket:\s.+/'; diff --git a/plugins/t/check_ldap.t b/plugins/t/check_ldap.t index b8a4a766..fcba0393 100644 --- a/plugins/t/check_ldap.t +++ b/plugins/t/check_ldap.t @@ -24,7 +24,7 @@ SKIP: { $result = NPTest->testCmd("$command -H $host_nonresponsive -b ou=blah -t 2 -w 1 -c 1"); is( $result->return_code, 2, "$command -H $host_nonresponsive -b ou=blah -t 5 -w 2 -c 3" ); - is( $result->output, 'CRITICAL - Socket timeout after 2 seconds', "output ok" ); + like($result->output, '/Socket timeout after \d+ seconds/', "output ok" ); }; SKIP: { diff --git a/plugins/t/check_ntp.t b/plugins/t/check_ntp.t index b8fc8fdf..e7bb76e3 100644 --- a/plugins/t/check_ntp.t +++ b/plugins/t/check_ntp.t @@ -37,7 +37,7 @@ my $ntp_critmatch1 = '/^NTP\sCRITICAL:\sOffset\s-?[0-9]+(\.[0-9]+)?(e-[0-9]{2})? my $ntp_okmatch2 = '/^NTP\sOK:\sOffset\s-?[0-9]+(\.[0-9]+)?(e-[0-9]{2})?\ssecs,\sjitter=[0-9]+\.[0-9]+,\sstratum=[0-9]{1,2},\struechimers=[0-9]+/'; my $ntp_warnmatch2 = '/^NTP\sWARNING:\sOffset\s-?[0-9]+(\.[0-9]+)?(e-[0-9]{2})?\ssecs,\sjitter=[0-9]+\.[0-9]+,\sstratum=[0-9]{1,2}\s\(WARNING\),\struechimers=[0-9]+/'; my $ntp_critmatch2 = '/^NTP\sCRITICAL:\sOffset\s-?[0-9]+(\.[0-9]+)?(e-[0-9]{2})?\ssecs,\sjitter=[0-9]+\.[0-9]+\s\(CRITICAL\),\sstratum=[0-9]{1,2},\struechimers=[0-9]+/'; -my $ntp_noresponse = '/^(CRITICAL - Socket timeout after 3 seconds)|(NTP CRITICAL: No response from NTP server)$/'; +my $ntp_noresponse = '/^(.*Socket timeout after \d+ seconds.*)|.*No response from NTP server.*)$/'; my $ntp_nosuchhost = '/^check_ntp.*: Invalid hostname/address - ' . $hostname_invalid . '/'; -- cgit v1.2.3-74-g34f1 From fea6a662bd73496a29200023ed6a06bedefab415 Mon Sep 17 00:00:00 2001 From: Lorenz Kästle <12514511+RincewindsHat@users.noreply.github.com> Date: Sun, 9 Mar 2025 00:12:37 +0100 Subject: fix accidently remove parentheses in test --- plugins/t/check_ntp.t | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/t/check_ntp.t b/plugins/t/check_ntp.t index e7bb76e3..a355aa4a 100644 --- a/plugins/t/check_ntp.t +++ b/plugins/t/check_ntp.t @@ -37,7 +37,7 @@ my $ntp_critmatch1 = '/^NTP\sCRITICAL:\sOffset\s-?[0-9]+(\.[0-9]+)?(e-[0-9]{2})? my $ntp_okmatch2 = '/^NTP\sOK:\sOffset\s-?[0-9]+(\.[0-9]+)?(e-[0-9]{2})?\ssecs,\sjitter=[0-9]+\.[0-9]+,\sstratum=[0-9]{1,2},\struechimers=[0-9]+/'; my $ntp_warnmatch2 = '/^NTP\sWARNING:\sOffset\s-?[0-9]+(\.[0-9]+)?(e-[0-9]{2})?\ssecs,\sjitter=[0-9]+\.[0-9]+,\sstratum=[0-9]{1,2}\s\(WARNING\),\struechimers=[0-9]+/'; my $ntp_critmatch2 = '/^NTP\sCRITICAL:\sOffset\s-?[0-9]+(\.[0-9]+)?(e-[0-9]{2})?\ssecs,\sjitter=[0-9]+\.[0-9]+\s\(CRITICAL\),\sstratum=[0-9]{1,2},\struechimers=[0-9]+/'; -my $ntp_noresponse = '/^(.*Socket timeout after \d+ seconds.*)|.*No response from NTP server.*)$/'; +my $ntp_noresponse = '/^(.*Socket timeout after \d+ seconds.*)|(.*No response from NTP server.*)$/'; my $ntp_nosuchhost = '/^check_ntp.*: Invalid hostname/address - ' . $hostname_invalid . '/'; -- cgit v1.2.3-74-g34f1 From 809e79c7454c4b5771fe47c4da309dc82f917c25 Mon Sep 17 00:00:00 2001 From: Lorenz Kästle <12514511+RincewindsHat@users.noreply.github.com> Date: Sun, 9 Mar 2025 00:30:33 +0100 Subject: Remove failing test --- plugins/t/check_smtp.t | 1 - 1 file changed, 1 deletion(-) diff --git a/plugins/t/check_smtp.t b/plugins/t/check_smtp.t index 1a1ebe3e..11e22644 100644 --- a/plugins/t/check_smtp.t +++ b/plugins/t/check_smtp.t @@ -73,7 +73,6 @@ SKIP: { my $unused_port = 4465; $res = NPTest->testCmd( "./check_smtp -H $host_tcp_smtp_tls -p $unused_port --ssl" ); is ($res->return_code, 2, "Check rc of connecting to $host_tcp_smtp_tls with TLS on unused port $unused_port" ); - like ($res->output, qr/^connect to address $host_tcp_smtp_tls and port $unused_port: Connection refused/, "Check output of connecting to $host_tcp_smtp_tls with TLS on unused port $unused_port"); } $res = NPTest->testCmd( "./check_smtp $host_nonresponsive" ); -- cgit v1.2.3-74-g34f1 From 69819d8c952a623f092186f7b99b10d6cb894d9c Mon Sep 17 00:00:00 2001 From: Lorenz Kästle <12514511+RincewindsHat@users.noreply.github.com> Date: Sun, 9 Mar 2025 10:24:28 +0100 Subject: Adapt test regex to new output --- plugins/t/check_ntp.t | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/t/check_ntp.t b/plugins/t/check_ntp.t index a355aa4a..a8ac7bb8 100644 --- a/plugins/t/check_ntp.t +++ b/plugins/t/check_ntp.t @@ -37,7 +37,7 @@ my $ntp_critmatch1 = '/^NTP\sCRITICAL:\sOffset\s-?[0-9]+(\.[0-9]+)?(e-[0-9]{2})? my $ntp_okmatch2 = '/^NTP\sOK:\sOffset\s-?[0-9]+(\.[0-9]+)?(e-[0-9]{2})?\ssecs,\sjitter=[0-9]+\.[0-9]+,\sstratum=[0-9]{1,2},\struechimers=[0-9]+/'; my $ntp_warnmatch2 = '/^NTP\sWARNING:\sOffset\s-?[0-9]+(\.[0-9]+)?(e-[0-9]{2})?\ssecs,\sjitter=[0-9]+\.[0-9]+,\sstratum=[0-9]{1,2}\s\(WARNING\),\struechimers=[0-9]+/'; my $ntp_critmatch2 = '/^NTP\sCRITICAL:\sOffset\s-?[0-9]+(\.[0-9]+)?(e-[0-9]{2})?\ssecs,\sjitter=[0-9]+\.[0-9]+\s\(CRITICAL\),\sstratum=[0-9]{1,2},\struechimers=[0-9]+/'; -my $ntp_noresponse = '/^(.*Socket timeout after \d+ seconds.*)|(.*No response from NTP server.*)$/'; +my $ntp_noresponse = '/(.*Socket timeout after \d+ seconds.*)|(.*No response from NTP server.*)/'; my $ntp_nosuchhost = '/^check_ntp.*: Invalid hostname/address - ' . $hostname_invalid . '/'; -- cgit v1.2.3-74-g34f1 From 9d5774aede083297656bce14bd52e2c27a9d3169 Mon Sep 17 00:00:00 2001 From: Lorenz Kästle <12514511+RincewindsHat@users.noreply.github.com> Date: Sun, 9 Mar 2025 10:25:01 +0100 Subject: Adapt number of tests --- plugins/t/check_smtp.t | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/t/check_smtp.t b/plugins/t/check_smtp.t index 11e22644..73b4a1fd 100644 --- a/plugins/t/check_smtp.t +++ b/plugins/t/check_smtp.t @@ -24,7 +24,7 @@ my $hostname_invalid = getTestParameter( "NP_HOSTNAME_INVALID", "An invalid (not known to DNS) hostname", "nosuchhost" ); my $res; -plan tests => 16; +plan tests => 15; SKIP: { skip "No SMTP server defined", 4 unless $host_tcp_smtp; -- cgit v1.2.3-74-g34f1 From 0426b8947d9e03375219074c3741616599651db4 Mon Sep 17 00:00:00 2001 From: Lorenz Kästle <12514511+RincewindsHat@users.noreply.github.com> Date: Sun, 9 Mar 2025 11:04:32 +0100 Subject: Add check_ssh config to distributable files --- plugins/Makefile.am | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/plugins/Makefile.am b/plugins/Makefile.am index a0e9cabf..28763dfc 100644 --- a/plugins/Makefile.am +++ b/plugins/Makefile.am @@ -46,7 +46,12 @@ SUBDIRS = picohttpparser np_test_scripts = tests/test_check_swap.t -EXTRA_DIST = t tests $(np_test_scripts) check_swap.d check_dbi.d +EXTRA_DIST = t \ + tests \ + $(np_test_scripts) \ + check_swap.d \ + check_dbi.d \ + check_ssh.d PLUGINHDRS = common.h -- cgit v1.2.3-74-g34f1 From 65794e31374b3aa6e1f2c03d090b52e137df13e6 Mon Sep 17 00:00:00 2001 From: Lorenz Kästle <12514511+RincewindsHat@users.noreply.github.com> Date: Sat, 8 Mar 2025 13:05:57 +0100 Subject: Refactor check_dns --- plugins/check_dns.c | 240 ++++++++++++++++++++++--------------------- plugins/check_dns.d/config.h | 34 ++++++ 2 files changed, 158 insertions(+), 116 deletions(-) create mode 100644 plugins/check_dns.d/config.h diff --git a/plugins/check_dns.c b/plugins/check_dns.c index b3d4a6e5..7071c01f 100644 --- a/plugins/check_dns.c +++ b/plugins/check_dns.c @@ -39,26 +39,22 @@ const char *email = "devel@monitoring-plugins.org"; #include "netutils.h" #include "runcmd.h" -static int process_arguments(int /*argc*/, char ** /*argv*/); -static int validate_arguments(void); -static int error_scan(char * /*input_buffer*/, bool *); +#include "states.h" +#include "check_dns.d/config.h" + +typedef struct { + int errorcode; + check_dns_config config; +} check_dns_config_wrapper; +static check_dns_config_wrapper process_arguments(int /*argc*/, char ** /*argv*/); +static check_dns_config_wrapper validate_arguments(check_dns_config_wrapper /*config_wrapper*/); +static mp_state_enum error_scan(char * /*input_buffer*/, bool * /*is_nxdomain*/, const char /*dns_server*/[ADDRESS_LENGTH]); static bool ip_match_cidr(const char * /*addr*/, const char * /*cidr_ro*/); static unsigned long ip2long(const char * /*src*/); static void print_help(void); void print_usage(void); -#define ADDRESS_LENGTH 256 -static char query_address[ADDRESS_LENGTH] = ""; -static char dns_server[ADDRESS_LENGTH] = ""; -static char ptr_server[ADDRESS_LENGTH] = ""; static bool verbose = false; -static char **expected_address = NULL; -static int expected_address_cnt = 0; -static bool expect_nxdomain = false; - -static bool expect_authority = false; -static bool all_match = false; -static thresholds *time_thresholds = NULL; static int qstrcmp(const void *p1, const void *p2) { /* The actual arguments to this function are "pointers to @@ -68,23 +64,6 @@ static int qstrcmp(const void *p1, const void *p2) { } int main(int argc, char **argv) { - char *command_line = NULL; - char input_buffer[MAX_INPUT_BUFFER]; - char *address = NULL; /* comma separated str with addrs/ptrs (sorted) */ - char **addresses = NULL; - int n_addresses = 0; - char *msg = NULL; - char *temp_buffer = NULL; - bool non_authoritative = false; - int result = STATE_UNKNOWN; - double elapsed_time; - long microsec; - struct timeval tv; - bool parse_address = false; /* This flag scans for Address: but only after Name: */ - output chld_out; - output chld_err; - bool is_nxdomain = false; - setlocale(LC_ALL, ""); bindtextdomain(PACKAGE, LOCALEDIR); textdomain(PACKAGE); @@ -97,13 +76,19 @@ 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_dns_config_wrapper tmp = process_arguments(argc, argv); + + if (tmp.errorcode == ERROR) { usage_va(_("Could not parse arguments")); } + const check_dns_config config = tmp.config; + + char *command_line = NULL; /* get the command to run */ - xasprintf(&command_line, "%s %s %s", NSLOOKUP_COMMAND, query_address, dns_server); + xasprintf(&command_line, "%s %s %s", NSLOOKUP_COMMAND, config.query_address, config.dns_server); + struct timeval tv; alarm(timeout_interval); gettimeofday(&tv, NULL); @@ -111,12 +96,23 @@ int main(int argc, char **argv) { printf("%s\n", command_line); } + output chld_out; + output chld_err; + char *msg = NULL; + mp_state_enum result = STATE_UNKNOWN; /* run the command */ if ((np_runcmd(command_line, &chld_out, &chld_err, 0)) != 0) { msg = (char *)_("nslookup returned an error status"); result = STATE_WARNING; } + char *address = NULL; /* comma separated str with addrs/ptrs (sorted) */ + char **addresses = NULL; + size_t n_addresses = 0; + bool non_authoritative = false; + bool is_nxdomain = false; + char *temp_buffer = NULL; + bool parse_address = false; /* This flag scans for Address: but only after Name: */ /* scan stdout */ for (size_t i = 0; i < chld_out.lines; i++) { if (addresses == NULL) { @@ -140,21 +136,22 @@ int main(int argc, char **argv) { /* bug ID: 2946553 - Older versions of bind will use all available dns servers, we have to match the one specified */ - if (strstr(chld_out.line[i], "Server:") && strlen(dns_server) > 0) { + if (strstr(chld_out.line[i], "Server:") && strlen(config.dns_server) > 0) { temp_buffer = strchr(chld_out.line[i], ':'); temp_buffer++; /* Strip leading tabs */ - for (; *temp_buffer != '\0' && *temp_buffer == '\t'; temp_buffer++) + for (; *temp_buffer != '\0' && *temp_buffer == '\t'; temp_buffer++) { /* NOOP */; + } strip(temp_buffer); if (temp_buffer == NULL || strlen(temp_buffer) == 0) { die(STATE_CRITICAL, _("DNS CRITICAL - '%s' returned empty server string\n"), NSLOOKUP_COMMAND); } - if (strcmp(temp_buffer, dns_server) != 0) { - die(STATE_CRITICAL, _("DNS CRITICAL - No response from DNS %s\n"), dns_server); + if (strcmp(temp_buffer, config.dns_server) != 0) { + die(STATE_CRITICAL, _("DNS CRITICAL - No response from DNS %s\n"), config.dns_server); } } @@ -180,7 +177,7 @@ int main(int argc, char **argv) { non_authoritative = true; } - result = error_scan(chld_out.line[i], &is_nxdomain); + result = error_scan(chld_out.line[i], &is_nxdomain, config.dns_server); if (result != STATE_OK) { msg = strchr(chld_out.line[i], ':'); if (msg) { @@ -190,14 +187,15 @@ int main(int argc, char **argv) { } } + char input_buffer[MAX_INPUT_BUFFER]; /* scan stderr */ for (size_t i = 0; i < chld_err.lines; i++) { if (verbose) { puts(chld_err.line[i]); } - if (error_scan(chld_err.line[i], &is_nxdomain) != STATE_OK) { - result = max_state(result, error_scan(chld_err.line[i], &is_nxdomain)); + if (error_scan(chld_err.line[i], &is_nxdomain, config.dns_server) != STATE_OK) { + result = max_state(result, error_scan(chld_err.line[i], &is_nxdomain, config.dns_server)); msg = strchr(input_buffer, ':'); if (msg) { msg++; @@ -207,20 +205,19 @@ int main(int argc, char **argv) { } } - if (is_nxdomain && !expect_nxdomain) { - die(STATE_CRITICAL, _("Domain '%s' was not found by the server\n"), query_address); + if (is_nxdomain && !config.expect_nxdomain) { + die(STATE_CRITICAL, _("Domain '%s' was not found by the server\n"), config.query_address); } if (addresses) { - int i; - int slen; - char *adrp; + size_t slen = 1; + char *adrp = NULL; qsort(addresses, n_addresses, sizeof(*addresses), qstrcmp); - for (i = 0, slen = 1; i < n_addresses; i++) { + for (size_t i = 0; i < n_addresses; i++) { slen += strlen(addresses[i]) + 1; } adrp = address = malloc(slen); - for (i = 0; i < n_addresses; i++) { + for (size_t i = 0; i < n_addresses; i++) { if (i) { *adrp++ = ','; } @@ -233,17 +230,16 @@ int main(int argc, char **argv) { } /* compare to expected address */ - if (result == STATE_OK && expected_address_cnt > 0) { + if (result == STATE_OK && config.expected_address_cnt > 0) { result = STATE_CRITICAL; temp_buffer = ""; - unsigned long expect_match = (1 << expected_address_cnt) - 1; + unsigned long expect_match = (1 << config.expected_address_cnt) - 1; unsigned long addr_match = (1 << n_addresses) - 1; - for (int i = 0; i < expected_address_cnt; i++) { - int j; + for (size_t i = 0; i < config.expected_address_cnt; i++) { /* check if we get a match on 'raw' ip or cidr */ - for (j = 0; j < n_addresses; j++) { - if (strcmp(addresses[j], expected_address[i]) == 0 || ip_match_cidr(addresses[j], expected_address[i])) { + for (size_t j = 0; j < n_addresses; j++) { + if (strcmp(addresses[j], config.expected_address[i]) == 0 || ip_match_cidr(addresses[j], config.expected_address[i])) { result = STATE_OK; addr_match &= ~(1 << j); expect_match &= ~(1 << i); @@ -251,10 +247,10 @@ int main(int argc, char **argv) { } /* prepare an error string */ - xasprintf(&temp_buffer, "%s%s; ", temp_buffer, expected_address[i]); + xasprintf(&temp_buffer, "%s%s; ", temp_buffer, config.expected_address[i]); } /* check if expected_address must cover all in addresses and none may be missing */ - if (all_match && (expect_match != 0 || addr_match != 0)) { + if (config.all_match && (expect_match != 0 || addr_match != 0)) { result = STATE_CRITICAL; } if (result == STATE_CRITICAL) { @@ -264,10 +260,10 @@ int main(int argc, char **argv) { } } - if (expect_nxdomain) { + if (config.expect_nxdomain) { if (!is_nxdomain) { result = STATE_CRITICAL; - xasprintf(&msg, _("Domain '%s' was found by the server: '%s'\n"), query_address, address); + xasprintf(&msg, _("Domain '%s' was found by the server: '%s'\n"), config.query_address, address); } else { if (address != NULL) { free(address); @@ -277,16 +273,16 @@ int main(int argc, char **argv) { } /* check if authoritative */ - if (result == STATE_OK && expect_authority && non_authoritative) { + if (result == STATE_OK && config.expect_authority && non_authoritative) { result = STATE_CRITICAL; - xasprintf(&msg, _("server %s is not authoritative for %s"), dns_server, query_address); + xasprintf(&msg, _("server %s is not authoritative for %s"), config.dns_server, config.query_address); } - microsec = deltime(tv); - elapsed_time = (double)microsec / 1.0e6; + long microsec = deltime(tv); + double elapsed_time = (double)microsec / 1.0e6; if (result == STATE_OK) { - result = get_status(elapsed_time, time_thresholds); + result = get_status(elapsed_time, config.time_thresholds); if (result == STATE_OK) { printf("DNS %s: ", _("OK")); } else if (result == STATE_WARNING) { @@ -295,14 +291,14 @@ int main(int argc, char **argv) { printf("DNS %s: ", _("CRITICAL")); } printf(ngettext("%.3f second response time", "%.3f seconds response time", elapsed_time), elapsed_time); - printf(_(". %s returns %s"), query_address, address); - if ((time_thresholds->warning != NULL) && (time_thresholds->critical != NULL)) { - printf("|%s\n", fperfdata("time", elapsed_time, "s", true, time_thresholds->warning->end, true, time_thresholds->critical->end, - true, 0, false, 0)); - } else if ((time_thresholds->warning == NULL) && (time_thresholds->critical != NULL)) { - printf("|%s\n", fperfdata("time", elapsed_time, "s", false, 0, true, time_thresholds->critical->end, true, 0, false, 0)); - } else if ((time_thresholds->warning != NULL) && (time_thresholds->critical == NULL)) { - printf("|%s\n", fperfdata("time", elapsed_time, "s", true, time_thresholds->warning->end, false, 0, true, 0, false, 0)); + printf(_(". %s returns %s"), config.query_address, address); + if ((config.time_thresholds->warning != NULL) && (config.time_thresholds->critical != NULL)) { + printf("|%s\n", fperfdata("time", elapsed_time, "s", true, config.time_thresholds->warning->end, true, + config.time_thresholds->critical->end, true, 0, false, 0)); + } else if ((config.time_thresholds->warning == NULL) && (config.time_thresholds->critical != NULL)) { + printf("|%s\n", fperfdata("time", elapsed_time, "s", false, 0, true, config.time_thresholds->critical->end, true, 0, false, 0)); + } else if ((config.time_thresholds->warning != NULL) && (config.time_thresholds->critical == NULL)) { + printf("|%s\n", fperfdata("time", elapsed_time, "s", true, config.time_thresholds->warning->end, false, 0, true, 0, false, 0)); } else { printf("|%s\n", fperfdata("time", elapsed_time, "s", false, 0, false, 0, true, 0, false, 0)); } @@ -314,7 +310,7 @@ int main(int argc, char **argv) { printf(_("DNS UNKNOWN - %s\n"), !strcmp(msg, "") ? _(" Probably a non-existent host/domain") : msg); } - return result; + exit(result); } bool ip_match_cidr(const char *addr, const char *cidr_ro) { @@ -342,7 +338,7 @@ unsigned long ip2long(const char *src) { : 0; } -int error_scan(char *input_buffer, bool *is_nxdomain) { +mp_state_enum error_scan(char *input_buffer, bool *is_nxdomain, const char dns_server[ADDRESS_LENGTH]) { const int nxdomain = strstr(input_buffer, "Non-existent") || strstr(input_buffer, "** server can't find") || strstr(input_buffer, "** Can't find") || strstr(input_buffer, "NXDOMAIN"); @@ -404,12 +400,7 @@ int error_scan(char *input_buffer, bool *is_nxdomain) { } /* process command-line arguments */ -int process_arguments(int argc, char **argv) { - int c; - char *warning = NULL; - char *critical = NULL; - - int opt_index = 0; +check_dns_config_wrapper process_arguments(int argc, char **argv) { static struct option long_opts[] = {{"help", no_argument, 0, 'h'}, {"version", no_argument, 0, 'V'}, {"verbose", no_argument, 0, 'v'}, @@ -425,24 +416,34 @@ int process_arguments(int argc, char **argv) { {"critical", required_argument, 0, 'c'}, {0, 0, 0, 0}}; + check_dns_config_wrapper result = { + .config = check_dns_config_init(), + .errorcode = OK, + }; + if (argc < 2) { - return ERROR; + result.errorcode = ERROR; + return result; } - for (c = 1; c < argc; c++) { - if (strcmp("-to", argv[c]) == 0) { - strcpy(argv[c], "-t"); + for (int index = 1; index < argc; index++) { + if (strcmp("-to", argv[index]) == 0) { + strcpy(argv[index], "-t"); } } - while (1) { - c = getopt_long(argc, argv, "hVvALnt:H:s:r:a:w:c:", long_opts, &opt_index); + char *warning = NULL; + char *critical = NULL; + int opt_index = 0; + int index = 0; + while (true) { + index = getopt_long(argc, argv, "hVvALnt:H:s:r:a:w:c:", long_opts, &opt_index); - if (c == -1 || c == EOF) { + if (index == -1 || index == EOF) { break; } - switch (c) { + switch (index) { case 'h': /* help */ print_help(); exit(STATE_UNKNOWN); @@ -459,7 +460,7 @@ int process_arguments(int argc, char **argv) { if (strlen(optarg) >= ADDRESS_LENGTH) { die(STATE_UNKNOWN, _("Input buffer overflow\n")); } - strcpy(query_address, optarg); + strcpy(result.config.query_address, optarg); break; case 's': /* server name */ /* TODO: this host_or_die check is probably unnecessary. @@ -468,14 +469,16 @@ int process_arguments(int argc, char **argv) { if (strlen(optarg) >= ADDRESS_LENGTH) { die(STATE_UNKNOWN, _("Input buffer overflow\n")); } - strcpy(dns_server, optarg); + strcpy(result.config.dns_server, optarg); break; case 'r': /* reverse server name */ /* TODO: Is this host_or_die necessary? */ + // TODO This does not do anything!!! 2025-03-08 rincewind host_or_die(optarg); if (strlen(optarg) >= ADDRESS_LENGTH) { die(STATE_UNKNOWN, _("Input buffer overflow\n")); } + static char ptr_server[ADDRESS_LENGTH] = ""; strcpy(ptr_server, optarg); break; case 'a': /* expected address */ @@ -485,29 +488,32 @@ int process_arguments(int argc, char **argv) { if (strchr(optarg, ',') != NULL) { char *comma = strchr(optarg, ','); while (comma != NULL) { - expected_address = (char **)realloc(expected_address, (expected_address_cnt + 1) * sizeof(char **)); - expected_address[expected_address_cnt] = strndup(optarg, comma - optarg); - expected_address_cnt++; + result.config.expected_address = + (char **)realloc(result.config.expected_address, (result.config.expected_address_cnt + 1) * sizeof(char **)); + result.config.expected_address[result.config.expected_address_cnt] = strndup(optarg, comma - optarg); + result.config.expected_address_cnt++; optarg = comma + 1; comma = strchr(optarg, ','); } - expected_address = (char **)realloc(expected_address, (expected_address_cnt + 1) * sizeof(char **)); - expected_address[expected_address_cnt] = strdup(optarg); - expected_address_cnt++; + result.config.expected_address = + (char **)realloc(result.config.expected_address, (result.config.expected_address_cnt + 1) * sizeof(char **)); + result.config.expected_address[result.config.expected_address_cnt] = strdup(optarg); + result.config.expected_address_cnt++; } else { - expected_address = (char **)realloc(expected_address, (expected_address_cnt + 1) * sizeof(char **)); - expected_address[expected_address_cnt] = strdup(optarg); - expected_address_cnt++; + result.config.expected_address = + (char **)realloc(result.config.expected_address, (result.config.expected_address_cnt + 1) * sizeof(char **)); + result.config.expected_address[result.config.expected_address_cnt] = strdup(optarg); + result.config.expected_address_cnt++; } break; case 'n': /* expect NXDOMAIN */ - expect_nxdomain = true; + result.config.expect_nxdomain = true; break; case 'A': /* expect authority */ - expect_authority = true; + result.config.expect_authority = true; break; case 'L': /* all must match */ - all_match = true; + result.config.all_match = true; break; case 'w': warning = optarg; @@ -520,40 +526,42 @@ int process_arguments(int argc, char **argv) { } } - c = optind; - if (strlen(query_address) == 0 && c < argc) { - if (strlen(argv[c]) >= ADDRESS_LENGTH) { + index = optind; + if (strlen(result.config.query_address) == 0 && index < argc) { + if (strlen(argv[index]) >= ADDRESS_LENGTH) { die(STATE_UNKNOWN, _("Input buffer overflow\n")); } - strcpy(query_address, argv[c++]); + strcpy(result.config.query_address, argv[index++]); } - if (strlen(dns_server) == 0 && c < argc) { + if (strlen(result.config.dns_server) == 0 && index < argc) { /* TODO: See -s option */ - host_or_die(argv[c]); - if (strlen(argv[c]) >= ADDRESS_LENGTH) { + host_or_die(argv[index]); + if (strlen(argv[index]) >= ADDRESS_LENGTH) { die(STATE_UNKNOWN, _("Input buffer overflow\n")); } - strcpy(dns_server, argv[c++]); + strcpy(result.config.dns_server, argv[index++]); } - set_thresholds(&time_thresholds, warning, critical); + set_thresholds(&result.config.time_thresholds, warning, critical); - return validate_arguments(); + return validate_arguments(result); } -int validate_arguments(void) { - if (query_address[0] == 0) { +check_dns_config_wrapper validate_arguments(check_dns_config_wrapper config_wrapper) { + if (config_wrapper.config.query_address[0] == 0) { printf("missing --host argument\n"); - return ERROR; + config_wrapper.errorcode = ERROR; + return config_wrapper; } - if (expected_address_cnt > 0 && expect_nxdomain) { + if (config_wrapper.config.expected_address_cnt > 0 && config_wrapper.config.expect_nxdomain) { printf("--expected-address and --expect-nxdomain cannot be combined\n"); - return ERROR; + config_wrapper.errorcode = ERROR; + return config_wrapper; } - return OK; + return config_wrapper; } void print_help(void) { diff --git a/plugins/check_dns.d/config.h b/plugins/check_dns.d/config.h new file mode 100644 index 00000000..9ec4eb82 --- /dev/null +++ b/plugins/check_dns.d/config.h @@ -0,0 +1,34 @@ +#pragma once + +#include "../../config.h" +#include "thresholds.h" +#include + +#define ADDRESS_LENGTH 256 + +typedef struct { + bool all_match; + char dns_server[ADDRESS_LENGTH]; + char query_address[ADDRESS_LENGTH]; + bool expect_nxdomain; + bool expect_authority; + char **expected_address; + size_t expected_address_cnt; + + thresholds *time_thresholds; +} check_dns_config; + +check_dns_config check_dns_config_init() { + check_dns_config tmp = { + .all_match = false, + .dns_server = "", + .query_address = "", + .expect_nxdomain = false, + .expect_authority = false, + .expected_address = NULL, + .expected_address_cnt = 0, + + .time_thresholds = NULL, + }; + return tmp; +} -- cgit v1.2.3-74-g34f1 From c0d9580dac9779c40434c9b63a0ef4ef82b2e8ba Mon Sep 17 00:00:00 2001 From: Lorenz Kästle <12514511+RincewindsHat@users.noreply.github.com> Date: Sun, 9 Mar 2025 12:11:02 +0100 Subject: check_dns: some comments, small improvements --- plugins/check_dns.c | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/plugins/check_dns.c b/plugins/check_dns.c index 7071c01f..e98c709f 100644 --- a/plugins/check_dns.c +++ b/plugins/check_dns.c @@ -106,14 +106,16 @@ int main(int argc, char **argv) { result = STATE_WARNING; } - char *address = NULL; /* comma separated str with addrs/ptrs (sorted) */ - char **addresses = NULL; - size_t n_addresses = 0; + /* ===== + * scan stdout, main results get retrieved here + * ===== + */ + char *address = NULL; /* comma separated str with addrs/ptrs (sorted) */ + char **addresses = NULL; // All addresses parsed from stdout + size_t n_addresses = 0; // counter for retrieved addresses bool non_authoritative = false; bool is_nxdomain = false; - char *temp_buffer = NULL; bool parse_address = false; /* This flag scans for Address: but only after Name: */ - /* scan stdout */ for (size_t i = 0; i < chld_out.lines; i++) { if (addresses == NULL) { addresses = malloc(sizeof(*addresses) * 10); @@ -126,6 +128,7 @@ int main(int argc, char **argv) { } if (strcasestr(chld_out.line[i], ".in-addr.arpa") || strcasestr(chld_out.line[i], ".ip6.arpa")) { + char *temp_buffer = NULL; if ((temp_buffer = strstr(chld_out.line[i], "name = "))) { addresses[n_addresses++] = strdup(temp_buffer + 7); } else { @@ -137,6 +140,7 @@ int main(int argc, char **argv) { /* bug ID: 2946553 - Older versions of bind will use all available dns servers, we have to match the one specified */ if (strstr(chld_out.line[i], "Server:") && strlen(config.dns_server) > 0) { + char *temp_buffer = NULL; temp_buffer = strchr(chld_out.line[i], ':'); temp_buffer++; @@ -159,6 +163,7 @@ int main(int argc, char **argv) { if (strstr(chld_out.line[i], "Name:")) { parse_address = true; } else if (parse_address && (strstr(chld_out.line[i], "Address:") || strstr(chld_out.line[i], "Addresses:"))) { + char *temp_buffer = NULL; temp_buffer = index(chld_out.line[i], ':'); temp_buffer++; @@ -216,6 +221,8 @@ int main(int argc, char **argv) { for (size_t i = 0; i < n_addresses; i++) { slen += strlen(addresses[i]) + 1; } + + // Temporary pointer adrp gets moved, address stays on the beginning adrp = address = malloc(slen); for (size_t i = 0; i < n_addresses; i++) { if (i) { @@ -232,7 +239,7 @@ int main(int argc, char **argv) { /* compare to expected address */ if (result == STATE_OK && config.expected_address_cnt > 0) { result = STATE_CRITICAL; - temp_buffer = ""; + char *temp_buffer = ""; unsigned long expect_match = (1 << config.expected_address_cnt) - 1; unsigned long addr_match = (1 << n_addresses) - 1; -- cgit v1.2.3-74-g34f1 From 8b8ce8a6055664b8db2156093fd6afa9cfa1c42f Mon Sep 17 00:00:00 2001 From: Lorenz Kästle <12514511+RincewindsHat@users.noreply.github.com> Date: Sun, 9 Mar 2025 12:41:13 +0100 Subject: Remove redundant NULL checks and replace deprecated index function --- plugins/check_dns.c | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/plugins/check_dns.c b/plugins/check_dns.c index e98c709f..a4c8e9b1 100644 --- a/plugins/check_dns.c +++ b/plugins/check_dns.c @@ -140,8 +140,11 @@ int main(int argc, char **argv) { /* bug ID: 2946553 - Older versions of bind will use all available dns servers, we have to match the one specified */ if (strstr(chld_out.line[i], "Server:") && strlen(config.dns_server) > 0) { - char *temp_buffer = NULL; - temp_buffer = strchr(chld_out.line[i], ':'); + char *temp_buffer = strchr(chld_out.line[i], ':'); + if (temp_buffer == NULL) { + die(STATE_UNKNOWN, _("'%s' returned a weirdly formatted Server line\n"), NSLOOKUP_COMMAND); + } + temp_buffer++; /* Strip leading tabs */ @@ -150,7 +153,7 @@ int main(int argc, char **argv) { } strip(temp_buffer); - if (temp_buffer == NULL || strlen(temp_buffer) == 0) { + if (strlen(temp_buffer) == 0) { die(STATE_CRITICAL, _("DNS CRITICAL - '%s' returned empty server string\n"), NSLOOKUP_COMMAND); } @@ -163,8 +166,11 @@ int main(int argc, char **argv) { if (strstr(chld_out.line[i], "Name:")) { parse_address = true; } else if (parse_address && (strstr(chld_out.line[i], "Address:") || strstr(chld_out.line[i], "Addresses:"))) { - char *temp_buffer = NULL; - temp_buffer = index(chld_out.line[i], ':'); + char *temp_buffer = strchr(chld_out.line[i], ':'); + if (temp_buffer == NULL) { + die(STATE_UNKNOWN, _("'%s' returned a weirdly formatted Address line\n"), NSLOOKUP_COMMAND); + } + temp_buffer++; /* Strip leading spaces */ @@ -173,7 +179,7 @@ int main(int argc, char **argv) { } strip(temp_buffer); - if (temp_buffer == NULL || strlen(temp_buffer) == 0) { + if (strlen(temp_buffer) == 0) { die(STATE_CRITICAL, _("DNS CRITICAL - '%s' returned empty host name string\n"), NSLOOKUP_COMMAND); } -- cgit v1.2.3-74-g34f1 From 8a415c3c09540caeeeffb2f8e24623ad25d23165 Mon Sep 17 00:00:00 2001 From: Lorenz Kästle <12514511+RincewindsHat@users.noreply.github.com> Date: Sun, 9 Mar 2025 12:45:15 +0100 Subject: Add check_dns to distribution files --- plugins/Makefile.am | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/plugins/Makefile.am b/plugins/Makefile.am index 28763dfc..6ee93c18 100644 --- a/plugins/Makefile.am +++ b/plugins/Makefile.am @@ -51,7 +51,8 @@ EXTRA_DIST = t \ $(np_test_scripts) \ check_swap.d \ check_dbi.d \ - check_ssh.d + check_ssh.d \ + check_dns.d PLUGINHDRS = common.h -- cgit v1.2.3-74-g34f1 From 16cb24807db5b1bd20e2b31a15bda7940f1145bd Mon Sep 17 00:00:00 2001 From: Lorenz Kästle <12514511+RincewindsHat@users.noreply.github.com> Date: Sun, 9 Mar 2025 15:43:06 +0100 Subject: ignore CNAMEs in RDNS-mode #1460 Suppose your provider uses RFC 2317 (or RFC 4183 for that matter). The output of nslookup could look like the following: 2.120.22.172.in-addr.arpa canonical name = 2.0/26.120.22.172.in-addr.arpa. 2.0/26.120.22.172.in-addr.arpa name = rajesh.intern.prauscher.de. Without this filter, check_dns would check the string against "2.0/26.120.22.172.in-addr.arpa., rajesh.intern.prauscher.de." which will fail for obvious reasons. In forward DNS, this is achieved in line 165, as nslookup will print the address separate from the CNAME-resolving. Original commit by Patrick Rauscher (prauscher@prauscher.de), adapted here. --- plugins/check_dns.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/plugins/check_dns.c b/plugins/check_dns.c index a4c8e9b1..95f33083 100644 --- a/plugins/check_dns.c +++ b/plugins/check_dns.c @@ -128,6 +128,9 @@ int main(int argc, char **argv) { } if (strcasestr(chld_out.line[i], ".in-addr.arpa") || strcasestr(chld_out.line[i], ".ip6.arpa")) { + if ((strstr(chld_out.line[i], "canonical name = ") != NULL)) { + continue; + } char *temp_buffer = NULL; if ((temp_buffer = strstr(chld_out.line[i], "name = "))) { addresses[n_addresses++] = strdup(temp_buffer + 7); -- cgit v1.2.3-74-g34f1 From 0867319268898bc63f483e6257c65123e10603ba Mon Sep 17 00:00:00 2001 From: Lorenz Kästle <12514511+RincewindsHat@users.noreply.github.com> Date: Sun, 9 Mar 2025 23:40:05 +0100 Subject: check_smtp: clang-format --- plugins/check_smtp.c | 850 +++++++++++++++++++++++++-------------------------- 1 file changed, 410 insertions(+), 440 deletions(-) diff --git a/plugins/check_smtp.c b/plugins/check_smtp.c index e6369e63..bb45e01b 100644 --- a/plugins/check_smtp.c +++ b/plugins/check_smtp.c @@ -1,32 +1,32 @@ /***************************************************************************** -* -* Monitoring check_smtp plugin -* -* License: GPL -* Copyright (c) 2000-2024 Monitoring Plugins Development Team -* -* Description: -* -* This file contains the check_smtp plugin -* -* This plugin will attempt to open an SMTP connection with the host. -* -* -* This program is free software: you can redistribute it and/or modify -* it under the terms of the GNU General Public License as published by -* the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU General Public License for more details. -* -* You should have received a copy of the GNU General Public License -* along with this program. If not, see . -* -* -*****************************************************************************/ + * + * Monitoring check_smtp plugin + * + * License: GPL + * Copyright (c) 2000-2024 Monitoring Plugins Development Team + * + * Description: + * + * This file contains the check_smtp plugin + * + * This plugin will attempt to open an SMTP connection with the host. + * + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + * + *****************************************************************************/ const char *progname = "check_smtp"; const char *copyright = "2000-2024"; @@ -42,24 +42,20 @@ const char *email = "devel@monitoring-plugins.org"; #ifdef HAVE_SSL static bool check_cert = false; static int days_till_exp_warn, days_till_exp_crit; -# define my_recv(buf, len) (((use_starttls || use_ssl) && ssl_established) ? np_net_ssl_read(buf, len) : read(sd, buf, len)) -# define my_send(buf, len) (((use_starttls || use_ssl) && ssl_established) ? np_net_ssl_write(buf, len) : send(sd, buf, len, 0)) +# define my_recv(buf, len) (((use_starttls || use_ssl) && ssl_established) ? np_net_ssl_read(buf, len) : read(sd, buf, len)) +# define my_send(buf, len) (((use_starttls || use_ssl) && ssl_established) ? np_net_ssl_write(buf, len) : send(sd, buf, len, 0)) #else /* ifndef HAVE_SSL */ -# define my_recv(buf, len) read(sd, buf, len) -# define my_send(buf, len) send(sd, buf, len, 0) +# define my_recv(buf, len) read(sd, buf, len) +# define my_send(buf, len) send(sd, buf, len, 0) #endif -enum { - SMTP_PORT = 25, - SMTPS_PORT = 465 -}; -#define PROXY_PREFIX "PROXY TCP4 0.0.0.0 0.0.0.0 25 25\r\n" -#define SMTP_EXPECT "220" -#define SMTP_HELO "HELO " -#define SMTP_EHLO "EHLO " -#define SMTP_LHLO "LHLO " -#define SMTP_QUIT "QUIT\r\n" -#define SMTP_STARTTLS "STARTTLS\r\n" +#define PROXY_PREFIX "PROXY TCP4 0.0.0.0 0.0.0.0 25 25\r\n" +#define SMTP_EXPECT "220" +#define SMTP_HELO "HELO " +#define SMTP_EHLO "EHLO " +#define SMTP_LHLO "LHLO " +#define SMTP_QUIT "QUIT\r\n" +#define SMTP_STARTTLS "STARTTLS\r\n" #define SMTP_AUTH_LOGIN "AUTH LOGIN\r\n" #define EHLO_SUPPORTS_STARTTLS 1 @@ -81,17 +77,16 @@ static int cflags = REG_EXTENDED | REG_NOSUB | REG_NEWLINE; static int eflags = 0; static int errcode, excode; -static int server_port = SMTP_PORT; static int server_port_option = 0; static char *server_address = NULL; static char *server_expect = NULL; static char *mail_command = NULL; static char *from_arg = NULL; -static int send_mail_from=0; -static int ncommands=0; -static int command_size=0; -static int nresponses=0; -static int response_size=0; +static int send_mail_from = 0; +static int ncommands = 0; +static int command_size = 0; +static int nresponses = 0; +static int response_size = 0; static char **commands = NULL; static char **responses = NULL; static char *authtype = NULL; @@ -113,15 +108,12 @@ static char *localhostname = NULL; static int sd; static char buffer[MAX_INPUT_BUFFER]; enum { - TCP_PROTOCOL = 1, - UDP_PROTOCOL = 2, + TCP_PROTOCOL = 1, + UDP_PROTOCOL = 2, }; static bool ignore_send_quit_failure = false; - -int -main (int argc, char **argv) -{ +int main(int argc, char **argv) { bool supports_tls = false; int n = 0; double elapsed_time; @@ -134,63 +126,68 @@ main (int argc, char **argv) struct timeval tv; /* Catch pipe errors in read/write - sometimes occurs when writing QUIT */ - (void) signal (SIGPIPE, SIG_IGN); + (void)signal(SIGPIPE, SIG_IGN); - setlocale (LC_ALL, ""); - bindtextdomain (PACKAGE, LOCALEDIR); - textdomain (PACKAGE); + setlocale(LC_ALL, ""); + bindtextdomain(PACKAGE, LOCALEDIR); + textdomain(PACKAGE); /* Parse extra opts if any */ - argv=np_extra_opts (&argc, argv, progname); + argv = np_extra_opts(&argc, argv, progname); - if (process_arguments (argc, argv) == ERROR) - usage4 (_("Could not parse arguments")); + if (process_arguments(argc, argv) == ERROR) { + usage4(_("Could not parse arguments")); + } /* If localhostname not set on command line, use gethostname to set */ - if(! localhostname){ - localhostname = malloc (HOST_MAX_BYTES); - if(!localhostname){ + if (!localhostname) { + localhostname = malloc(HOST_MAX_BYTES); + if (!localhostname) { printf(_("malloc() failed!\n")); return STATE_CRITICAL; } - if(gethostname(localhostname, HOST_MAX_BYTES)){ + if (gethostname(localhostname, HOST_MAX_BYTES)) { printf(_("gethostname() failed!\n")); return STATE_CRITICAL; } } - if(use_lhlo) - xasprintf (&helocmd, "%s%s%s", SMTP_LHLO, localhostname, "\r\n"); - else if(use_ehlo) - xasprintf (&helocmd, "%s%s%s", SMTP_EHLO, localhostname, "\r\n"); - else - xasprintf (&helocmd, "%s%s%s", SMTP_HELO, localhostname, "\r\n"); - - if (verbose) + if (use_lhlo) { + xasprintf(&helocmd, "%s%s%s", SMTP_LHLO, localhostname, "\r\n"); + } else if (use_ehlo) { + xasprintf(&helocmd, "%s%s%s", SMTP_EHLO, localhostname, "\r\n"); + } else { + xasprintf(&helocmd, "%s%s%s", SMTP_HELO, localhostname, "\r\n"); + } + + if (verbose) { printf("HELOCMD: %s", helocmd); + } /* initialize the MAIL command with optional FROM command */ - xasprintf (&cmd_str, "%sFROM:<%s>%s", mail_command, from_arg, "\r\n"); + xasprintf(&cmd_str, "%sFROM:<%s>%s", mail_command, from_arg, "\r\n"); - if (verbose && send_mail_from) - printf ("FROM CMD: %s", cmd_str); + if (verbose && send_mail_from) { + printf("FROM CMD: %s", cmd_str); + } /* initialize alarm signal handling */ - (void) signal (SIGALRM, socket_timeout_alarm_handler); + (void)signal(SIGALRM, socket_timeout_alarm_handler); /* set socket timeout */ - (void) alarm (socket_timeout); + (void)alarm(socket_timeout); /* start timer */ - gettimeofday (&tv, NULL); + gettimeofday(&tv, NULL); /* try to connect to the host at the given port number */ - result = my_tcp_connect (server_address, server_port, &sd); + result = my_tcp_connect(server_address, server_port, &sd); if (result == STATE_OK) { /* we connected */ /* If requested, send PROXY header */ if (use_proxy_prefix) { - if (verbose) - printf ("Sending header %s\n", PROXY_PREFIX); + if (verbose) { + printf("Sending header %s\n", PROXY_PREFIX); + } my_send(PROXY_PREFIX, strlen(PROXY_PREFIX)); } @@ -198,7 +195,7 @@ main (int argc, char **argv) if (use_ssl) { result = np_net_ssl_init_with_hostname(sd, (use_sni ? server_address : NULL)); if (result != STATE_OK) { - printf (_("CRITICAL - Cannot create SSL context.\n")); + printf(_("CRITICAL - Cannot create SSL context.\n")); close(sd); np_net_ssl_cleanup(); return STATE_CRITICAL; @@ -211,7 +208,7 @@ main (int argc, char **argv) /* watch for the SMTP connection string and */ /* return a WARNING status if we couldn't read any data */ if (recvlines(buffer, MAX_INPUT_BUFFER) <= 0) { - printf (_("recv() failed\n")); + printf(_("recv() failed\n")); return STATE_WARNING; } @@ -223,130 +220,131 @@ main (int argc, char **argv) /* allow for response to helo command to reach us */ if (recvlines(buffer, MAX_INPUT_BUFFER) <= 0) { - printf (_("recv() failed\n")); + printf(_("recv() failed\n")); return STATE_WARNING; - } else if(use_ehlo || use_lhlo){ - if(strstr(buffer, "250 STARTTLS") != NULL || - strstr(buffer, "250-STARTTLS") != NULL){ - supports_tls=true; + } else if (use_ehlo || use_lhlo) { + if (strstr(buffer, "250 STARTTLS") != NULL || strstr(buffer, "250-STARTTLS") != NULL) { + supports_tls = true; } } - if(use_starttls && ! supports_tls){ + if (use_starttls && !supports_tls) { printf(_("WARNING - TLS not supported by server\n")); smtp_quit(); return STATE_WARNING; } #ifdef HAVE_SSL - if(use_starttls) { - /* send the STARTTLS command */ - send(sd, SMTP_STARTTLS, strlen(SMTP_STARTTLS), 0); - - recvlines(buffer, MAX_INPUT_BUFFER); /* wait for it */ - if (!strstr (buffer, SMTP_EXPECT)) { - printf (_("Server does not support STARTTLS\n")); - smtp_quit(); - return STATE_UNKNOWN; - } - result = np_net_ssl_init_with_hostname(sd, (use_sni ? server_address : NULL)); - if(result != STATE_OK) { - printf (_("CRITICAL - Cannot create SSL context.\n")); - close(sd); - np_net_ssl_cleanup(); - return STATE_CRITICAL; - } else { - ssl_established = 1; - } - - /* - * Resend the EHLO command. - * - * RFC 3207 (4.2) says: ``The client MUST discard any knowledge - * obtained from the server, such as the list of SMTP service - * extensions, which was not obtained from the TLS negotiation - * itself. The client SHOULD send an EHLO command as the first - * command after a successful TLS negotiation.'' For this - * reason, some MTAs will not allow an AUTH LOGIN command before - * we resent EHLO via TLS. - */ - if (my_send(helocmd, strlen(helocmd)) <= 0) { - printf("%s\n", _("SMTP UNKNOWN - Cannot send EHLO command via TLS.")); - my_close(); - return STATE_UNKNOWN; - } - if (verbose) - printf(_("sent %s"), helocmd); - if ((n = recvlines(buffer, MAX_INPUT_BUFFER)) <= 0) { - printf("%s\n", _("SMTP UNKNOWN - Cannot read EHLO response via TLS.")); - my_close(); - return STATE_UNKNOWN; - } - if (verbose) { - printf("%s", buffer); - } + if (use_starttls) { + /* send the STARTTLS command */ + send(sd, SMTP_STARTTLS, strlen(SMTP_STARTTLS), 0); + + recvlines(buffer, MAX_INPUT_BUFFER); /* wait for it */ + if (!strstr(buffer, SMTP_EXPECT)) { + printf(_("Server does not support STARTTLS\n")); + smtp_quit(); + return STATE_UNKNOWN; + } + result = np_net_ssl_init_with_hostname(sd, (use_sni ? server_address : NULL)); + if (result != STATE_OK) { + printf(_("CRITICAL - Cannot create SSL context.\n")); + close(sd); + np_net_ssl_cleanup(); + return STATE_CRITICAL; + } else { + ssl_established = 1; + } + + /* + * Resend the EHLO command. + * + * RFC 3207 (4.2) says: ``The client MUST discard any knowledge + * obtained from the server, such as the list of SMTP service + * extensions, which was not obtained from the TLS negotiation + * itself. The client SHOULD send an EHLO command as the first + * command after a successful TLS negotiation.'' For this + * reason, some MTAs will not allow an AUTH LOGIN command before + * we resent EHLO via TLS. + */ + if (my_send(helocmd, strlen(helocmd)) <= 0) { + printf("%s\n", _("SMTP UNKNOWN - Cannot send EHLO command via TLS.")); + my_close(); + return STATE_UNKNOWN; + } + if (verbose) { + printf(_("sent %s"), helocmd); + } + if ((n = recvlines(buffer, MAX_INPUT_BUFFER)) <= 0) { + printf("%s\n", _("SMTP UNKNOWN - Cannot read EHLO response via TLS.")); + my_close(); + return STATE_UNKNOWN; + } + if (verbose) { + printf("%s", buffer); + } -# ifdef USE_OPENSSL - if ( check_cert ) { - result = np_net_ssl_check_cert(days_till_exp_warn, days_till_exp_crit); - smtp_quit(); - my_close(); - return result; - } -# endif /* USE_OPENSSL */ +# ifdef USE_OPENSSL + if (check_cert) { + result = np_net_ssl_check_cert(days_till_exp_warn, days_till_exp_crit); + smtp_quit(); + my_close(); + return result; + } +# endif /* USE_OPENSSL */ } #endif - if (verbose) - printf ("%s", buffer); + if (verbose) { + printf("%s", buffer); + } /* save buffer for later use */ xasprintf(&server_response, "%s%s", server_response, buffer); /* strip the buffer of carriage returns */ - strip (server_response); + strip(server_response); /* make sure we find the droids we are looking for */ - if (!strstr (server_response, server_expect)) { - if (server_port == SMTP_PORT) - printf (_("Invalid SMTP response received from host: %s\n"), server_response); - else - printf (_("Invalid SMTP response received from host on port %d: %s\n"), - server_port, server_response); + if (!strstr(server_response, server_expect)) { + if (server_port == SMTP_PORT) { + printf(_("Invalid SMTP response received from host: %s\n"), server_response); + } else { + printf(_("Invalid SMTP response received from host on port %d: %s\n"), server_port, server_response); + } return STATE_WARNING; } if (send_mail_from) { - my_send(cmd_str, strlen(cmd_str)); - if (recvlines(buffer, MAX_INPUT_BUFFER) >= 1 && verbose) - printf("%s", buffer); + my_send(cmd_str, strlen(cmd_str)); + if (recvlines(buffer, MAX_INPUT_BUFFER) >= 1 && verbose) { + printf("%s", buffer); + } } n = 0; while (n < ncommands) { - xasprintf (&cmd_str, "%s%s", commands[n], "\r\n"); + xasprintf(&cmd_str, "%s%s", commands[n], "\r\n"); my_send(cmd_str, strlen(cmd_str)); - if (recvlines(buffer, MAX_INPUT_BUFFER) >= 1 && verbose) + if (recvlines(buffer, MAX_INPUT_BUFFER) >= 1 && verbose) { printf("%s", buffer); - strip (buffer); + } + strip(buffer); if (n < nresponses) { cflags |= REG_EXTENDED | REG_NOSUB | REG_NEWLINE; - errcode = regcomp (&preg, responses[n], cflags); + errcode = regcomp(&preg, responses[n], cflags); if (errcode != 0) { - regerror (errcode, &preg, errbuf, MAX_INPUT_BUFFER); - printf (_("Could Not Compile Regular Expression")); + regerror(errcode, &preg, errbuf, MAX_INPUT_BUFFER); + printf(_("Could Not Compile Regular Expression")); return ERROR; } - excode = regexec (&preg, buffer, 10, pmatch, eflags); + excode = regexec(&preg, buffer, 10, pmatch, eflags); if (excode == 0) { result = STATE_OK; - } - else if (excode == REG_NOMATCH) { + } else if (excode == REG_NOMATCH) { result = STATE_WARNING; - printf (_("SMTP %s - Invalid response '%s' to command '%s'\n"), state_text (result), buffer, commands[n]); - } - else { - regerror (excode, &preg, errbuf, MAX_INPUT_BUFFER); - printf (_("Execute Error: %s\n"), errbuf); + printf(_("SMTP %s - Invalid response '%s' to command '%s'\n"), state_text(result), buffer, commands[n]); + } else { + regerror(excode, &preg, errbuf, MAX_INPUT_BUFFER); + printf(_("Execute Error: %s\n"), errbuf); result = STATE_UNKNOWN; } } @@ -354,7 +352,7 @@ main (int argc, char **argv) } if (authtype != NULL) { - if (strcmp (authtype, "LOGIN") == 0) { + if (strcmp(authtype, "LOGIN") == 0) { char *abuf; int ret; do { @@ -371,29 +369,32 @@ main (int argc, char **argv) /* send AUTH LOGIN */ my_send(SMTP_AUTH_LOGIN, strlen(SMTP_AUTH_LOGIN)); - if (verbose) - printf (_("sent %s\n"), "AUTH LOGIN"); + if (verbose) { + printf(_("sent %s\n"), "AUTH LOGIN"); + } if ((ret = recvlines(buffer, MAX_INPUT_BUFFER)) <= 0) { xasprintf(&error_msg, _("recv() failed after AUTH LOGIN, ")); result = STATE_WARNING; break; } - if (verbose) - printf (_("received %s\n"), buffer); + if (verbose) { + printf(_("received %s\n"), buffer); + } - if (strncmp (buffer, "334", 3) != 0) { + if (strncmp(buffer, "334", 3) != 0) { result = STATE_CRITICAL; xasprintf(&error_msg, _("invalid response received after AUTH LOGIN, ")); break; } /* encode authuser with base64 */ - base64_encode_alloc (authuser, strlen(authuser), &abuf); + base64_encode_alloc(authuser, strlen(authuser), &abuf); xasprintf(&abuf, "%s\r\n", abuf); my_send(abuf, strlen(abuf)); - if (verbose) - printf (_("sent %s\n"), abuf); + if (verbose) { + printf(_("sent %s\n"), abuf); + } if ((ret = recvlines(buffer, MAX_INPUT_BUFFER)) <= 0) { result = STATE_CRITICAL; @@ -401,19 +402,19 @@ main (int argc, char **argv) break; } if (verbose) { - printf (_("received %s\n"), buffer); + printf(_("received %s\n"), buffer); } - if (strncmp (buffer, "334", 3) != 0) { + if (strncmp(buffer, "334", 3) != 0) { result = STATE_CRITICAL; xasprintf(&error_msg, _("invalid response received after authuser, ")); break; } /* encode authpass with base64 */ - base64_encode_alloc (authpass, strlen(authpass), &abuf); + base64_encode_alloc(authpass, strlen(authpass), &abuf); xasprintf(&abuf, "%s\r\n", abuf); my_send(abuf, strlen(abuf)); if (verbose) { - printf (_("sent %s\n"), abuf); + printf(_("sent %s\n"), abuf); } if ((ret = recvlines(buffer, MAX_INPUT_BUFFER)) <= 0) { result = STATE_CRITICAL; @@ -421,9 +422,9 @@ main (int argc, char **argv) break; } if (verbose) { - printf (_("received %s\n"), buffer); + printf(_("received %s\n"), buffer); } - if (strncmp (buffer, "235", 3) != 0) { + if (strncmp(buffer, "235", 3) != 0) { result = STATE_CRITICAL; xasprintf(&error_msg, _("invalid response received after authpass, ")); break; @@ -440,120 +441,112 @@ main (int argc, char **argv) smtp_quit(); /* finally close the connection */ - close (sd); + close(sd); } /* reset the alarm */ - alarm (0); + alarm(0); - microsec = deltime (tv); + microsec = deltime(tv); elapsed_time = (double)microsec / 1.0e6; if (result == STATE_OK) { - if (check_critical_time && elapsed_time > critical_time) + if (check_critical_time && elapsed_time > critical_time) { result = STATE_CRITICAL; - else if (check_warning_time && elapsed_time > warning_time) + } else if (check_warning_time && elapsed_time > warning_time) { result = STATE_WARNING; + } } - printf (_("SMTP %s - %s%.3f sec. response time%s%s|%s\n"), - state_text (result), - error_msg, - elapsed_time, - verbose?", ":"", verbose?buffer:"", - fperfdata ("time", elapsed_time, "s", - (int)check_warning_time, warning_time, - (int)check_critical_time, critical_time, - true, 0, false, 0)); + printf(_("SMTP %s - %s%.3f sec. response time%s%s|%s\n"), state_text(result), error_msg, elapsed_time, verbose ? ", " : "", + verbose ? buffer : "", + fperfdata("time", elapsed_time, "s", (int)check_warning_time, warning_time, (int)check_critical_time, critical_time, true, 0, + false, 0)); return result; } - - /* process command-line arguments */ -int -process_arguments (int argc, char **argv) -{ +int process_arguments(int argc, char **argv) { int c; - char* temp; + char *temp; bool implicit_tls = false; enum { - SNI_OPTION + SNI_OPTION }; int option = 0; - static struct option longopts[] = { - {"hostname", required_argument, 0, 'H'}, - {"expect", required_argument, 0, 'e'}, - {"critical", required_argument, 0, 'c'}, - {"warning", required_argument, 0, 'w'}, - {"timeout", required_argument, 0, 't'}, - {"port", required_argument, 0, 'p'}, - {"from", required_argument, 0, 'f'}, - {"fqdn", required_argument, 0, 'F'}, - {"authtype", required_argument, 0, 'A'}, - {"authuser", required_argument, 0, 'U'}, - {"authpass", required_argument, 0, 'P'}, - {"command", required_argument, 0, 'C'}, - {"response", required_argument, 0, 'R'}, - {"verbose", no_argument, 0, 'v'}, - {"version", no_argument, 0, 'V'}, - {"use-ipv4", no_argument, 0, '4'}, - {"use-ipv6", no_argument, 0, '6'}, - {"help", no_argument, 0, 'h'}, - {"lmtp", no_argument, 0, 'L'}, - {"ssl", no_argument, 0, 's'}, - {"tls", no_argument, 0, 's'}, - {"starttls",no_argument,0,'S'}, - {"sni", no_argument, 0, SNI_OPTION}, - {"certificate",required_argument,0,'D'}, - {"ignore-quit-failure",no_argument,0,'q'}, - {"proxy",no_argument,0,'r'}, - {0, 0, 0, 0} - }; - - if (argc < 2) + static struct option longopts[] = {{"hostname", required_argument, 0, 'H'}, + {"expect", required_argument, 0, 'e'}, + {"critical", required_argument, 0, 'c'}, + {"warning", required_argument, 0, 'w'}, + {"timeout", required_argument, 0, 't'}, + {"port", required_argument, 0, 'p'}, + {"from", required_argument, 0, 'f'}, + {"fqdn", required_argument, 0, 'F'}, + {"authtype", required_argument, 0, 'A'}, + {"authuser", required_argument, 0, 'U'}, + {"authpass", required_argument, 0, 'P'}, + {"command", required_argument, 0, 'C'}, + {"response", required_argument, 0, 'R'}, + {"verbose", no_argument, 0, 'v'}, + {"version", no_argument, 0, 'V'}, + {"use-ipv4", no_argument, 0, '4'}, + {"use-ipv6", no_argument, 0, '6'}, + {"help", no_argument, 0, 'h'}, + {"lmtp", no_argument, 0, 'L'}, + {"ssl", no_argument, 0, 's'}, + {"tls", no_argument, 0, 's'}, + {"starttls", no_argument, 0, 'S'}, + {"sni", no_argument, 0, SNI_OPTION}, + {"certificate", required_argument, 0, 'D'}, + {"ignore-quit-failure", no_argument, 0, 'q'}, + {"proxy", no_argument, 0, 'r'}, + {0, 0, 0, 0}}; + + if (argc < 2) { return ERROR; + } for (c = 1; c < argc; c++) { - if (strcmp ("-to", argv[c]) == 0) - strcpy (argv[c], "-t"); - else if (strcmp ("-wt", argv[c]) == 0) - strcpy (argv[c], "-w"); - else if (strcmp ("-ct", argv[c]) == 0) - strcpy (argv[c], "-c"); + if (strcmp("-to", argv[c]) == 0) { + strcpy(argv[c], "-t"); + } else if (strcmp("-wt", argv[c]) == 0) { + strcpy(argv[c], "-w"); + } else if (strcmp("-ct", argv[c]) == 0) { + strcpy(argv[c], "-c"); + } } while (1) { - c = getopt_long (argc, argv, "+hVv46Lrt:p:f:e:c:w:H:C:R:sSD:F:A:U:P:q", - longopts, &option); + c = getopt_long(argc, argv, "+hVv46Lrt:p:f:e:c:w:H:C:R:sSD:F:A:U:P:q", longopts, &option); - if (c == -1 || c == EOF) + if (c == -1 || c == EOF) { break; + } switch (c) { - case 'H': /* hostname */ - if (is_host (optarg)) { + case 'H': /* hostname */ + if (is_host(optarg)) { server_address = optarg; - } - else { - usage2 (_("Invalid hostname/address"), optarg); + } else { + usage2(_("Invalid hostname/address"), optarg); } break; - case 'p': /* port */ - if (is_intpos (optarg)) - server_port_option = atoi (optarg); - else - usage4 (_("Port must be a positive integer")); + case 'p': /* port */ + if (is_intpos(optarg)) { + server_port_option = atoi(optarg); + } else { + usage4(_("Port must be a positive integer")); + } break; case 'F': - /* localhostname */ + /* localhostname */ localhostname = strdup(optarg); break; - case 'f': /* from argument */ + case 'f': /* from argument */ from_arg = optarg + strspn(optarg, "<"); from_arg = strndup(from_arg, strcspn(from_arg, ">")); send_mail_from = 1; @@ -568,97 +561,98 @@ process_arguments (int argc, char **argv) case 'P': authpass = optarg; break; - case 'e': /* server expect string on 220 */ + case 'e': /* server expect string on 220 */ server_expect = optarg; break; - case 'C': /* commands */ + case 'C': /* commands */ if (ncommands >= command_size) { - command_size+=8; - commands = realloc (commands, sizeof(char *) * command_size); - if (commands == NULL) - die (STATE_UNKNOWN, - _("Could not realloc() units [%d]\n"), ncommands); + command_size += 8; + commands = realloc(commands, sizeof(char *) * command_size); + if (commands == NULL) { + die(STATE_UNKNOWN, _("Could not realloc() units [%d]\n"), ncommands); + } } - commands[ncommands] = (char *) malloc (sizeof(char) * 255); - strncpy (commands[ncommands], optarg, 255); + commands[ncommands] = (char *)malloc(sizeof(char) * 255); + strncpy(commands[ncommands], optarg, 255); ncommands++; break; - case 'R': /* server responses */ + case 'R': /* server responses */ if (nresponses >= response_size) { response_size += 8; - responses = realloc (responses, sizeof(char *) * response_size); - if (responses == NULL) - die (STATE_UNKNOWN, - _("Could not realloc() units [%d]\n"), nresponses); + responses = realloc(responses, sizeof(char *) * response_size); + if (responses == NULL) { + die(STATE_UNKNOWN, _("Could not realloc() units [%d]\n"), nresponses); + } } - responses[nresponses] = (char *) malloc (sizeof(char) * 255); - strncpy (responses[nresponses], optarg, 255); + responses[nresponses] = (char *)malloc(sizeof(char) * 255); + strncpy(responses[nresponses], optarg, 255); nresponses++; break; - case 'c': /* critical time threshold */ - if (!is_nonnegative (optarg)) - usage4 (_("Critical time must be a positive")); - else { - critical_time = strtod (optarg, NULL); + case 'c': /* critical time threshold */ + if (!is_nonnegative(optarg)) { + usage4(_("Critical time must be a positive")); + } else { + critical_time = strtod(optarg, NULL); check_critical_time = true; } break; - case 'w': /* warning time threshold */ - if (!is_nonnegative (optarg)) - usage4 (_("Warning time must be a positive")); - else { - warning_time = strtod (optarg, NULL); + case 'w': /* warning time threshold */ + if (!is_nonnegative(optarg)) { + usage4(_("Warning time must be a positive")); + } else { + warning_time = strtod(optarg, NULL); check_warning_time = true; } break; - case 'v': /* verbose */ + case 'v': /* verbose */ verbose++; break; case 'q': - ignore_send_quit_failure = true; /* ignore problem sending QUIT */ + ignore_send_quit_failure = true; /* ignore problem sending QUIT */ break; - case 't': /* timeout */ - if (is_intnonneg (optarg)) { - socket_timeout = atoi (optarg); - } - else { - usage4 (_("Timeout interval must be a positive integer")); + case 't': /* timeout */ + if (is_intnonneg(optarg)) { + socket_timeout = atoi(optarg); + } else { + usage4(_("Timeout interval must be a positive integer")); } break; case 'D': - /* Check SSL cert validity */ + /* Check SSL cert validity */ #ifdef USE_OPENSSL - if ((temp=strchr(optarg,','))!=NULL) { - *temp='\0'; - if (!is_intnonneg (optarg)) - usage2 ("Invalid certificate expiration period", optarg); - days_till_exp_warn = atoi(optarg); - *temp=','; - temp++; - if (!is_intnonneg (temp)) - usage2 (_("Invalid certificate expiration period"), temp); - days_till_exp_crit = atoi (temp); - } - else { - days_till_exp_crit=0; - if (!is_intnonneg (optarg)) - usage2 ("Invalid certificate expiration period", optarg); - days_till_exp_warn = atoi (optarg); - } + if ((temp = strchr(optarg, ',')) != NULL) { + *temp = '\0'; + if (!is_intnonneg(optarg)) { + usage2("Invalid certificate expiration period", optarg); + } + days_till_exp_warn = atoi(optarg); + *temp = ','; + temp++; + if (!is_intnonneg(temp)) { + usage2(_("Invalid certificate expiration period"), temp); + } + days_till_exp_crit = atoi(temp); + } else { + days_till_exp_crit = 0; + if (!is_intnonneg(optarg)) { + usage2("Invalid certificate expiration period", optarg); + } + days_till_exp_warn = atoi(optarg); + } check_cert = true; ignore_send_quit_failure = true; #else - usage (_("SSL support not available - install OpenSSL and recompile")); + usage(_("SSL support not available - install OpenSSL and recompile")); #endif implicit_tls = true; // fallthrough case 's': - /* ssl */ + /* ssl */ use_ssl = true; server_port = SMTPS_PORT; break; case 'S': - /* starttls */ + /* starttls */ use_starttls = true; use_ehlo = true; break; @@ -666,7 +660,7 @@ process_arguments (int argc, char **argv) #ifdef HAVE_SSL use_sni = true; #else - usage (_("SSL support not available - install OpenSSL and recompile")); + usage(_("SSL support not available - install OpenSSL and recompile")); #endif break; case 'r': @@ -682,48 +676,51 @@ process_arguments (int argc, char **argv) #ifdef USE_IPV6 address_family = AF_INET6; #else - usage4 (_("IPv6 support not available")); + usage4(_("IPv6 support not available")); #endif break; - case 'V': /* version */ - print_revision (progname, NP_VERSION); - exit (STATE_UNKNOWN); - case 'h': /* help */ - print_help (); - exit (STATE_UNKNOWN); - case '?': /* help */ - usage5 (); + case 'V': /* version */ + print_revision(progname, NP_VERSION); + exit(STATE_UNKNOWN); + case 'h': /* help */ + print_help(); + exit(STATE_UNKNOWN); + case '?': /* help */ + usage5(); } } c = optind; if (server_address == NULL) { if (argv[c]) { - if (is_host (argv[c])) + if (is_host(argv[c])) { server_address = argv[c]; - else - usage2 (_("Invalid hostname/address"), argv[c]); - } - else { - xasprintf (&server_address, "127.0.0.1"); + } else { + usage2(_("Invalid hostname/address"), argv[c]); + } + } else { + xasprintf(&server_address, "127.0.0.1"); } } - if (server_expect == NULL) - server_expect = strdup (SMTP_EXPECT); + if (server_expect == NULL) { + server_expect = strdup(SMTP_EXPECT); + } - if (mail_command == NULL) + if (mail_command == NULL) { mail_command = strdup("MAIL "); + } - if (from_arg==NULL) + if (from_arg == NULL) { from_arg = strdup(" "); + } if (use_starttls && use_ssl) { if (implicit_tls) { use_ssl = false; server_port = SMTP_PORT; } else { - usage4 (_("Set either -s/--ssl/--tls or -S/--starttls")); + usage4(_("Set either -s/--ssl/--tls or -S/--starttls")); } } @@ -731,54 +728,44 @@ process_arguments (int argc, char **argv) server_port = server_port_option; } - return validate_arguments (); -} - - - -int -validate_arguments (void) -{ - return OK; + return validate_arguments(); } +int validate_arguments(void) { return OK; } -void -smtp_quit(void) -{ +void smtp_quit(void) { int bytes; int n; n = my_send(SMTP_QUIT, strlen(SMTP_QUIT)); - if(n < 0) { - if(ignore_send_quit_failure) { - if(verbose) { + if (n < 0) { + if (ignore_send_quit_failure) { + if (verbose) { printf(_("Connection closed by server before sending QUIT command\n")); } return; } - die (STATE_UNKNOWN, - _("Connection closed by server before sending QUIT command\n")); + die(STATE_UNKNOWN, _("Connection closed by server before sending QUIT command\n")); } - if (verbose) + if (verbose) { printf(_("sent %s\n"), "QUIT"); + } /* read the response but don't care about problems */ bytes = recvlines(buffer, MAX_INPUT_BUFFER); if (verbose) { - if (bytes < 0) + if (bytes < 0) { printf(_("recv() failed after QUIT.")); - else if (bytes == 0) + } else if (bytes == 0) { printf(_("Connection reset by peer.")); - else { + } else { buffer[bytes] = '\0'; printf(_("received %s\n"), buffer); } } } - /* * Receive one line, copy it into buf and nul-terminate it. Returns the * number of bytes written to buf (excluding the '\0') or 0 on EOF or <0 on @@ -788,24 +775,22 @@ smtp_quit(void) * function which buffers the data, move that to netutils.c and change * check_smtp and other plugins to use that. Also, remove (\r)\n. */ -int -recvline(char *buf, size_t bufsize) -{ +int recvline(char *buf, size_t bufsize) { int result; unsigned i; for (i = result = 0; i < bufsize - 1; i++) { - if ((result = my_recv(&buf[i], 1)) != 1) + if ((result = my_recv(&buf[i], 1)) != 1) { break; + } if (buf[i] == '\n') { buf[++i] = '\0'; return i; } } - return (result == 1 || i == 0) ? -2 : result; /* -2 if out of space */ + return (result == 1 || i == 0) ? -2 : result; /* -2 if out of space */ } - /* * Receive one or more lines, copy them into buf and nul-terminate it. Returns * the number of bytes written to buf (excluding the '\0') or 0 on EOF or <0 on @@ -820,26 +805,20 @@ recvline(char *buf, size_t bufsize) * * TODO: Move this to netutils.c. Also, remove \r and possibly the final \n. */ -int -recvlines(char *buf, size_t bufsize) -{ +int recvlines(char *buf, size_t bufsize) { int result, i; - for (i = 0; /* forever */; i += result) - if (!((result = recvline(buf + i, bufsize - i)) > 3 && - isdigit((int)buf[i]) && - isdigit((int)buf[i + 1]) && - isdigit((int)buf[i + 2]) && - buf[i + 3] == '-')) + for (i = 0; /* forever */; i += result) { + if (!((result = recvline(buf + i, bufsize - i)) > 3 && isdigit((int)buf[i]) && isdigit((int)buf[i + 1]) && + isdigit((int)buf[i + 2]) && buf[i + 3] == '-')) { break; + } + } return (result <= 0) ? result : result + i; } - -int -my_close (void) -{ +int my_close(void) { int result; result = close(sd); #ifdef HAVE_SSL @@ -848,89 +827,80 @@ my_close (void) return result; } - -void -print_help (void) -{ +void print_help(void) { char *myport; - xasprintf (&myport, "%d", SMTP_PORT); + xasprintf(&myport, "%d", SMTP_PORT); - print_revision (progname, NP_VERSION); + print_revision(progname, NP_VERSION); - printf ("Copyright (c) 1999-2001 Ethan Galstad \n"); - printf (COPYRIGHT, copyright, email); + printf("Copyright (c) 1999-2001 Ethan Galstad \n"); + printf(COPYRIGHT, copyright, email); printf("%s\n", _("This plugin will attempt to open an SMTP connection with the host.")); - printf ("\n\n"); + printf("\n\n"); - print_usage (); + print_usage(); - printf (UT_HELP_VRSN); - printf (UT_EXTRA_OPTS); + printf(UT_HELP_VRSN); + printf(UT_EXTRA_OPTS); - printf (UT_HOST_PORT, 'p', myport); + printf(UT_HOST_PORT, 'p', myport); - printf (UT_IPv46); + printf(UT_IPv46); - printf (" %s\n", "-e, --expect=STRING"); - printf (_(" String to expect in first line of server response (default: '%s')\n"), SMTP_EXPECT); - printf (" %s\n", "-C, --command=STRING"); - printf (" %s\n", _("SMTP command (may be used repeatedly)")); - printf (" %s\n", "-R, --response=STRING"); - printf (" %s\n", _("Expected response to command (may be used repeatedly)")); - printf (" %s\n", "-f, --from=STRING"); - printf (" %s\n", _("FROM-address to include in MAIL command, required by Exchange 2000")), - printf (" %s\n", "-F, --fqdn=STRING"); - printf (" %s\n", _("FQDN used for HELO")); - printf (" %s\n", "-r, --proxy"); - printf (" %s\n", _("Use PROXY protocol prefix for the connection.")); + printf(" %s\n", "-e, --expect=STRING"); + printf(_(" String to expect in first line of server response (default: '%s')\n"), SMTP_EXPECT); + printf(" %s\n", "-C, --command=STRING"); + printf(" %s\n", _("SMTP command (may be used repeatedly)")); + printf(" %s\n", "-R, --response=STRING"); + printf(" %s\n", _("Expected response to command (may be used repeatedly)")); + printf(" %s\n", "-f, --from=STRING"); + printf(" %s\n", _("FROM-address to include in MAIL command, required by Exchange 2000")), printf(" %s\n", "-F, --fqdn=STRING"); + printf(" %s\n", _("FQDN used for HELO")); + printf(" %s\n", "-r, --proxy"); + printf(" %s\n", _("Use PROXY protocol prefix for the connection.")); #ifdef HAVE_SSL - printf (" %s\n", "-D, --certificate=INTEGER[,INTEGER]"); - printf (" %s\n", _("Minimum number of days a certificate has to be valid.")); - printf (" %s\n", "-s, --ssl, --tls"); - printf (" %s\n", _("Use SSL/TLS for the connection.")); - printf (_(" Sets default port to %d.\n"), SMTPS_PORT); - printf (" %s\n", "-S, --starttls"); - printf (" %s\n", _("Use STARTTLS for the connection.")); - printf (" %s\n", "--sni"); - printf (" %s\n", _("Enable SSL/TLS hostname extension support (SNI)")); + printf(" %s\n", "-D, --certificate=INTEGER[,INTEGER]"); + printf(" %s\n", _("Minimum number of days a certificate has to be valid.")); + printf(" %s\n", "-s, --ssl, --tls"); + printf(" %s\n", _("Use SSL/TLS for the connection.")); + printf(_(" Sets default port to %d.\n"), SMTPS_PORT); + printf(" %s\n", "-S, --starttls"); + printf(" %s\n", _("Use STARTTLS for the connection.")); + printf(" %s\n", "--sni"); + printf(" %s\n", _("Enable SSL/TLS hostname extension support (SNI)")); #endif - printf (" %s\n", "-A, --authtype=STRING"); - printf (" %s\n", _("SMTP AUTH type to check (default none, only LOGIN supported)")); - printf (" %s\n", "-U, --authuser=STRING"); - printf (" %s\n", _("SMTP AUTH username")); - printf (" %s\n", "-P, --authpass=STRING"); - printf (" %s\n", _("SMTP AUTH password")); - printf (" %s\n", "-L, --lmtp"); - printf (" %s\n", _("Send LHLO instead of HELO/EHLO")); - printf (" %s\n", "-q, --ignore-quit-failure"); - printf (" %s\n", _("Ignore failure when sending QUIT command to server")); - - printf (UT_WARN_CRIT); + printf(" %s\n", "-A, --authtype=STRING"); + printf(" %s\n", _("SMTP AUTH type to check (default none, only LOGIN supported)")); + printf(" %s\n", "-U, --authuser=STRING"); + printf(" %s\n", _("SMTP AUTH username")); + printf(" %s\n", "-P, --authpass=STRING"); + printf(" %s\n", _("SMTP AUTH password")); + printf(" %s\n", "-L, --lmtp"); + printf(" %s\n", _("Send LHLO instead of HELO/EHLO")); + printf(" %s\n", "-q, --ignore-quit-failure"); + printf(" %s\n", _("Ignore failure when sending QUIT command to server")); + + printf(UT_WARN_CRIT); - printf (UT_CONN_TIMEOUT, DEFAULT_SOCKET_TIMEOUT); + printf(UT_CONN_TIMEOUT, DEFAULT_SOCKET_TIMEOUT); - printf (UT_VERBOSE); + printf(UT_VERBOSE); printf("\n"); - printf ("%s\n", _("Successful connects return STATE_OK, refusals and timeouts return")); - printf ("%s\n", _("STATE_CRITICAL, other errors return STATE_UNKNOWN. Successful")); - printf ("%s\n", _("connects, but incorrect response messages from the host result in")); - printf ("%s\n", _("STATE_WARNING return values.")); + printf("%s\n", _("Successful connects return STATE_OK, refusals and timeouts return")); + printf("%s\n", _("STATE_CRITICAL, other errors return STATE_UNKNOWN. Successful")); + printf("%s\n", _("connects, but incorrect response messages from the host result in")); + printf("%s\n", _("STATE_WARNING return values.")); - printf (UT_SUPPORT); + printf(UT_SUPPORT); } - - -void -print_usage (void) -{ - printf ("%s\n", _("Usage:")); - printf ("%s -H host [-p port] [-4|-6] [-e expect] [-C command] [-R response] [-f from addr]\n", progname); - printf ("[-A authtype -U authuser -P authpass] [-w warn] [-c crit] [-t timeout] [-q]\n"); - printf ("[-F fqdn] [-S] [-L] [-D warn days cert expire[,crit days cert expire]] [-r] [--sni] [-v] \n"); +void print_usage(void) { + printf("%s\n", _("Usage:")); + printf("%s -H host [-p port] [-4|-6] [-e expect] [-C command] [-R response] [-f from addr]\n", progname); + printf("[-A authtype -U authuser -P authpass] [-w warn] [-c crit] [-t timeout] [-q]\n"); + printf("[-F fqdn] [-S] [-L] [-D warn days cert expire[,crit days cert expire]] [-r] [--sni] [-v] \n"); } - -- cgit v1.2.3-74-g34f1 From 883fcb607f9b3e810e22b2e21da7441a073b6e32 Mon Sep 17 00:00:00 2001 From: Lorenz Kästle <12514511+RincewindsHat@users.noreply.github.com> Date: Mon, 10 Mar 2025 01:31:52 +0100 Subject: Refactor check_smtp --- plugins/Makefile.am | 3 +- plugins/check_smtp.c | 518 ++++++++++++++++++++---------------------- plugins/check_smtp.d/config.h | 92 ++++++++ 3 files changed, 343 insertions(+), 270 deletions(-) create mode 100644 plugins/check_smtp.d/config.h diff --git a/plugins/Makefile.am b/plugins/Makefile.am index 6ee93c18..5e8f0650 100644 --- a/plugins/Makefile.am +++ b/plugins/Makefile.am @@ -52,7 +52,8 @@ EXTRA_DIST = t \ check_swap.d \ check_dbi.d \ check_ssh.d \ - check_dns.d + check_dns.d \ + check_smtp.d PLUGINHDRS = common.h diff --git a/plugins/check_smtp.c b/plugins/check_smtp.c index bb45e01b..0be02937 100644 --- a/plugins/check_smtp.c +++ b/plugins/check_smtp.c @@ -28,6 +28,7 @@ * *****************************************************************************/ +#include "states.h" const char *progname = "check_smtp"; const char *copyright = "2000-2024"; const char *email = "devel@monitoring-plugins.org"; @@ -36,21 +37,12 @@ const char *email = "devel@monitoring-plugins.org"; #include "netutils.h" #include "utils.h" #include "base64.h" +#include "regex.h" #include - -#ifdef HAVE_SSL -static bool check_cert = false; -static int days_till_exp_warn, days_till_exp_crit; -# define my_recv(buf, len) (((use_starttls || use_ssl) && ssl_established) ? np_net_ssl_read(buf, len) : read(sd, buf, len)) -# define my_send(buf, len) (((use_starttls || use_ssl) && ssl_established) ? np_net_ssl_write(buf, len) : send(sd, buf, len, 0)) -#else /* ifndef HAVE_SSL */ -# define my_recv(buf, len) read(sd, buf, len) -# define my_send(buf, len) send(sd, buf, len, 0) -#endif +#include "check_smtp.d/config.h" #define PROXY_PREFIX "PROXY TCP4 0.0.0.0 0.0.0.0 25 25\r\n" -#define SMTP_EXPECT "220" #define SMTP_HELO "HELO " #define SMTP_EHLO "EHLO " #define SMTP_LHLO "LHLO " @@ -60,71 +52,51 @@ static int days_till_exp_warn, days_till_exp_crit; #define EHLO_SUPPORTS_STARTTLS 1 -static int process_arguments (int, char **); -static int validate_arguments (void); -static void print_help (void); -void print_usage (void); -static void smtp_quit(void); -static int recvline(char *, size_t); -static int recvlines(char *, size_t); -static int my_close(void); +typedef struct { + int errorcode; + check_smtp_config config; +} check_smtp_config_wrapper; +static check_smtp_config_wrapper process_arguments(int /*argc*/, char ** /*argv*/); + +int my_recv(check_smtp_config config, void *buf, int num, int socket_descriptor, bool ssl_established) { +#ifdef HAVE_SSL + if ((config.use_starttls || config.use_ssl) && ssl_established) { + return np_net_ssl_read(buf, num); + } + return (int)read(socket_descriptor, buf, (size_t)num); +#else /* ifndef HAVE_SSL */ + return read(socket_descriptor, buf, len) +#endif +} + +int my_send(check_smtp_config config, void *buf, int num, int socket_descriptor, bool ssl_established) { +#ifdef HAVE_SSL + if ((config.use_starttls || config.use_ssl) && ssl_established) { + + return np_net_ssl_write(buf, num); + } + return (int)send(socket_descriptor, buf, (size_t)num, 0); +#else /* ifndef HAVE_SSL */ + return send(socket_descriptor, buf, len, 0); +#endif +} + +static void print_help(void); +void print_usage(void); +static char *smtp_quit(check_smtp_config /*config*/, char /*buffer*/[MAX_INPUT_BUFFER], int /*socket_descriptor*/, + bool /*ssl_established*/); +static int recvline(char * /*buf*/, size_t /*bufsize*/, check_smtp_config /*config*/, int /*socket_descriptor*/, bool /*ssl_established*/); +static int recvlines(check_smtp_config /*config*/, char * /*buf*/, size_t /*bufsize*/, int /*socket_descriptor*/, bool /*ssl_established*/); +static int my_close(int /*socket_descriptor*/); -#include "regex.h" -static regex_t preg; -static regmatch_t pmatch[10]; -static char errbuf[MAX_INPUT_BUFFER]; -static int cflags = REG_EXTENDED | REG_NOSUB | REG_NEWLINE; -static int eflags = 0; -static int errcode, excode; - -static int server_port_option = 0; -static char *server_address = NULL; -static char *server_expect = NULL; -static char *mail_command = NULL; -static char *from_arg = NULL; -static int send_mail_from = 0; -static int ncommands = 0; -static int command_size = 0; -static int nresponses = 0; -static int response_size = 0; -static char **commands = NULL; -static char **responses = NULL; -static char *authtype = NULL; -static char *authuser = NULL; -static char *authpass = NULL; -static double warning_time = 0; -static bool check_warning_time = false; -static double critical_time = 0; -static bool check_critical_time = false; static int verbose = 0; -static bool use_ssl = false; -static bool use_starttls = false; -static bool use_sni = false; -static bool use_proxy_prefix = false; -static bool use_ehlo = false; -static bool use_lhlo = false; -static bool ssl_established = false; -static char *localhostname = NULL; -static int sd; -static char buffer[MAX_INPUT_BUFFER]; + enum { TCP_PROTOCOL = 1, UDP_PROTOCOL = 2, }; -static bool ignore_send_quit_failure = false; int main(int argc, char **argv) { - bool supports_tls = false; - int n = 0; - double elapsed_time; - long microsec; - int result = STATE_UNKNOWN; - char *cmd_str = NULL; - char *helocmd = NULL; - char *error_msg = ""; - char *server_response = NULL; - struct timeval tv; - /* Catch pipe errors in read/write - sometimes occurs when writing QUIT */ (void)signal(SIGPIPE, SIG_IGN); @@ -135,25 +107,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_smtp_config_wrapper tmp_config = process_arguments(argc, argv); + + if (tmp_config.errorcode == ERROR) { usage4(_("Could not parse arguments")); } + const check_smtp_config config = tmp_config.config; + /* If localhostname not set on command line, use gethostname to set */ + char *localhostname = config.localhostname; if (!localhostname) { localhostname = malloc(HOST_MAX_BYTES); if (!localhostname) { printf(_("malloc() failed!\n")); - return STATE_CRITICAL; + exit(STATE_CRITICAL); } if (gethostname(localhostname, HOST_MAX_BYTES)) { printf(_("gethostname() failed!\n")); - return STATE_CRITICAL; + exit(STATE_CRITICAL); } } - if (use_lhlo) { + char *helocmd = NULL; + if (config.use_lhlo) { xasprintf(&helocmd, "%s%s%s", SMTP_LHLO, localhostname, "\r\n"); - } else if (use_ehlo) { + } else if (config.use_ehlo) { xasprintf(&helocmd, "%s%s%s", SMTP_EHLO, localhostname, "\r\n"); } else { xasprintf(&helocmd, "%s%s%s", SMTP_HELO, localhostname, "\r\n"); @@ -163,10 +141,13 @@ int main(int argc, char **argv) { printf("HELOCMD: %s", helocmd); } + char *mail_command = strdup("MAIL "); + + char *cmd_str = NULL; /* initialize the MAIL command with optional FROM command */ - xasprintf(&cmd_str, "%sFROM:<%s>%s", mail_command, from_arg, "\r\n"); + xasprintf(&cmd_str, "%sFROM:<%s>%s", mail_command, config.from_arg, "\r\n"); - if (verbose && send_mail_from) { + if (verbose && config.send_mail_from) { printf("FROM CMD: %s", cmd_str); } @@ -176,84 +157,90 @@ int main(int argc, char **argv) { /* set socket timeout */ (void)alarm(socket_timeout); + struct timeval start_time; /* start timer */ - gettimeofday(&tv, NULL); + gettimeofday(&start_time, NULL); + int socket_descriptor = 0; /* try to connect to the host at the given port number */ - result = my_tcp_connect(server_address, server_port, &sd); + mp_state_enum result = my_tcp_connect(config.server_address, config.server_port, &socket_descriptor); + char *error_msg = ""; + char buffer[MAX_INPUT_BUFFER]; + bool ssl_established = false; if (result == STATE_OK) { /* we connected */ /* If requested, send PROXY header */ - if (use_proxy_prefix) { + if (config.use_proxy_prefix) { if (verbose) { printf("Sending header %s\n", PROXY_PREFIX); } - my_send(PROXY_PREFIX, strlen(PROXY_PREFIX)); + my_send(config, PROXY_PREFIX, strlen(PROXY_PREFIX), socket_descriptor, ssl_established); } #ifdef HAVE_SSL - if (use_ssl) { - result = np_net_ssl_init_with_hostname(sd, (use_sni ? server_address : NULL)); + if (config.use_ssl) { + result = np_net_ssl_init_with_hostname(socket_descriptor, (config.use_sni ? config.server_address : NULL)); if (result != STATE_OK) { printf(_("CRITICAL - Cannot create SSL context.\n")); - close(sd); + close(socket_descriptor); np_net_ssl_cleanup(); - return STATE_CRITICAL; - } else { - ssl_established = 1; + exit(STATE_CRITICAL); } + ssl_established = true; } #endif /* watch for the SMTP connection string and */ /* return a WARNING status if we couldn't read any data */ - if (recvlines(buffer, MAX_INPUT_BUFFER) <= 0) { + if (recvlines(config, buffer, MAX_INPUT_BUFFER, socket_descriptor, ssl_established) <= 0) { printf(_("recv() failed\n")); - return STATE_WARNING; + exit(STATE_WARNING); } + char *server_response = NULL; /* save connect return (220 hostname ..) for later use */ xasprintf(&server_response, "%s", buffer); /* send the HELO/EHLO command */ - my_send(helocmd, strlen(helocmd)); + my_send(config, helocmd, (int)strlen(helocmd), socket_descriptor, ssl_established); /* allow for response to helo command to reach us */ - if (recvlines(buffer, MAX_INPUT_BUFFER) <= 0) { + if (recvlines(config, buffer, MAX_INPUT_BUFFER, socket_descriptor, ssl_established) <= 0) { printf(_("recv() failed\n")); - return STATE_WARNING; - } else if (use_ehlo || use_lhlo) { + exit(STATE_WARNING); + } + bool supports_tls = false; + if (config.use_ehlo || config.use_lhlo) { if (strstr(buffer, "250 STARTTLS") != NULL || strstr(buffer, "250-STARTTLS") != NULL) { supports_tls = true; } } - if (use_starttls && !supports_tls) { + if (config.use_starttls && !supports_tls) { printf(_("WARNING - TLS not supported by server\n")); - smtp_quit(); - return STATE_WARNING; + smtp_quit(config, buffer, socket_descriptor, ssl_established); + exit(STATE_WARNING); } #ifdef HAVE_SSL - if (use_starttls) { + if (config.use_starttls) { /* send the STARTTLS command */ - send(sd, SMTP_STARTTLS, strlen(SMTP_STARTTLS), 0); + send(socket_descriptor, SMTP_STARTTLS, strlen(SMTP_STARTTLS), 0); - recvlines(buffer, MAX_INPUT_BUFFER); /* wait for it */ + recvlines(config, buffer, MAX_INPUT_BUFFER, socket_descriptor, ssl_established); /* wait for it */ if (!strstr(buffer, SMTP_EXPECT)) { printf(_("Server does not support STARTTLS\n")); - smtp_quit(); - return STATE_UNKNOWN; + smtp_quit(config, buffer, socket_descriptor, ssl_established); + exit(STATE_UNKNOWN); } - result = np_net_ssl_init_with_hostname(sd, (use_sni ? server_address : NULL)); + result = np_net_ssl_init_with_hostname(socket_descriptor, (config.use_sni ? config.server_address : NULL)); if (result != STATE_OK) { printf(_("CRITICAL - Cannot create SSL context.\n")); - close(sd); + close(socket_descriptor); np_net_ssl_cleanup(); - return STATE_CRITICAL; - } else { - ssl_established = 1; + exit(STATE_CRITICAL); } + ssl_established = true; /* * Resend the EHLO command. @@ -266,29 +253,32 @@ int main(int argc, char **argv) { * reason, some MTAs will not allow an AUTH LOGIN command before * we resent EHLO via TLS. */ - if (my_send(helocmd, strlen(helocmd)) <= 0) { + if (my_send(config, helocmd, strlen(helocmd), socket_descriptor, ssl_established) <= 0) { printf("%s\n", _("SMTP UNKNOWN - Cannot send EHLO command via TLS.")); - my_close(); - return STATE_UNKNOWN; + my_close(socket_descriptor); + exit(STATE_UNKNOWN); } + if (verbose) { printf(_("sent %s"), helocmd); } - if ((n = recvlines(buffer, MAX_INPUT_BUFFER)) <= 0) { + + if (recvlines(config, buffer, MAX_INPUT_BUFFER, socket_descriptor, ssl_established) <= 0) { printf("%s\n", _("SMTP UNKNOWN - Cannot read EHLO response via TLS.")); - my_close(); - return STATE_UNKNOWN; + my_close(socket_descriptor); + exit(STATE_UNKNOWN); } + if (verbose) { printf("%s", buffer); } # ifdef USE_OPENSSL - if (check_cert) { - result = np_net_ssl_check_cert(days_till_exp_warn, days_till_exp_crit); - smtp_quit(); - my_close(); - return result; + if (config.check_cert) { + result = np_net_ssl_check_cert(config.days_till_exp_warn, config.days_till_exp_crit); + smtp_quit(config, buffer, socket_descriptor, ssl_established); + my_close(socket_descriptor); + exit(result); } # endif /* USE_OPENSSL */ } @@ -304,76 +294,81 @@ int main(int argc, char **argv) { strip(server_response); /* make sure we find the droids we are looking for */ - if (!strstr(server_response, server_expect)) { - if (server_port == SMTP_PORT) { + if (!strstr(server_response, config.server_expect)) { + if (config.server_port == SMTP_PORT) { printf(_("Invalid SMTP response received from host: %s\n"), server_response); } else { - printf(_("Invalid SMTP response received from host on port %d: %s\n"), server_port, server_response); + printf(_("Invalid SMTP response received from host on port %d: %s\n"), config.server_port, server_response); } - return STATE_WARNING; + exit(STATE_WARNING); } - if (send_mail_from) { - my_send(cmd_str, strlen(cmd_str)); - if (recvlines(buffer, MAX_INPUT_BUFFER) >= 1 && verbose) { + if (config.send_mail_from) { + my_send(config, cmd_str, (int)strlen(cmd_str), socket_descriptor, ssl_established); + if (recvlines(config, buffer, MAX_INPUT_BUFFER, socket_descriptor, ssl_established) >= 1 && verbose) { printf("%s", buffer); } } - n = 0; - while (n < ncommands) { - xasprintf(&cmd_str, "%s%s", commands[n], "\r\n"); - my_send(cmd_str, strlen(cmd_str)); - if (recvlines(buffer, MAX_INPUT_BUFFER) >= 1 && verbose) { + int counter = 0; + while (counter < config.ncommands) { + xasprintf(&cmd_str, "%s%s", config.commands[counter], "\r\n"); + my_send(config, cmd_str, (int)strlen(cmd_str), socket_descriptor, ssl_established); + if (recvlines(config, buffer, MAX_INPUT_BUFFER, socket_descriptor, ssl_established) >= 1 && verbose) { printf("%s", buffer); } strip(buffer); - if (n < nresponses) { - cflags |= REG_EXTENDED | REG_NOSUB | REG_NEWLINE; - errcode = regcomp(&preg, responses[n], cflags); + if (counter < config.nresponses) { + int cflags = REG_EXTENDED | REG_NOSUB | REG_NEWLINE; + regex_t preg; + int errcode = regcomp(&preg, config.responses[counter], cflags); + char errbuf[MAX_INPUT_BUFFER]; if (errcode != 0) { regerror(errcode, &preg, errbuf, MAX_INPUT_BUFFER); printf(_("Could Not Compile Regular Expression")); - return ERROR; + exit(STATE_UNKNOWN); } - excode = regexec(&preg, buffer, 10, pmatch, eflags); + + regmatch_t pmatch[10]; + int eflags = 0; + int excode = regexec(&preg, buffer, 10, pmatch, eflags); if (excode == 0) { result = STATE_OK; } else if (excode == REG_NOMATCH) { result = STATE_WARNING; - printf(_("SMTP %s - Invalid response '%s' to command '%s'\n"), state_text(result), buffer, commands[n]); + printf(_("SMTP %s - Invalid response '%s' to command '%s'\n"), state_text(result), buffer, config.commands[counter]); } else { regerror(excode, &preg, errbuf, MAX_INPUT_BUFFER); printf(_("Execute Error: %s\n"), errbuf); result = STATE_UNKNOWN; } } - n++; + counter++; } - if (authtype != NULL) { - if (strcmp(authtype, "LOGIN") == 0) { + if (config.authtype != NULL) { + if (strcmp(config.authtype, "LOGIN") == 0) { char *abuf; int ret; do { - if (authuser == NULL) { + if (config.authuser == NULL) { result = STATE_CRITICAL; xasprintf(&error_msg, _("no authuser specified, ")); break; } - if (authpass == NULL) { + if (config.authpass == NULL) { result = STATE_CRITICAL; xasprintf(&error_msg, _("no authpass specified, ")); break; } /* send AUTH LOGIN */ - my_send(SMTP_AUTH_LOGIN, strlen(SMTP_AUTH_LOGIN)); + my_send(config, SMTP_AUTH_LOGIN, strlen(SMTP_AUTH_LOGIN), socket_descriptor, ssl_established); if (verbose) { printf(_("sent %s\n"), "AUTH LOGIN"); } - if ((ret = recvlines(buffer, MAX_INPUT_BUFFER)) <= 0) { + if ((ret = recvlines(config, buffer, MAX_INPUT_BUFFER, socket_descriptor, ssl_established)) <= 0) { xasprintf(&error_msg, _("recv() failed after AUTH LOGIN, ")); result = STATE_WARNING; break; @@ -389,14 +384,14 @@ int main(int argc, char **argv) { } /* encode authuser with base64 */ - base64_encode_alloc(authuser, strlen(authuser), &abuf); + base64_encode_alloc(config.authuser, strlen(config.authuser), &abuf); xasprintf(&abuf, "%s\r\n", abuf); - my_send(abuf, strlen(abuf)); + my_send(config, abuf, (int)strlen(abuf), socket_descriptor, ssl_established); if (verbose) { printf(_("sent %s\n"), abuf); } - if ((ret = recvlines(buffer, MAX_INPUT_BUFFER)) <= 0) { + if ((ret = recvlines(config, buffer, MAX_INPUT_BUFFER, socket_descriptor, ssl_established)) <= 0) { result = STATE_CRITICAL; xasprintf(&error_msg, _("recv() failed after sending authuser, ")); break; @@ -410,13 +405,13 @@ int main(int argc, char **argv) { break; } /* encode authpass with base64 */ - base64_encode_alloc(authpass, strlen(authpass), &abuf); + base64_encode_alloc(config.authpass, strlen(config.authpass), &abuf); xasprintf(&abuf, "%s\r\n", abuf); - my_send(abuf, strlen(abuf)); + my_send(config, abuf, (int)strlen(abuf), socket_descriptor, ssl_established); if (verbose) { printf(_("sent %s\n"), abuf); } - if ((ret = recvlines(buffer, MAX_INPUT_BUFFER)) <= 0) { + if ((ret = recvlines(config, buffer, MAX_INPUT_BUFFER, socket_descriptor, ssl_established)) <= 0) { result = STATE_CRITICAL; xasprintf(&error_msg, _("recv() failed after sending authpass, ")); break; @@ -438,41 +433,36 @@ int main(int argc, char **argv) { } /* tell the server we're done */ - smtp_quit(); + smtp_quit(config, buffer, socket_descriptor, ssl_established); /* finally close the connection */ - close(sd); + close(socket_descriptor); } /* reset the alarm */ alarm(0); - microsec = deltime(tv); - elapsed_time = (double)microsec / 1.0e6; + long microsec = deltime(start_time); + double elapsed_time = (double)microsec / 1.0e6; if (result == STATE_OK) { - if (check_critical_time && elapsed_time > critical_time) { + if (config.check_critical_time && elapsed_time > config.critical_time) { result = STATE_CRITICAL; - } else if (check_warning_time && elapsed_time > warning_time) { + } else if (config.check_warning_time && elapsed_time > config.warning_time) { result = STATE_WARNING; } } printf(_("SMTP %s - %s%.3f sec. response time%s%s|%s\n"), state_text(result), error_msg, elapsed_time, verbose ? ", " : "", verbose ? buffer : "", - fperfdata("time", elapsed_time, "s", (int)check_warning_time, warning_time, (int)check_critical_time, critical_time, true, 0, - false, 0)); + fperfdata("time", elapsed_time, "s", config.check_warning_time, config.warning_time, config.check_critical_time, + config.critical_time, true, 0, false, 0)); - return result; + exit(result); } /* process command-line arguments */ -int process_arguments(int argc, char **argv) { - int c; - char *temp; - - bool implicit_tls = false; - +check_smtp_config_wrapper process_arguments(int argc, char **argv) { enum { SNI_OPTION }; @@ -506,109 +496,118 @@ int process_arguments(int argc, char **argv) { {"proxy", no_argument, 0, 'r'}, {0, 0, 0, 0}}; + check_smtp_config_wrapper result = { + .config = check_smtp_config_init(), + .errorcode = OK, + }; + if (argc < 2) { - return ERROR; + result.errorcode = ERROR; + return result; } - for (c = 1; c < argc; c++) { - if (strcmp("-to", argv[c]) == 0) { - strcpy(argv[c], "-t"); - } else if (strcmp("-wt", argv[c]) == 0) { - strcpy(argv[c], "-w"); - } else if (strcmp("-ct", argv[c]) == 0) { - strcpy(argv[c], "-c"); + for (int index = 1; index < argc; index++) { + if (strcmp("-to", argv[index]) == 0) { + strcpy(argv[index], "-t"); + } else if (strcmp("-wt", argv[index]) == 0) { + strcpy(argv[index], "-w"); + } else if (strcmp("-ct", argv[index]) == 0) { + strcpy(argv[index], "-c"); } } - while (1) { - c = getopt_long(argc, argv, "+hVv46Lrt:p:f:e:c:w:H:C:R:sSD:F:A:U:P:q", longopts, &option); + int command_size = 0; + int response_size = 0; + bool implicit_tls = false; + while (true) { + int opt_index = getopt_long(argc, argv, "+hVv46Lrt:p:f:e:c:w:H:C:R:sSD:F:A:U:P:q", longopts, &option); - if (c == -1 || c == EOF) { + if (opt_index == -1 || opt_index == EOF) { break; } - switch (c) { + switch (opt_index) { case 'H': /* hostname */ if (is_host(optarg)) { - server_address = optarg; + result.config.server_address = optarg; } else { usage2(_("Invalid hostname/address"), optarg); } break; case 'p': /* port */ if (is_intpos(optarg)) { - server_port_option = atoi(optarg); + result.config.server_port = atoi(optarg); } else { usage4(_("Port must be a positive integer")); } break; case 'F': /* localhostname */ - localhostname = strdup(optarg); + result.config.localhostname = strdup(optarg); break; case 'f': /* from argument */ - from_arg = optarg + strspn(optarg, "<"); - from_arg = strndup(from_arg, strcspn(from_arg, ">")); - send_mail_from = 1; + result.config.from_arg = optarg + strspn(optarg, "<"); + result.config.from_arg = strndup(result.config.from_arg, strcspn(result.config.from_arg, ">")); + result.config.send_mail_from = true; break; case 'A': - authtype = optarg; - use_ehlo = true; + result.config.authtype = optarg; + result.config.use_ehlo = true; break; case 'U': - authuser = optarg; + result.config.authuser = optarg; break; case 'P': - authpass = optarg; + result.config.authpass = optarg; break; case 'e': /* server expect string on 220 */ - server_expect = optarg; + result.config.server_expect = optarg; break; case 'C': /* commands */ - if (ncommands >= command_size) { + if (result.config.ncommands >= command_size) { command_size += 8; - commands = realloc(commands, sizeof(char *) * command_size); - if (commands == NULL) { - die(STATE_UNKNOWN, _("Could not realloc() units [%d]\n"), ncommands); + result.config.commands = realloc(result.config.commands, sizeof(char *) * command_size); + if (result.config.commands == NULL) { + die(STATE_UNKNOWN, _("Could not realloc() units [%d]\n"), result.config.ncommands); } } - commands[ncommands] = (char *)malloc(sizeof(char) * 255); - strncpy(commands[ncommands], optarg, 255); - ncommands++; + result.config.commands[result.config.ncommands] = (char *)malloc(sizeof(char) * 255); + strncpy(result.config.commands[result.config.ncommands], optarg, 255); + result.config.ncommands++; break; case 'R': /* server responses */ - if (nresponses >= response_size) { + if (result.config.nresponses >= response_size) { response_size += 8; - responses = realloc(responses, sizeof(char *) * response_size); - if (responses == NULL) { - die(STATE_UNKNOWN, _("Could not realloc() units [%d]\n"), nresponses); + result.config.responses = realloc(result.config.responses, sizeof(char *) * response_size); + if (result.config.responses == NULL) { + die(STATE_UNKNOWN, _("Could not realloc() units [%d]\n"), result.config.nresponses); } } - responses[nresponses] = (char *)malloc(sizeof(char) * 255); - strncpy(responses[nresponses], optarg, 255); - nresponses++; + result.config.responses[result.config.nresponses] = (char *)malloc(sizeof(char) * 255); + strncpy(result.config.responses[result.config.nresponses], optarg, 255); + result.config.nresponses++; break; case 'c': /* critical time threshold */ if (!is_nonnegative(optarg)) { usage4(_("Critical time must be a positive")); } else { - critical_time = strtod(optarg, NULL); - check_critical_time = true; + result.config.critical_time = strtod(optarg, NULL); + result.config.check_critical_time = true; } break; case 'w': /* warning time threshold */ if (!is_nonnegative(optarg)) { usage4(_("Warning time must be a positive")); } else { - warning_time = strtod(optarg, NULL); - check_warning_time = true; + result.config.warning_time = strtod(optarg, NULL); + result.config.check_warning_time = true; } break; case 'v': /* verbose */ verbose++; break; case 'q': - ignore_send_quit_failure = true; /* ignore problem sending QUIT */ + result.config.ignore_send_quit_failure = true; /* ignore problem sending QUIT */ break; case 't': /* timeout */ if (is_intnonneg(optarg)) { @@ -617,30 +616,31 @@ int process_arguments(int argc, char **argv) { usage4(_("Timeout interval must be a positive integer")); } break; - case 'D': + case 'D': { /* Check SSL cert validity */ #ifdef USE_OPENSSL + char *temp; if ((temp = strchr(optarg, ',')) != NULL) { *temp = '\0'; if (!is_intnonneg(optarg)) { usage2("Invalid certificate expiration period", optarg); } - days_till_exp_warn = atoi(optarg); + result.config.days_till_exp_warn = atoi(optarg); *temp = ','; temp++; if (!is_intnonneg(temp)) { usage2(_("Invalid certificate expiration period"), temp); } - days_till_exp_crit = atoi(temp); + result.config.days_till_exp_crit = atoi(temp); } else { - days_till_exp_crit = 0; + result.config.days_till_exp_crit = 0; if (!is_intnonneg(optarg)) { usage2("Invalid certificate expiration period", optarg); } - days_till_exp_warn = atoi(optarg); + result.config.days_till_exp_warn = atoi(optarg); } - check_cert = true; - ignore_send_quit_failure = true; + result.config.check_cert = true; + result.config.ignore_send_quit_failure = true; #else usage(_("SSL support not available - install OpenSSL and recompile")); #endif @@ -648,26 +648,27 @@ int process_arguments(int argc, char **argv) { // fallthrough case 's': /* ssl */ - use_ssl = true; - server_port = SMTPS_PORT; + result.config.use_ssl = true; + result.config.server_port = SMTPS_PORT; break; case 'S': /* starttls */ - use_starttls = true; - use_ehlo = true; + result.config.use_starttls = true; + result.config.use_ehlo = true; break; + } case SNI_OPTION: #ifdef HAVE_SSL - use_sni = true; + result.config.use_sni = true; #else usage(_("SSL support not available - install OpenSSL and recompile")); #endif break; case 'r': - use_proxy_prefix = true; + result.config.use_proxy_prefix = true; break; case 'L': - use_lhlo = true; + result.config.use_lhlo = true; break; case '4': address_family = AF_INET; @@ -690,60 +691,36 @@ int process_arguments(int argc, char **argv) { } } - c = optind; - if (server_address == NULL) { + int c = optind; + if (result.config.server_address == NULL) { if (argv[c]) { if (is_host(argv[c])) { - server_address = argv[c]; + result.config.server_address = argv[c]; } else { usage2(_("Invalid hostname/address"), argv[c]); } - } else { - xasprintf(&server_address, "127.0.0.1"); } } - if (server_expect == NULL) { - server_expect = strdup(SMTP_EXPECT); - } - - if (mail_command == NULL) { - mail_command = strdup("MAIL "); - } - - if (from_arg == NULL) { - from_arg = strdup(" "); - } - - if (use_starttls && use_ssl) { + if (result.config.use_starttls && result.config.use_ssl) { if (implicit_tls) { - use_ssl = false; - server_port = SMTP_PORT; + result.config.use_ssl = false; } else { usage4(_("Set either -s/--ssl/--tls or -S/--starttls")); } } - if (server_port_option != 0) { - server_port = server_port_option; - } - - return validate_arguments(); + return result; } -int validate_arguments(void) { return OK; } - -void smtp_quit(void) { - int bytes; - int n; - - n = my_send(SMTP_QUIT, strlen(SMTP_QUIT)); - if (n < 0) { - if (ignore_send_quit_failure) { +char *smtp_quit(check_smtp_config config, char buffer[MAX_INPUT_BUFFER], int socket_descriptor, bool ssl_established) { + int sent_bytes = my_send(config, SMTP_QUIT, strlen(SMTP_QUIT), socket_descriptor, ssl_established); + if (sent_bytes < 0) { + if (config.ignore_send_quit_failure) { if (verbose) { printf(_("Connection closed by server before sending QUIT command\n")); } - return; + return buffer; } die(STATE_UNKNOWN, _("Connection closed by server before sending QUIT command\n")); } @@ -753,7 +730,7 @@ void smtp_quit(void) { } /* read the response but don't care about problems */ - bytes = recvlines(buffer, MAX_INPUT_BUFFER); + int bytes = recvlines(config, buffer, MAX_INPUT_BUFFER, socket_descriptor, ssl_established); if (verbose) { if (bytes < 0) { printf(_("recv() failed after QUIT.")); @@ -764,6 +741,8 @@ void smtp_quit(void) { printf(_("received %s\n"), buffer); } } + + return buffer; } /* @@ -775,20 +754,20 @@ void smtp_quit(void) { * function which buffers the data, move that to netutils.c and change * check_smtp and other plugins to use that. Also, remove (\r)\n. */ -int recvline(char *buf, size_t bufsize) { +int recvline(char *buf, size_t bufsize, check_smtp_config config, int socket_descriptor, bool ssl_established) { int result; - unsigned i; + int counter; - for (i = result = 0; i < bufsize - 1; i++) { - if ((result = my_recv(&buf[i], 1)) != 1) { + for (counter = result = 0; counter < bufsize - 1; counter++) { + if ((result = my_recv(config, &buf[counter], 1, socket_descriptor, ssl_established)) != 1) { break; } - if (buf[i] == '\n') { - buf[++i] = '\0'; - return i; + if (buf[counter] == '\n') { + buf[++counter] = '\0'; + return counter; } } - return (result == 1 || i == 0) ? -2 : result; /* -2 if out of space */ + return (result == 1 || counter == 0) ? -2 : result; /* -2 if out of space */ } /* @@ -805,22 +784,23 @@ int recvline(char *buf, size_t bufsize) { * * TODO: Move this to netutils.c. Also, remove \r and possibly the final \n. */ -int recvlines(char *buf, size_t bufsize) { - int result, i; +int recvlines(check_smtp_config config, char *buf, size_t bufsize, int socket_descriptor, bool ssl_established) { + int result; + int counter; - for (i = 0; /* forever */; i += result) { - if (!((result = recvline(buf + i, bufsize - i)) > 3 && isdigit((int)buf[i]) && isdigit((int)buf[i + 1]) && - isdigit((int)buf[i + 2]) && buf[i + 3] == '-')) { + for (counter = 0; /* forever */; counter += result) { + if (!((result = recvline(buf + counter, bufsize - counter, config, socket_descriptor, ssl_established)) > 3 && + isdigit((int)buf[counter]) && isdigit((int)buf[counter + 1]) && isdigit((int)buf[counter + 2]) && buf[counter + 3] == '-')) { break; } } - return (result <= 0) ? result : result + i; + return (result <= 0) ? result : result + counter; } -int my_close(void) { +int my_close(int socket_descriptor) { int result; - result = close(sd); + result = close(socket_descriptor); #ifdef HAVE_SSL np_net_ssl_cleanup(); #endif diff --git a/plugins/check_smtp.d/config.h b/plugins/check_smtp.d/config.h new file mode 100644 index 00000000..c8660445 --- /dev/null +++ b/plugins/check_smtp.d/config.h @@ -0,0 +1,92 @@ +#pragma once + +#include "../../config.h" +#include +#include + +enum { + SMTP_PORT = 25, + SMTPS_PORT = 465 +}; + +#define SMTP_EXPECT "220" + +typedef struct { + int server_port; + char *server_address; + char *localhostname; + char *server_expect; + bool ignore_send_quit_failure; + + double warning_time; + bool check_warning_time; + double critical_time; + bool check_critical_time; + bool use_ehlo; + bool use_lhlo; + + char *from_arg; + bool send_mail_from; + + int ncommands; + char **commands; + + int nresponses; + char **responses; + + char *authtype; + char *authuser; + char *authpass; + + bool use_proxy_prefix; +#ifdef HAVE_SSL + bool check_cert; + int days_till_exp_warn; + int days_till_exp_crit; + bool use_ssl; + bool use_starttls; + bool use_sni; +#endif +} check_smtp_config; + +check_smtp_config check_smtp_config_init() { + check_smtp_config tmp = { + .server_port = SMTP_PORT, + .server_address = strdup("localhost"), + .localhostname = NULL, + + .server_expect = SMTP_EXPECT, + .ignore_send_quit_failure = false, + + .warning_time = 0, + .check_warning_time = false, + .critical_time = 0, + .check_critical_time = false, + .use_ehlo = false, + .use_lhlo = false, + + .from_arg = strdup(" "), + .send_mail_from = false, + + .ncommands = 0, + .commands = NULL, + + .nresponses = 0, + .responses = NULL, + + .authtype = NULL, + .authuser = NULL, + .authpass = NULL, + + .use_proxy_prefix = false, +#ifdef HAVE_SSL + .check_cert = false, + .days_till_exp_warn = 0, + .days_till_exp_crit = 0, + .use_ssl = false, + .use_starttls = false, + .use_sni = false, +#endif + }; + return tmp; +} -- cgit v1.2.3-74-g34f1 From acf57dba5233926a95fc746429f31f3009111b6f Mon Sep 17 00:00:00 2001 From: Lorenz Kästle <12514511+RincewindsHat@users.noreply.github.com> Date: Mon, 10 Mar 2025 01:32:49 +0100 Subject: check_smtp: Remove unused enum --- plugins/check_smtp.c | 5 ----- 1 file changed, 5 deletions(-) diff --git a/plugins/check_smtp.c b/plugins/check_smtp.c index 0be02937..1b36a22a 100644 --- a/plugins/check_smtp.c +++ b/plugins/check_smtp.c @@ -91,11 +91,6 @@ static int my_close(int /*socket_descriptor*/); static int verbose = 0; -enum { - TCP_PROTOCOL = 1, - UDP_PROTOCOL = 2, -}; - int main(int argc, char **argv) { /* Catch pipe errors in read/write - sometimes occurs when writing QUIT */ (void)signal(SIGPIPE, SIG_IGN); -- cgit v1.2.3-74-g34f1 From c5f873aa7b74c26c985a81bc4ffeb8d5fd1ce8a9 Mon Sep 17 00:00:00 2001 From: Lorenz Kästle <12514511+RincewindsHat@users.noreply.github.com> Date: Mon, 10 Mar 2025 09:56:05 +0100 Subject: check_smtp: small style fixes --- plugins/check_smtp.c | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/plugins/check_smtp.c b/plugins/check_smtp.c index 1b36a22a..ac0aa45d 100644 --- a/plugins/check_smtp.c +++ b/plugins/check_smtp.c @@ -28,7 +28,6 @@ * *****************************************************************************/ -#include "states.h" const char *progname = "check_smtp"; const char *copyright = "2000-2024"; const char *email = "devel@monitoring-plugins.org"; @@ -41,6 +40,7 @@ const char *email = "devel@monitoring-plugins.org"; #include #include "check_smtp.d/config.h" +#include "../lib/states.h" #define PROXY_PREFIX "PROXY TCP4 0.0.0.0 0.0.0.0 25 25\r\n" #define SMTP_HELO "HELO " @@ -92,9 +92,6 @@ static int my_close(int /*socket_descriptor*/); static int verbose = 0; int main(int argc, char **argv) { - /* Catch pipe errors in read/write - sometimes occurs when writing QUIT */ - (void)signal(SIGPIPE, SIG_IGN); - setlocale(LC_ALL, ""); bindtextdomain(PACKAGE, LOCALEDIR); textdomain(PACKAGE); @@ -123,6 +120,7 @@ int main(int argc, char **argv) { exit(STATE_CRITICAL); } } + char *helocmd = NULL; if (config.use_lhlo) { xasprintf(&helocmd, "%s%s%s", SMTP_LHLO, localhostname, "\r\n"); @@ -137,7 +135,6 @@ int main(int argc, char **argv) { } char *mail_command = strdup("MAIL "); - char *cmd_str = NULL; /* initialize the MAIL command with optional FROM command */ xasprintf(&cmd_str, "%sFROM:<%s>%s", mail_command, config.from_arg, "\r\n"); @@ -146,6 +143,9 @@ int main(int argc, char **argv) { printf("FROM CMD: %s", cmd_str); } + /* Catch pipe errors in read/write - sometimes occurs when writing QUIT */ + (void)signal(SIGPIPE, SIG_IGN); + /* initialize alarm signal handling */ (void)signal(SIGALRM, socket_timeout_alarm_handler); @@ -204,6 +204,7 @@ int main(int argc, char **argv) { printf(_("recv() failed\n")); exit(STATE_WARNING); } + bool supports_tls = false; if (config.use_ehlo || config.use_lhlo) { if (strstr(buffer, "250 STARTTLS") != NULL || strstr(buffer, "250-STARTTLS") != NULL) { @@ -228,6 +229,7 @@ int main(int argc, char **argv) { smtp_quit(config, buffer, socket_descriptor, ssl_established); exit(STATE_UNKNOWN); } + result = np_net_ssl_init_with_hostname(socket_descriptor, (config.use_sni ? config.server_address : NULL)); if (result != STATE_OK) { printf(_("CRITICAL - Cannot create SSL context.\n")); @@ -235,6 +237,7 @@ int main(int argc, char **argv) { np_net_ssl_cleanup(); exit(STATE_CRITICAL); } + ssl_established = true; /* -- cgit v1.2.3-74-g34f1 From cda3906b12f88388ca4caeadf9f351c9c018bf89 Mon Sep 17 00:00:00 2001 From: Lorenz Kästle <12514511+RincewindsHat@users.noreply.github.com> Date: Mon, 10 Mar 2025 10:45:50 +0100 Subject: Refactor check_apt --- plugins/Makefile.am | 3 +- plugins/check_apt.c | 151 ++++++++++++++++++++++--------------------- plugins/check_apt.d/config.h | 42 ++++++++++++ 3 files changed, 120 insertions(+), 76 deletions(-) create mode 100644 plugins/check_apt.d/config.h diff --git a/plugins/Makefile.am b/plugins/Makefile.am index d40a0937..2ffb5fd0 100644 --- a/plugins/Makefile.am +++ b/plugins/Makefile.am @@ -53,7 +53,8 @@ EXTRA_DIST = t \ check_game.d \ check_dbi.d \ check_ssh.d \ - check_dns.d + check_dns.d \ + check_apt.d PLUGINHDRS = common.h diff --git a/plugins/check_apt.c b/plugins/check_apt.c index 1eda45dd..e840184b 100644 --- a/plugins/check_apt.c +++ b/plugins/check_apt.c @@ -29,6 +29,7 @@ * *****************************************************************************/ +#include "states.h" const char *progname = "check_apt"; const char *copyright = "2006-2024"; const char *email = "devel@monitoring-plugins.org"; @@ -37,13 +38,7 @@ const char *email = "devel@monitoring-plugins.org"; #include "runcmd.h" #include "utils.h" #include "regex.h" - -/* some constants */ -typedef enum { - UPGRADE, - DIST_UPGRADE, - NO_UPGRADE -} upgrade_type; +#include "check_apt.d/config.h" /* Character for hidden input file option (for testing). */ #define INPUT_FILE_OPT CHAR_MAX + 1 @@ -61,14 +56,18 @@ typedef enum { #define SECURITY_RE "^[^\\(]*\\(.* (Debian-Security:|Ubuntu:[^/]*/[^-]*-security)" /* some standard functions */ -static int process_arguments(int /*argc*/, char ** /*argv*/); +typedef struct { + int errorcode; + check_apt_config config; +} check_apt_config_wrapper; +static check_apt_config_wrapper process_arguments(int /*argc*/, char ** /*argv*/); static void print_help(void); void print_usage(void); /* construct the appropriate apt-get cmdline */ -static char *construct_cmdline(upgrade_type u, const char *opts); +static char *construct_cmdline(upgrade_type /*u*/, const char * /*opts*/); /* run an apt-get update */ -static int run_update(void); +static int run_update(char * /*update_opts*/); typedef struct { int errorcode; @@ -79,42 +78,35 @@ typedef struct { } run_upgrade_result; /* run an apt-get upgrade */ -static run_upgrade_result run_upgrade(void); +run_upgrade_result run_upgrade(upgrade_type upgrade, const char *do_include, const char *do_exclude, const char *do_critical, + const char *upgrade_opts, const char *input_filename); /* add another clause to a regexp */ -static char *add_to_regexp(char *expr, const char *next); +static char *add_to_regexp(char * /*expr*/, const char * /*next*/); /* extract package name from Inst line */ -static char *pkg_name(char *line); +static char *pkg_name(char * /*line*/); /* string comparison function for qsort */ -static int cmpstringp(const void *p1, const void *p2); +static int cmpstringp(const void * /*p1*/, const void * /*p2*/); /* configuration variables */ -static int verbose = 0; /* -v */ -static bool list = false; /* list packages available for upgrade */ -static bool do_update = false; /* whether to call apt-get update */ -static bool only_critical = false; /* whether to warn about non-critical updates */ -static upgrade_type upgrade = UPGRADE; /* which type of upgrade to do */ -static char *upgrade_opts = NULL; /* options to override defaults for upgrade */ -static char *update_opts = NULL; /* options to override defaults for update */ -static char *do_include = NULL; /* regexp to only include certain packages */ -static char *do_exclude = NULL; /* regexp to only exclude certain packages */ -static char *do_critical = NULL; /* regexp specifying critical packages */ -static char *input_filename = NULL; /* input filename for testing */ -/* number of packages available for upgrade to return WARNING status */ -static int packages_warning = 1; +static int verbose = 0; /* -v */ /* other global variables */ -static int stderr_warning = 0; /* if a cmd issued output on stderr */ -static int exec_warning = 0; /* if a cmd exited non-zero */ +static bool stderr_warning = false; /* if a cmd issued output on stderr */ +static bool exec_warning = false; /* if a cmd exited non-zero */ 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_apt_config_wrapper tmp_config = process_arguments(argc, argv); + + if (tmp_config.errorcode == ERROR) { usage_va(_("Could not parse arguments")); } + const check_apt_config config = tmp_config.config; + /* Set signal handling and alarm timeout */ if (signal(SIGALRM, timeout_alarm_handler) == SIG_ERR) { usage_va(_("Cannot catch SIGALRM")); @@ -123,14 +115,15 @@ int main(int argc, char **argv) { /* handle timeouts gracefully... */ alarm(timeout_interval); - int result = STATE_UNKNOWN; + mp_state_enum result = STATE_UNKNOWN; /* if they want to run apt-get update first... */ - if (do_update) { - result = run_update(); + if (config.do_update) { + result = run_update(config.update_opts); } /* apt-get upgrade */ - run_upgrade_result upgrad_res = run_upgrade(); + run_upgrade_result upgrad_res = + run_upgrade(config.upgrade, config.do_include, config.do_exclude, config.do_critical, config.upgrade_opts, config.input_filename); result = max_state(result, upgrad_res.errorcode); int packages_available = upgrad_res.package_count; @@ -140,18 +133,18 @@ int main(int argc, char **argv) { if (sec_count > 0) { result = max_state(result, STATE_CRITICAL); - } else if (packages_available >= packages_warning && only_critical == false) { + } else if (packages_available >= config.packages_warning && !config.only_critical) { result = max_state(result, STATE_WARNING); } else if (result > STATE_UNKNOWN) { result = STATE_UNKNOWN; } printf(_("APT %s: %d packages available for %s (%d critical updates). %s%s%s%s|available_upgrades=%d;;;0 critical_updates=%d;;;0\n"), - state_text(result), packages_available, (upgrade == DIST_UPGRADE) ? "dist-upgrade" : "upgrade", sec_count, + state_text(result), packages_available, (config.upgrade == DIST_UPGRADE) ? "dist-upgrade" : "upgrade", sec_count, (stderr_warning) ? " warnings detected" : "", (stderr_warning && exec_warning) ? "," : "", (exec_warning) ? " errors detected" : "", (stderr_warning || exec_warning) ? "." : "", packages_available, sec_count); - if (list) { + if (config.list) { qsort(secpackages_list, sec_count, sizeof(char *), cmpstringp); qsort(packages_list, packages_available - sec_count, sizeof(char *), cmpstringp); @@ -159,7 +152,7 @@ int main(int argc, char **argv) { printf("%s (security)\n", secpackages_list[i]); } - if (only_critical == false) { + if (!config.only_critical) { for (int i = 0; i < packages_available - sec_count; i++) { printf("%s\n", packages_list[i]); } @@ -170,7 +163,7 @@ int main(int argc, char **argv) { } /* process command-line arguments */ -int process_arguments(int argc, char **argv) { +check_apt_config_wrapper process_arguments(int argc, char **argv) { static struct option longopts[] = {{"version", no_argument, 0, 'V'}, {"help", no_argument, 0, 'h'}, {"verbose", no_argument, 0, 'v'}, @@ -179,7 +172,7 @@ int process_arguments(int argc, char **argv) { {"upgrade", optional_argument, 0, 'U'}, {"no-upgrade", no_argument, 0, 'n'}, {"dist-upgrade", optional_argument, 0, 'd'}, - {"list", no_argument, false, 'l'}, + {"list", no_argument, 0, 'l'}, {"include", required_argument, 0, 'i'}, {"exclude", required_argument, 0, 'e'}, {"critical", required_argument, 0, 'c'}, @@ -188,6 +181,11 @@ int process_arguments(int argc, char **argv) { {"packages-warning", required_argument, 0, 'w'}, {0, 0, 0, 0}}; + check_apt_config_wrapper result = { + .errorcode = OK, + .config = check_apt_config_init(), + }; + while (true) { int option_char = getopt_long(argc, argv, "hVvt:u::U::d::nli:e:c:ow:", longopts, NULL); @@ -209,55 +207,55 @@ int process_arguments(int argc, char **argv) { timeout_interval = atoi(optarg); break; case 'd': - upgrade = DIST_UPGRADE; + result.config.upgrade = DIST_UPGRADE; if (optarg != NULL) { - upgrade_opts = strdup(optarg); - if (upgrade_opts == NULL) { + result.config.upgrade_opts = strdup(optarg); + if (result.config.upgrade_opts == NULL) { die(STATE_UNKNOWN, "strdup failed"); } } break; case 'U': - upgrade = UPGRADE; + result.config.upgrade = UPGRADE; if (optarg != NULL) { - upgrade_opts = strdup(optarg); - if (upgrade_opts == NULL) { + result.config.upgrade_opts = strdup(optarg); + if (result.config.upgrade_opts == NULL) { die(STATE_UNKNOWN, "strdup failed"); } } break; case 'n': - upgrade = NO_UPGRADE; + result.config.upgrade = NO_UPGRADE; break; case 'u': - do_update = true; + result.config.do_update = true; if (optarg != NULL) { - update_opts = strdup(optarg); - if (update_opts == NULL) { + result.config.update_opts = strdup(optarg); + if (result.config.update_opts == NULL) { die(STATE_UNKNOWN, "strdup failed"); } } break; case 'l': - list = true; + result.config.list = true; break; case 'i': - do_include = add_to_regexp(do_include, optarg); + result.config.do_include = add_to_regexp(result.config.do_include, optarg); break; case 'e': - do_exclude = add_to_regexp(do_exclude, optarg); + result.config.do_exclude = add_to_regexp(result.config.do_exclude, optarg); break; case 'c': - do_critical = add_to_regexp(do_critical, optarg); + result.config.do_critical = add_to_regexp(result.config.do_critical, optarg); break; case 'o': - only_critical = true; + result.config.only_critical = true; break; case INPUT_FILE_OPT: - input_filename = optarg; + result.config.input_filename = optarg; break; case 'w': - packages_warning = atoi(optarg); + result.config.packages_warning = atoi(optarg); break; default: /* print short usage statement if args not parsable */ @@ -265,11 +263,12 @@ int process_arguments(int argc, char **argv) { } } - return OK; + return result; } /* run an apt-get upgrade */ -run_upgrade_result run_upgrade(void) { +run_upgrade_result run_upgrade(const upgrade_type upgrade, const char *do_include, const char *do_exclude, const char *do_critical, + const char *upgrade_opts, const char *input_filename) { regex_t ereg; /* initialize ereg as it is possible it is printed while uninitialized */ memset(&ereg, '\0', sizeof(ereg.buffer)); @@ -332,7 +331,7 @@ run_upgrade_result run_upgrade(void) { fprintf(stderr, _("'%s' exited with non-zero status.\n"), cmdline); } - char **pkglist = malloc(sizeof(char *) * chld_out.lines); + char **pkglist = malloc(sizeof(char *) * chld_out.lines); if (!pkglist) { die(STATE_UNKNOWN, "malloc failed!\n"); } @@ -385,7 +384,7 @@ run_upgrade_result run_upgrade(void) { /* If we get anything on stderr, at least set warning */ if (input_filename == NULL && chld_err.buflen) { - stderr_warning = 1; + stderr_warning = true; result.errorcode = max_state(result.errorcode, STATE_WARNING); if (verbose) { for (size_t i = 0; i < chld_err.lines; i++) { @@ -405,7 +404,7 @@ run_upgrade_result run_upgrade(void) { } /* run an apt-get update (needs root) */ -int run_update(void) { +int run_update(char *update_opts) { int result = STATE_UNKNOWN; char *cmdline; /* run the update */ @@ -418,7 +417,7 @@ int run_update(void) { * since we were explicitly asked to do so, this is treated as * a critical error. */ if (result != 0) { - exec_warning = 1; + exec_warning = true; result = STATE_CRITICAL; fprintf(stderr, _("'%s' exited with non-zero status.\n"), cmdline); } @@ -446,7 +445,7 @@ int run_update(void) { char *pkg_name(char *line) { char *start = line + strlen(PKGINST_PREFIX); - int len = strlen(start); + size_t len = strlen(start); char *space = index(start, ' '); if (space != NULL) { @@ -464,35 +463,37 @@ char *pkg_name(char *line) { return pkg; } -int cmpstringp(const void *p1, const void *p2) { return strcmp(*(char *const *)p1, *(char *const *)p2); } +int cmpstringp(const void *left_string, const void *right_string) { + return strcmp(*(char *const *)left_string, *(char *const *)right_string); +} char *add_to_regexp(char *expr, const char *next) { - char *re = NULL; + char *regex_string = NULL; if (expr == NULL) { - re = malloc(sizeof(char) * (strlen("()") + strlen(next) + 1)); - if (!re) { + regex_string = malloc(sizeof(char) * (strlen("()") + strlen(next) + 1)); + if (!regex_string) { die(STATE_UNKNOWN, "malloc failed!\n"); } - sprintf(re, "(%s)", next); + sprintf(regex_string, "(%s)", next); } else { /* resize it, adding an extra char for the new '|' separator */ - re = realloc(expr, sizeof(char) * (strlen(expr) + 1 + strlen(next) + 1)); - if (!re) { + regex_string = realloc(expr, sizeof(char) * (strlen(expr) + 1 + strlen(next) + 1)); + if (!regex_string) { die(STATE_UNKNOWN, "realloc failed!\n"); } /* append it starting at ')' in the old re */ - sprintf((char *)(re + strlen(re) - 1), "|%s)", next); + sprintf((char *)(regex_string + strlen(regex_string) - 1), "|%s)", next); } - return re; + return regex_string; } -char *construct_cmdline(upgrade_type u, const char *opts) { +char *construct_cmdline(upgrade_type upgrade, const char *opts) { const char *opts_ptr = NULL; const char *aptcmd = NULL; - switch (u) { + switch (upgrade) { case UPGRADE: if (opts == NULL) { opts_ptr = UPGRADE_DEFAULT_OPTS; diff --git a/plugins/check_apt.d/config.h b/plugins/check_apt.d/config.h new file mode 100644 index 00000000..2c962e5a --- /dev/null +++ b/plugins/check_apt.d/config.h @@ -0,0 +1,42 @@ +#pragma once + +#include "../../config.h" +#include + +/* some constants */ +typedef enum { + UPGRADE, + DIST_UPGRADE, + NO_UPGRADE +} upgrade_type; + +typedef struct { + bool do_update; /* whether to call apt-get update */ + upgrade_type upgrade; /* which type of upgrade to do */ + bool only_critical; /* whether to warn about non-critical updates */ + bool list; /* list packages available for upgrade */ + /* number of packages available for upgrade to return WARNING status */ + int packages_warning; + + char *upgrade_opts; /* options to override defaults for upgrade */ + char *update_opts; /* options to override defaults for update */ + char *do_include; /* regexp to only include certain packages */ + char *do_exclude; /* regexp to only exclude certain packages */ + char *do_critical; /* regexp specifying critical packages */ + char *input_filename; /* input filename for testing */ +} check_apt_config; + +check_apt_config check_apt_config_init() { + check_apt_config tmp = {.do_update = false, + .upgrade = UPGRADE, + .only_critical = false, + .list = false, + .packages_warning = 1, + .update_opts = NULL, + .update_opts = NULL, + .do_include = NULL, + .do_exclude = NULL, + .do_critical = NULL, + .input_filename = NULL}; + return tmp; +} -- cgit v1.2.3-74-g34f1 From bd3ec036c77fe88a63af365cfc0d8e525394489d Mon Sep 17 00:00:00 2001 From: Lorenz Kästle <12514511+RincewindsHat@users.noreply.github.com> Date: Mon, 10 Mar 2025 15:02:46 +0100 Subject: Refactor check_by_ssh --- plugins/Makefile.am | 3 +- plugins/check_apt.d/config.h | 1 - plugins/check_by_ssh.c | 265 +++++++++++++++++++++------------------- plugins/check_by_ssh.d/config.h | 56 +++++++++ 4 files changed, 197 insertions(+), 128 deletions(-) create mode 100644 plugins/check_by_ssh.d/config.h diff --git a/plugins/Makefile.am b/plugins/Makefile.am index 2ffb5fd0..3d5ad1a9 100644 --- a/plugins/Makefile.am +++ b/plugins/Makefile.am @@ -54,7 +54,8 @@ EXTRA_DIST = t \ check_dbi.d \ check_ssh.d \ check_dns.d \ - check_apt.d + check_apt.d \ + check_by_ssh.d PLUGINHDRS = common.h diff --git a/plugins/check_apt.d/config.h b/plugins/check_apt.d/config.h index 2c962e5a..981f4f42 100644 --- a/plugins/check_apt.d/config.h +++ b/plugins/check_apt.d/config.h @@ -33,7 +33,6 @@ check_apt_config check_apt_config_init() { .list = false, .packages_warning = 1, .update_opts = NULL, - .update_opts = NULL, .do_include = NULL, .do_exclude = NULL, .do_critical = NULL, diff --git a/plugins/check_by_ssh.c b/plugins/check_by_ssh.c index 2ac7805d..2bc38d49 100644 --- a/plugins/check_by_ssh.c +++ b/plugins/check_by_ssh.c @@ -32,48 +32,28 @@ const char *email = "devel@monitoring-plugins.org"; #include "common.h" #include "utils.h" -#include "netutils.h" #include "utils_cmd.h" +#include "check_by_ssh.d/config.h" +#include "states.h" #ifndef NP_MAXARGS # define NP_MAXARGS 1024 #endif -static int process_arguments(int /*argc*/, char ** /*argv*/); -static int validate_arguments(void); -static void comm_append(const char * /*str*/); +typedef struct { + int errorcode; + check_by_ssh_config config; +} check_by_ssh_config_wrapper; +static check_by_ssh_config_wrapper process_arguments(int /*argc*/, char ** /*argv*/); +static check_by_ssh_config_wrapper validate_arguments(check_by_ssh_config_wrapper /*config_wrapper*/); + +static command_construct comm_append(command_construct /*cmd*/, const char * /*str*/); static void print_help(void); void print_usage(void); -static unsigned int commands = 0; -static unsigned int services = 0; -static int skip_stdout = 0; -static int skip_stderr = 0; -static int warn_on_stderr = 0; -static bool unknown_timeout = false; -static char *remotecmd = NULL; -static char **commargv = NULL; -static int commargc = 0; -static char *hostname = NULL; -static char *outputfile = NULL; -static char *host_shortname = NULL; -static char **service; -static bool passive = false; static bool verbose = false; int main(int argc, char **argv) { - - char *status_text; - int cresult; - int result = STATE_UNKNOWN; - time_t local_time; - FILE *file_pointer = NULL; - output chld_out; - output chld_err; - - remotecmd = ""; - comm_append(SSH_COMMAND); - setlocale(LC_ALL, ""); bindtextdomain(PACKAGE, LOCALEDIR); textdomain(PACKAGE); @@ -81,11 +61,15 @@ int main(int argc, char **argv) { /* Parse extra opts if any */ argv = np_extra_opts(&argc, argv, progname); + check_by_ssh_config_wrapper tmp_config = process_arguments(argc, argv); + /* process arguments */ - if (process_arguments(argc, argv) == ERROR) { + if (tmp_config.errorcode == ERROR) { usage_va(_("Could not parse arguments")); } + const check_by_ssh_config config = tmp_config.config; + /* Set signal handling and alarm timeout */ if (signal(SIGALRM, timeout_alarm_handler) == SIG_ERR) { usage_va(_("Cannot catch SIGALRM")); @@ -94,16 +78,18 @@ int main(int argc, char **argv) { /* run the command */ if (verbose) { - printf("Command: %s\n", commargv[0]); - for (int i = 1; i < commargc; i++) { - printf("Argument %i: %s\n", i, commargv[i]); + printf("Command: %s\n", config.cmd.commargv[0]); + for (int i = 1; i < config.cmd.commargc; i++) { + printf("Argument %i: %s\n", i, config.cmd.commargv[i]); } } - result = cmd_run_array(commargv, &chld_out, &chld_err, 0); + output chld_out; + output chld_err; + mp_state_enum result = cmd_run_array(config.cmd.commargv, &chld_out, &chld_err, 0); /* SSH returns 255 if connection attempt fails; include the first line of error output */ - if (result == 255 && unknown_timeout) { + if (result == 255 && config.unknown_timeout) { printf(_("SSH connection failed: %s\n"), chld_err.lines > 0 ? chld_err.line[0] : "(no error output)"); return STATE_UNKNOWN; } @@ -117,17 +103,24 @@ int main(int argc, char **argv) { } } - if (skip_stdout == -1) { /* --skip-stdout specified without argument */ + size_t skip_stdout = 0; + if (config.skip_stdout == -1) { /* --skip-stdout specified without argument */ skip_stdout = chld_out.lines; + } else { + skip_stdout = config.skip_stdout; } - if (skip_stderr == -1) { /* --skip-stderr specified without argument */ + + size_t skip_stderr = 0; + if (config.skip_stderr == -1) { /* --skip-stderr specified without argument */ skip_stderr = chld_err.lines; + } else { + skip_stderr = config.skip_stderr; } /* UNKNOWN or worse if (non-skipped) output found on stderr */ if (chld_err.lines > (size_t)skip_stderr) { printf(_("Remote command execution failed: %s\n"), chld_err.line[skip_stderr]); - if (warn_on_stderr) { + if (config.warn_on_stderr) { return max_state_alt(result, STATE_WARNING); } return max_state_alt(result, STATE_UNKNOWN); @@ -135,13 +128,13 @@ int main(int argc, char **argv) { /* this is simple if we're not supposed to be passive. * Wrap up quickly and keep the tricks below */ - if (!passive) { + if (!config.passive) { if (chld_out.lines > (size_t)skip_stdout) { for (size_t i = skip_stdout; i < chld_out.lines; i++) { puts(chld_out.line[i]); } } else { - printf(_("%s - check_by_ssh: Remote command '%s' returned status %d\n"), state_text(result), remotecmd, result); + printf(_("%s - check_by_ssh: Remote command '%s' returned status %d\n"), state_text(result), config.remotecmd, result); } return result; /* return error status from remote command */ } @@ -151,36 +144,34 @@ int main(int argc, char **argv) { */ /* process output */ - if (!(file_pointer = fopen(outputfile, "a"))) { - printf(_("SSH WARNING: could not open %s\n"), outputfile); + FILE *file_pointer = NULL; + if (!(file_pointer = fopen(config.outputfile, "a"))) { + printf(_("SSH WARNING: could not open %s\n"), config.outputfile); exit(STATE_UNKNOWN); } - local_time = time(NULL); - commands = 0; + time_t local_time = time(NULL); + unsigned int commands = 0; + char *status_text; + int cresult; for (size_t i = skip_stdout; i < chld_out.lines; i++) { status_text = chld_out.line[i++]; if (i == chld_out.lines || strstr(chld_out.line[i], "STATUS CODE: ") == NULL) { die(STATE_UNKNOWN, _("%s: Error parsing output\n"), progname); } - if (service[commands] && status_text && sscanf(chld_out.line[i], "STATUS CODE: %d", &cresult) == 1) { - fprintf(file_pointer, "[%d] PROCESS_SERVICE_CHECK_RESULT;%s;%s;%d;%s\n", (int)local_time, host_shortname, service[commands++], - cresult, status_text); + if (config.service[commands] && status_text && sscanf(chld_out.line[i], "STATUS CODE: %d", &cresult) == 1) { + fprintf(file_pointer, "[%d] PROCESS_SERVICE_CHECK_RESULT;%s;%s;%d;%s\n", (int)local_time, config.host_shortname, + config.service[commands++], cresult, status_text); } } /* Multiple commands and passive checking should always return OK */ - return result; + exit(result); } /* process command-line arguments */ -int process_arguments(int argc, char **argv) { - int c; - char *p1; - char *p2; - - int option = 0; +check_by_ssh_config_wrapper process_arguments(int argc, char **argv) { static struct option longopts[] = {{"version", no_argument, 0, 'V'}, {"help", no_argument, 0, 'h'}, {"verbose", no_argument, 0, 'v'}, @@ -210,24 +201,33 @@ int process_arguments(int argc, char **argv) { {"configfile", optional_argument, 0, 'F'}, {0, 0, 0, 0}}; + check_by_ssh_config_wrapper result = { + .errorcode = OK, + .config = check_by_ssh_config_init(), + }; + if (argc < 2) { - return ERROR; + result.errorcode = ERROR; + return result; } - for (c = 1; c < argc; c++) { - if (strcmp("-to", argv[c]) == 0) { - strcpy(argv[c], "-t"); + for (int index = 1; index < argc; index++) { + if (strcmp("-to", argv[index]) == 0) { + strcpy(argv[index], "-t"); } } - while (1) { - c = getopt_long(argc, argv, "Vvh1246fqt:UH:O:p:i:u:l:C:S::E::n:s:o:F:", longopts, &option); + result.config.cmd = comm_append(result.config.cmd, SSH_COMMAND); - if (c == -1 || c == EOF) { + int option = 0; + while (true) { + int opt_index = getopt_long(argc, argv, "Vvh1246fqt:UH:O:p:i:u:l:C:S::E::n:s:o:F:", longopts, &option); + + if (opt_index == -1 || opt_index == EOF) { break; } - switch (c) { + switch (opt_index) { case 'V': /* version */ print_revision(progname, NP_VERSION); exit(STATE_UNKNOWN); @@ -245,169 +245,182 @@ int process_arguments(int argc, char **argv) { } break; case 'U': - unknown_timeout = true; + result.config.unknown_timeout = true; break; case 'H': /* host */ - hostname = optarg; + result.config.hostname = optarg; break; case 'p': /* port number */ if (!is_integer(optarg)) { usage_va(_("Port must be a positive integer")); } - comm_append("-p"); - comm_append(optarg); + result.config.cmd = comm_append(result.config.cmd, "-p"); + result.config.cmd = comm_append(result.config.cmd, optarg); break; case 'O': /* output file */ - outputfile = optarg; - passive = true; + result.config.outputfile = optarg; + result.config.passive = true; break; - case 's': /* description of service to check */ + case 's': /* description of service to check */ { + char *p1; + char *p2; + p1 = optarg; - service = realloc(service, (++services) * sizeof(char *)); + result.config.service = realloc(result.config.service, (++result.config.number_of_services) * sizeof(char *)); while ((p2 = index(p1, ':'))) { *p2 = '\0'; - service[services - 1] = p1; - service = realloc(service, (++services) * sizeof(char *)); + result.config.service[result.config.number_of_services - 1] = p1; + result.config.service = realloc(result.config.service, (++result.config.number_of_services) * sizeof(char *)); p1 = p2 + 1; } - service[services - 1] = p1; + result.config.service[result.config.number_of_services - 1] = p1; break; case 'n': /* short name of host in the monitoring configuration */ - host_shortname = optarg; - break; - + result.config.host_shortname = optarg; + } break; case 'u': - comm_append("-l"); - comm_append(optarg); + result.config.cmd = comm_append(result.config.cmd, "-l"); + result.config.cmd = comm_append(result.config.cmd, optarg); break; case 'l': /* login name */ - comm_append("-l"); - comm_append(optarg); + result.config.cmd = comm_append(result.config.cmd, "-l"); + result.config.cmd = comm_append(result.config.cmd, optarg); break; case 'i': /* identity */ - comm_append("-i"); - comm_append(optarg); + result.config.cmd = comm_append(result.config.cmd, "-i"); + result.config.cmd = comm_append(result.config.cmd, optarg); break; case '1': /* Pass these switches directly to ssh */ - comm_append("-1"); + result.config.cmd = comm_append(result.config.cmd, "-1"); break; case '2': /* 1 to force version 1, 2 to force version 2 */ - comm_append("-2"); + result.config.cmd = comm_append(result.config.cmd, "-2"); break; case '4': /* -4 for IPv4 */ - comm_append("-4"); + result.config.cmd = comm_append(result.config.cmd, "-4"); break; case '6': /* -6 for IPv6 */ - comm_append("-6"); + result.config.cmd = comm_append(result.config.cmd, "-6"); break; case 'f': /* fork to background */ - comm_append("-f"); + result.config.cmd = comm_append(result.config.cmd, "-f"); break; case 'C': /* Command for remote machine */ - commands++; - if (commands > 1) { - xasprintf(&remotecmd, "%s;echo STATUS CODE: $?;", remotecmd); + result.config.commands++; + if (result.config.commands > 1) { + xasprintf(&result.config.remotecmd, "%s;echo STATUS CODE: $?;", result.config.remotecmd); } - xasprintf(&remotecmd, "%s%s", remotecmd, optarg); + xasprintf(&result.config.remotecmd, "%s%s", result.config.remotecmd, optarg); break; case 'S': /* skip n (or all) lines on stdout */ if (optarg == NULL) { - skip_stdout = -1; /* skip all output on stdout */ + result.config.skip_stdout = -1; /* skip all output on stdout */ } else if (!is_integer(optarg)) { usage_va(_("skip-stdout argument must be an integer")); } else { - skip_stdout = atoi(optarg); + result.config.skip_stdout = atoi(optarg); } break; case 'E': /* skip n (or all) lines on stderr */ if (optarg == NULL) { - skip_stderr = -1; /* skip all output on stderr */ + result.config.skip_stderr = -1; /* skip all output on stderr */ } else if (!is_integer(optarg)) { usage_va(_("skip-stderr argument must be an integer")); } else { - skip_stderr = atoi(optarg); + result.config.skip_stderr = atoi(optarg); } break; case 'W': /* exit with warning if there is an output on stderr */ - warn_on_stderr = 1; + result.config.warn_on_stderr = true; break; case 'o': /* Extra options for the ssh command */ - comm_append("-o"); - comm_append(optarg); + result.config.cmd = comm_append(result.config.cmd, "-o"); + result.config.cmd = comm_append(result.config.cmd, optarg); break; case 'q': /* Tell the ssh command to be quiet */ - comm_append("-q"); + result.config.cmd = comm_append(result.config.cmd, "-q"); break; case 'F': /* ssh configfile */ - comm_append("-F"); - comm_append(optarg); + result.config.cmd = comm_append(result.config.cmd, "-F"); + result.config.cmd = comm_append(result.config.cmd, optarg); break; default: /* help */ usage5(); } } - c = optind; - if (hostname == NULL) { + int c = optind; + if (result.config.hostname == NULL) { if (c <= argc) { die(STATE_UNKNOWN, _("%s: You must provide a host name\n"), progname); } - hostname = argv[c++]; + result.config.hostname = argv[c++]; } - if (strlen(remotecmd) == 0) { + if (strlen(result.config.remotecmd) == 0) { for (; c < argc; c++) { - if (strlen(remotecmd) > 0) { - xasprintf(&remotecmd, "%s %s", remotecmd, argv[c]); + if (strlen(result.config.remotecmd) > 0) { + xasprintf(&result.config.remotecmd, "%s %s", result.config.remotecmd, argv[c]); } else { - xasprintf(&remotecmd, "%s", argv[c]); + xasprintf(&result.config.remotecmd, "%s", argv[c]); } } } - if (commands > 1 || passive) { - xasprintf(&remotecmd, "%s;echo STATUS CODE: $?;", remotecmd); + if (result.config.commands > 1 || result.config.passive) { + xasprintf(&result.config.remotecmd, "%s;echo STATUS CODE: $?;", result.config.remotecmd); } - if (remotecmd == NULL || strlen(remotecmd) <= 1) { + if (result.config.remotecmd == NULL || strlen(result.config.remotecmd) <= 1) { usage_va(_("No remotecmd")); } - comm_append(hostname); - comm_append(remotecmd); + result.config.cmd = comm_append(result.config.cmd, result.config.hostname); + result.config.cmd = comm_append(result.config.cmd, result.config.remotecmd); - return validate_arguments(); + return validate_arguments(result); } -void comm_append(const char *str) { +command_construct comm_append(command_construct cmd, const char *str) { + + if (verbose) { + for (int i = 0; i < cmd.commargc; i++) { + printf("Current command: [%i] %s\n", i, cmd.commargv[i]); + } - if (++commargc > NP_MAXARGS) { + printf("Appending: %s\n", str); + } + + if (++cmd.commargc > NP_MAXARGS) { die(STATE_UNKNOWN, _("%s: Argument limit of %d exceeded\n"), progname, NP_MAXARGS); } - if ((commargv = (char **)realloc(commargv, (commargc + 1) * sizeof(char *))) == NULL) { + if ((cmd.commargv = (char **)realloc(cmd.commargv, (cmd.commargc + 1) * sizeof(char *))) == NULL) { die(STATE_UNKNOWN, _("Can not (re)allocate 'commargv' buffer\n")); } - commargv[commargc - 1] = strdup(str); - commargv[commargc] = NULL; + cmd.commargv[cmd.commargc - 1] = strdup(str); + cmd.commargv[cmd.commargc] = NULL; + + return cmd; } -int validate_arguments(void) { - if (remotecmd == NULL || hostname == NULL) { - return ERROR; +check_by_ssh_config_wrapper validate_arguments(check_by_ssh_config_wrapper config_wrapper) { + if (config_wrapper.config.remotecmd == NULL || config_wrapper.config.hostname == NULL) { + config_wrapper.errorcode = ERROR; + return config_wrapper; } - if (passive && commands != services) { + if (config_wrapper.config.passive && config_wrapper.config.commands != config_wrapper.config.number_of_services) { die(STATE_UNKNOWN, _("%s: In passive mode, you must provide a service name for each command.\n"), progname); } - if (passive && host_shortname == NULL) { + if (config_wrapper.config.passive && config_wrapper.config.host_shortname == NULL) { die(STATE_UNKNOWN, _("%s: In passive mode, you must provide the host short name from the monitoring configs.\n"), progname); } - return OK; + return config_wrapper; } void print_help(void) { diff --git a/plugins/check_by_ssh.d/config.h b/plugins/check_by_ssh.d/config.h new file mode 100644 index 00000000..05435def --- /dev/null +++ b/plugins/check_by_ssh.d/config.h @@ -0,0 +1,56 @@ +#pragma once + +#include "../../config.h" +#include + +typedef struct { + int commargc; + char **commargv; +} command_construct; + +typedef struct { + char *hostname; + char *host_shortname; + + char **service; + unsigned int number_of_services; + + unsigned int commands; // Not needed during actual test run + char *remotecmd; + + command_construct cmd; + + bool unknown_timeout; + bool warn_on_stderr; + int skip_stdout; + int skip_stderr; + bool passive; + char *outputfile; +} check_by_ssh_config; + +check_by_ssh_config check_by_ssh_config_init() { + check_by_ssh_config tmp = { + .hostname = NULL, + .host_shortname = NULL, + + .service = NULL, + .number_of_services = 0, + + .commands = 0, + .remotecmd = "", + + .cmd = + { + .commargc = 0, + .commargv = NULL, + }, + + .unknown_timeout = false, + .warn_on_stderr = false, + .skip_stderr = 0, + .skip_stdout = 0, + .passive = false, + .outputfile = NULL, + }; + return tmp; +} -- cgit v1.2.3-74-g34f1 From 58f08344200e89fe9a3fbd3edbf4fa2c5b2ec194 Mon Sep 17 00:00:00 2001 From: Lorenz Kästle <12514511+RincewindsHat@users.noreply.github.com> Date: Mon, 10 Mar 2025 16:03:36 +0100 Subject: check_dig: clang-format --- plugins/check_dig.c | 35 +++++++++++++++++++++++------------ 1 file changed, 23 insertions(+), 12 deletions(-) diff --git a/plugins/check_dig.c b/plugins/check_dig.c index 2bbd1e05..abca6b24 100644 --- a/plugins/check_dig.c +++ b/plugins/check_dig.c @@ -80,14 +80,16 @@ int main(int argc, char **argv) { textdomain(PACKAGE); /* Set signal handling and alarm */ - if (signal(SIGALRM, runcmd_timeout_alarm_handler) == SIG_ERR) + if (signal(SIGALRM, runcmd_timeout_alarm_handler) == SIG_ERR) { usage_va(_("Cannot catch SIGALRM")); + } /* Parse extra opts if any */ argv = np_extra_opts(&argc, argv, progname); - if (process_arguments(argc, argv) == ERROR) + if (process_arguments(argc, argv) == ERROR) { usage_va(_("Could not parse arguments")); + } /* dig applies the timeout to each try, so we need to work around this */ timeout_interval_dig = timeout_interval / number_tries + number_tries; @@ -121,8 +123,9 @@ int main(int argc, char **argv) { /* loop through the whole 'ANSWER SECTION' */ for (; i < chld_out.lines; i++) { /* get the host address */ - if (verbose) + if (verbose) { printf("%s\n", chld_out.line[i]); + } if (strcasestr(chld_out.line[i], (expected_address == NULL ? query_address : expected_address)) != NULL) { msg = chld_out.line[i]; @@ -130,8 +133,9 @@ int main(int argc, char **argv) { /* Translate output TAB -> SPACE */ t = msg; - while ((t = strchr(t, '\t')) != NULL) + while ((t = strchr(t, '\t')) != NULL) { *t = ' '; + } break; } } @@ -154,7 +158,7 @@ int main(int argc, char **argv) { /* If we get anything on STDERR, at least set warning */ if (chld_err.buflen > 0) { result = max_state(result, STATE_WARNING); - if (!msg) + if (!msg) { for (i = 0; i < chld_err.lines; i++) { msg = strchr(chld_err.line[0], ':'); if (msg) { @@ -162,16 +166,19 @@ int main(int argc, char **argv) { break; } } + } } microsec = deltime(tv); elapsed_time = (double)microsec / 1.0e6; - if (critical_interval > UNDEFINED && elapsed_time > critical_interval) + if (critical_interval > UNDEFINED && elapsed_time > critical_interval) { result = STATE_CRITICAL; + } - else if (warning_interval > UNDEFINED && elapsed_time > warning_interval) + else if (warning_interval > UNDEFINED && elapsed_time > warning_interval) { result = STATE_WARNING; + } printf("DNS %s - %.3f seconds response time (%s)|%s\n", state_text(result), elapsed_time, msg ? msg : _("Probably a non-existent host/domain"), @@ -201,14 +208,16 @@ int process_arguments(int argc, char **argv) { {"use-ipv6", no_argument, 0, '6'}, {0, 0, 0, 0}}; - if (argc < 2) + if (argc < 2) { return ERROR; + } while (1) { c = getopt_long(argc, argv, "hVvt:l:H:w:c:T:p:a:A:46", longopts, &option); - if (c == -1 || c == EOF) + if (c == -1 || c == EOF) { break; + } switch (c) { case 'h': /* help */ @@ -281,10 +290,11 @@ int process_arguments(int argc, char **argv) { host_or_die(argv[c]); dns_server = argv[c]; } else { - if (strcmp(query_transport, "-6") == 0) + if (strcmp(query_transport, "-6") == 0) { dns_server = strdup("::1"); - else + } else { dns_server = strdup("127.0.0.1"); + } } } @@ -292,8 +302,9 @@ int process_arguments(int argc, char **argv) { } int validate_arguments(void) { - if (query_address != NULL) + if (query_address != NULL) { return OK; + } return ERROR; } -- cgit v1.2.3-74-g34f1 From 920d2e0873fa05878df247e40a2b063ca959814a Mon Sep 17 00:00:00 2001 From: Lorenz Kästle <12514511+RincewindsHat@users.noreply.github.com> Date: Mon, 10 Mar 2025 16:34:51 +0100 Subject: Refactor check_dig --- plugins/Makefile.am | 3 +- plugins/check_dig.c | 162 +++++++++++++++++++++---------------------- plugins/check_dig.d/config.h | 40 +++++++++++ 3 files changed, 121 insertions(+), 84 deletions(-) create mode 100644 plugins/check_dig.d/config.h diff --git a/plugins/Makefile.am b/plugins/Makefile.am index 3d5ad1a9..643a4992 100644 --- a/plugins/Makefile.am +++ b/plugins/Makefile.am @@ -55,7 +55,8 @@ EXTRA_DIST = t \ check_ssh.d \ check_dns.d \ check_apt.d \ - check_by_ssh.d + check_by_ssh.d \ + check_dig.d PLUGINHDRS = common.h diff --git a/plugins/check_dig.c b/plugins/check_dig.c index abca6b24..d0903be2 100644 --- a/plugins/check_dig.c +++ b/plugins/check_dig.c @@ -41,40 +41,22 @@ const char *email = "devel@monitoring-plugins.org"; #include "utils.h" #include "runcmd.h" -static int process_arguments(int /*argc*/, char ** /*argv*/); -static int validate_arguments(void); +#include "check_dig.d/config.h" +#include "states.h" + +typedef struct { + int errorcode; + check_dig_config config; +} check_dig_config_wrapper; +static check_dig_config_wrapper process_arguments(int /*argc*/, char ** /*argv*/); +static check_dig_config_wrapper validate_arguments(check_dig_config_wrapper /*config_wrapper*/); + static void print_help(void); void print_usage(void); -#define UNDEFINED 0 -#define DEFAULT_PORT 53 -#define DEFAULT_TRIES 2 - -static char *query_address = NULL; -static char *record_type = "A"; -static char *expected_address = NULL; -static char *dns_server = NULL; -static char *dig_args = ""; -static char *query_transport = ""; -static bool verbose = false; -static int server_port = DEFAULT_PORT; -static int number_tries = DEFAULT_TRIES; -static double warning_interval = UNDEFINED; -static double critical_interval = UNDEFINED; -static struct timeval tv; +static int verbose = 0; int main(int argc, char **argv) { - char *command_line; - output chld_out; - output chld_err; - char *msg = NULL; - size_t i; - char *t; - long microsec; - double elapsed_time; - int result = STATE_UNKNOWN; - int timeout_interval_dig; - setlocale(LC_ALL, ""); bindtextdomain(PACKAGE, LOCALEDIR); textdomain(PACKAGE); @@ -87,36 +69,45 @@ 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_dig_config_wrapper tmp_config = process_arguments(argc, argv); + if (tmp_config.errorcode == ERROR) { usage_va(_("Could not parse arguments")); } + const check_dig_config config = tmp_config.config; + /* dig applies the timeout to each try, so we need to work around this */ - timeout_interval_dig = timeout_interval / number_tries + number_tries; + int timeout_interval_dig = ((int)timeout_interval / config.number_tries) + config.number_tries; + char *command_line; /* get the command to run */ - xasprintf(&command_line, "%s %s %s -p %d @%s %s %s +retry=%d +time=%d", PATH_TO_DIG, dig_args, query_transport, server_port, dns_server, - query_address, record_type, number_tries, timeout_interval_dig); + xasprintf(&command_line, "%s %s %s -p %d @%s %s %s +retry=%d +time=%d", PATH_TO_DIG, config.dig_args, config.query_transport, + config.server_port, config.dns_server, config.query_address, config.record_type, config.number_tries, timeout_interval_dig); alarm(timeout_interval); - gettimeofday(&tv, NULL); + struct timeval start_time; + gettimeofday(&start_time, NULL); if (verbose) { printf("%s\n", command_line); - if (expected_address != NULL) { - printf(_("Looking for: '%s'\n"), expected_address); + if (config.expected_address != NULL) { + printf(_("Looking for: '%s'\n"), config.expected_address); } else { - printf(_("Looking for: '%s'\n"), query_address); + printf(_("Looking for: '%s'\n"), config.query_address); } } + output chld_out; + output chld_err; + char *msg = NULL; + mp_state_enum result = STATE_UNKNOWN; /* run the command */ if (np_runcmd(command_line, &chld_out, &chld_err, 0) != 0) { result = STATE_WARNING; msg = (char *)_("dig returned an error status"); } - for (i = 0; i < chld_out.lines; i++) { + for (size_t i = 0; i < chld_out.lines; i++) { /* the server is responding, we just got the host name... */ if (strstr(chld_out.line[i], ";; ANSWER SECTION:")) { @@ -127,14 +118,15 @@ int main(int argc, char **argv) { printf("%s\n", chld_out.line[i]); } - if (strcasestr(chld_out.line[i], (expected_address == NULL ? query_address : expected_address)) != NULL) { + if (strcasestr(chld_out.line[i], (config.expected_address == NULL ? config.query_address : config.expected_address)) != + NULL) { msg = chld_out.line[i]; result = STATE_OK; /* Translate output TAB -> SPACE */ - t = msg; - while ((t = strchr(t, '\t')) != NULL) { - *t = ' '; + char *temp = msg; + while ((temp = strchr(temp, '\t')) != NULL) { + *temp = ' '; } break; } @@ -159,7 +151,7 @@ int main(int argc, char **argv) { if (chld_err.buflen > 0) { result = max_state(result, STATE_WARNING); if (!msg) { - for (i = 0; i < chld_err.lines; i++) { + for (size_t i = 0; i < chld_err.lines; i++) { msg = strchr(chld_err.line[0], ':'); if (msg) { msg++; @@ -169,29 +161,26 @@ int main(int argc, char **argv) { } } - microsec = deltime(tv); - elapsed_time = (double)microsec / 1.0e6; + long microsec = deltime(start_time); + double elapsed_time = (double)microsec / 1.0e6; - if (critical_interval > UNDEFINED && elapsed_time > critical_interval) { + if (config.critical_interval > UNDEFINED && elapsed_time > config.critical_interval) { result = STATE_CRITICAL; } - else if (warning_interval > UNDEFINED && elapsed_time > warning_interval) { + else if (config.warning_interval > UNDEFINED && elapsed_time > config.warning_interval) { result = STATE_WARNING; } printf("DNS %s - %.3f seconds response time (%s)|%s\n", state_text(result), elapsed_time, msg ? msg : _("Probably a non-existent host/domain"), - fperfdata("time", elapsed_time, "s", (warning_interval > UNDEFINED ? true : false), warning_interval, - (critical_interval > UNDEFINED ? true : false), critical_interval, true, 0, false, 0)); - return result; + fperfdata("time", elapsed_time, "s", (config.warning_interval > UNDEFINED), config.warning_interval, + (config.critical_interval > UNDEFINED), config.critical_interval, true, 0, false, 0)); + exit(result); } /* process command-line arguments */ -int process_arguments(int argc, char **argv) { - int c; - - int option = 0; +check_dig_config_wrapper process_arguments(int argc, char **argv) { static struct option longopts[] = {{"hostname", required_argument, 0, 'H'}, {"query_address", required_argument, 0, 'l'}, {"warning", required_argument, 0, 'w'}, @@ -208,18 +197,25 @@ int process_arguments(int argc, char **argv) { {"use-ipv6", no_argument, 0, '6'}, {0, 0, 0, 0}}; + check_dig_config_wrapper result = { + .errorcode = OK, + .config = check_dig_config_init(), + }; + if (argc < 2) { - return ERROR; + result.errorcode = ERROR; + return result; } - while (1) { - c = getopt_long(argc, argv, "hVvt:l:H:w:c:T:p:a:A:46", longopts, &option); + int option = 0; + while (true) { + int option_index = getopt_long(argc, argv, "hVvt:l:H:w:c:T:p:a:A:46", longopts, &option); - 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); @@ -228,28 +224,28 @@ int process_arguments(int argc, char **argv) { exit(STATE_UNKNOWN); case 'H': /* hostname */ host_or_die(optarg); - dns_server = optarg; + result.config.dns_server = optarg; break; case 'p': /* server port */ if (is_intpos(optarg)) { - server_port = atoi(optarg); + result.config.server_port = atoi(optarg); } else { usage_va(_("Port must be a positive integer - %s"), optarg); } break; case 'l': /* address to lookup */ - query_address = optarg; + result.config.query_address = optarg; break; case 'w': /* warning */ if (is_nonnegative(optarg)) { - warning_interval = strtod(optarg, NULL); + result.config.warning_interval = strtod(optarg, NULL); } else { usage_va(_("Warning interval must be a positive integer - %s"), optarg); } break; case 'c': /* critical */ if (is_nonnegative(optarg)) { - critical_interval = strtod(optarg, NULL); + result.config.critical_interval = strtod(optarg, NULL); } else { usage_va(_("Critical interval must be a positive integer - %s"), optarg); } @@ -262,50 +258,50 @@ int process_arguments(int argc, char **argv) { } break; case 'A': /* dig arguments */ - dig_args = strdup(optarg); + result.config.dig_args = strdup(optarg); break; case 'v': /* verbose */ - verbose = true; + verbose++; break; case 'T': - record_type = optarg; + result.config.record_type = optarg; break; case 'a': - expected_address = optarg; + result.config.expected_address = optarg; break; case '4': - query_transport = "-4"; + result.config.query_transport = "-4"; break; case '6': - query_transport = "-6"; + result.config.query_transport = "-6"; break; default: /* usage5 */ usage5(); } } - c = optind; - if (dns_server == NULL) { - if (c < argc) { - host_or_die(argv[c]); - dns_server = argv[c]; + int index = optind; + if (result.config.dns_server == NULL) { + if (index < argc) { + host_or_die(argv[index]); + result.config.dns_server = argv[index]; } else { - if (strcmp(query_transport, "-6") == 0) { - dns_server = strdup("::1"); + if (strcmp(result.config.query_transport, "-6") == 0) { + result.config.dns_server = strdup("::1"); } else { - dns_server = strdup("127.0.0.1"); + result.config.dns_server = strdup("127.0.0.1"); } } } - return validate_arguments(); + return validate_arguments(result); } -int validate_arguments(void) { - if (query_address != NULL) { - return OK; +check_dig_config_wrapper validate_arguments(check_dig_config_wrapper config_wrapper) { + if (config_wrapper.config.query_address == NULL) { + config_wrapper.errorcode = ERROR; } - return ERROR; + return config_wrapper; } void print_help(void) { diff --git a/plugins/check_dig.d/config.h b/plugins/check_dig.d/config.h new file mode 100644 index 00000000..a570b633 --- /dev/null +++ b/plugins/check_dig.d/config.h @@ -0,0 +1,40 @@ +#pragma once + +#include "../../config.h" +#include + +#define UNDEFINED 0 +#define DEFAULT_PORT 53 +#define DEFAULT_TRIES 2 + +typedef struct { + char *query_address; + char *record_type; + char *expected_address; + char *dns_server; + char *query_transport; + int server_port; + char *dig_args; + int number_tries; + + double warning_interval; + double critical_interval; +} check_dig_config; + +check_dig_config check_dig_config_init() { + check_dig_config tmp = { + .query_address = NULL, + .record_type = "A", + .expected_address = NULL, + .dns_server = NULL, + .query_transport = "", + .server_port = DEFAULT_PORT, + .dig_args = "", + .number_tries = DEFAULT_TRIES, + + .warning_interval = UNDEFINED, + .critical_interval = UNDEFINED, + + }; + return tmp; +} -- cgit v1.2.3-74-g34f1 From 897fef937096c6aae32f9cd80d7b867558596bc5 Mon Sep 17 00:00:00 2001 From: Lorenz Kästle <12514511+RincewindsHat@users.noreply.github.com> Date: Mon, 10 Mar 2025 20:54:52 +0100 Subject: check_smtp: small improvements --- plugins/check_smtp.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/plugins/check_smtp.c b/plugins/check_smtp.c index ac0aa45d..324549d4 100644 --- a/plugins/check_smtp.c +++ b/plugins/check_smtp.c @@ -423,7 +423,7 @@ int main(int argc, char **argv) { break; } break; - } while (0); + } while (false); } else { result = STATE_CRITICAL; xasprintf(&error_msg, _("only authtype LOGIN is supported, ")); @@ -462,7 +462,7 @@ int main(int argc, char **argv) { /* process command-line arguments */ check_smtp_config_wrapper process_arguments(int argc, char **argv) { enum { - SNI_OPTION + SNI_OPTION = CHAR_MAX + 1 }; int option = 0; -- cgit v1.2.3-74-g34f1 From 5cf53de34fa410702ca59437cdf3f304366c3c55 Mon Sep 17 00:00:00 2001 From: Lorenz Kästle <12514511+RincewindsHat@users.noreply.github.com> Date: Mon, 10 Mar 2025 20:56:09 +0100 Subject: check_smtp: fix positional host logic --- plugins/check_smtp.c | 2 ++ plugins/check_smtp.d/config.h | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/plugins/check_smtp.c b/plugins/check_smtp.c index 324549d4..fd492294 100644 --- a/plugins/check_smtp.c +++ b/plugins/check_smtp.c @@ -697,6 +697,8 @@ check_smtp_config_wrapper process_arguments(int argc, char **argv) { } else { usage2(_("Invalid hostname/address"), argv[c]); } + } else { + result.config.server_address = strdup("localhost"); } } diff --git a/plugins/check_smtp.d/config.h b/plugins/check_smtp.d/config.h index c8660445..0a6511ef 100644 --- a/plugins/check_smtp.d/config.h +++ b/plugins/check_smtp.d/config.h @@ -52,7 +52,7 @@ typedef struct { check_smtp_config check_smtp_config_init() { check_smtp_config tmp = { .server_port = SMTP_PORT, - .server_address = strdup("localhost"), + .server_address = NULL, .localhostname = NULL, .server_expect = SMTP_EXPECT, -- cgit v1.2.3-74-g34f1 From 6cd097921f0c5016fcae60b38dfb88c412e4bb20 Mon Sep 17 00:00:00 2001 From: Lorenz Kästle <12514511+RincewindsHat@users.noreply.github.com> Date: Mon, 10 Mar 2025 21:27:50 +0100 Subject: Allow setting of port independent of argument position again --- plugins/check_smtp.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/plugins/check_smtp.c b/plugins/check_smtp.c index fd492294..44b735f9 100644 --- a/plugins/check_smtp.c +++ b/plugins/check_smtp.c @@ -517,6 +517,7 @@ check_smtp_config_wrapper process_arguments(int argc, char **argv) { int command_size = 0; int response_size = 0; bool implicit_tls = false; + int server_port_option = 0; while (true) { int opt_index = getopt_long(argc, argv, "+hVv46Lrt:p:f:e:c:w:H:C:R:sSD:F:A:U:P:q", longopts, &option); @@ -534,7 +535,7 @@ check_smtp_config_wrapper process_arguments(int argc, char **argv) { break; case 'p': /* port */ if (is_intpos(optarg)) { - result.config.server_port = atoi(optarg); + server_port_option = atoi(optarg); } else { usage4(_("Port must be a positive integer")); } @@ -710,6 +711,10 @@ check_smtp_config_wrapper process_arguments(int argc, char **argv) { } } + if (server_port_option != 0) { + result.config.server_port = server_port_option; + } + return result; } -- cgit v1.2.3-74-g34f1 From 1584eb6a62f3ce546f886c2568dc967e33897f6b Mon Sep 17 00:00:00 2001 From: Lorenz Kästle <12514511+RincewindsHat@users.noreply.github.com> Date: Mon, 10 Mar 2025 21:57:31 +0100 Subject: check_cluster: clang-format --- plugins/check_cluster.c | 24 ++++++++++++++++-------- 1 file changed, 16 insertions(+), 8 deletions(-) diff --git a/plugins/check_cluster.c b/plugins/check_cluster.c index b40c38c7..d6c4b1c5 100644 --- a/plugins/check_cluster.c +++ b/plugins/check_cluster.c @@ -72,13 +72,15 @@ int main(int argc, char **argv) { /* Parse extra opts if any */ argv = np_extra_opts(&argc, argv, progname); - if (process_arguments(argc, argv) == ERROR) + if (process_arguments(argc, argv) == ERROR) { usage(_("Could not parse arguments")); + } /* Initialize the thresholds */ set_thresholds(&thresholds, warn_threshold, crit_threshold); - if (verbose) + if (verbose) { print_thresholds("check_cluster", thresholds); + } /* check the data values */ for (ptr = strtok(data_vals, ","); ptr != NULL; ptr = strtok(NULL, ",")) { @@ -145,15 +147,17 @@ int process_arguments(int argc, char **argv) { {"help", no_argument, 0, 'H'}, {0, 0, 0, 0}}; /* no options were supplied */ - if (argc < 2) + if (argc < 2) { return ERROR; + } while (1) { c = getopt_long(argc, argv, "hHsvVw:c:d:l:", longopts, &option); - if (c == -1 || c == EOF || c == 1) + if (c == -1 || c == EOF || c == 1) { break; + } switch (c) { @@ -177,12 +181,15 @@ int process_arguments(int argc, char **argv) { data_vals = (char *)strdup(optarg); /* validate data */ for (ptr = data_vals; ptr != NULL; ptr += 2) { - if (ptr[0] < '0' || ptr[0] > '3') + if (ptr[0] < '0' || ptr[0] > '3') { return ERROR; - if (ptr[1] == '\0') + } + if (ptr[1] == '\0') { break; - if (ptr[1] != ',') + } + if (ptr[1] != ',') { return ERROR; + } } break; @@ -210,8 +217,9 @@ int process_arguments(int argc, char **argv) { } } - if (data_vals == NULL) + if (data_vals == NULL) { return ERROR; + } return OK; } -- cgit v1.2.3-74-g34f1 From 1a97496a83562b1d354609226b05857717c5ab5a Mon Sep 17 00:00:00 2001 From: Lorenz Kästle <12514511+RincewindsHat@users.noreply.github.com> Date: Mon, 10 Mar 2025 22:07:29 +0100 Subject: check_cluster: general refactoring --- plugins/check_cluster.c | 41 +++++++++++++---------------------------- 1 file changed, 13 insertions(+), 28 deletions(-) diff --git a/plugins/check_cluster.c b/plugins/check_cluster.c index d6c4b1c5..72acde2e 100644 --- a/plugins/check_cluster.c +++ b/plugins/check_cluster.c @@ -60,11 +60,6 @@ static int verbose = 0; static int process_arguments(int /*argc*/, char ** /*argv*/); int main(int argc, char **argv) { - char *ptr; - int data_val; - int return_code = STATE_OK; - thresholds *thresholds = NULL; - setlocale(LC_ALL, ""); bindtextdomain(PACKAGE, LOCALEDIR); textdomain(PACKAGE); @@ -76,14 +71,16 @@ int main(int argc, char **argv) { usage(_("Could not parse arguments")); } + thresholds *thresholds = NULL; /* Initialize the thresholds */ set_thresholds(&thresholds, warn_threshold, crit_threshold); if (verbose) { print_thresholds("check_cluster", thresholds); } + int data_val; /* check the data values */ - for (ptr = strtok(data_vals, ","); ptr != NULL; ptr = strtok(NULL, ",")) { + for (char *ptr = strtok(data_vals, ","); ptr != NULL; ptr = strtok(NULL, ",")) { data_val = atoi(ptr); @@ -121,6 +118,7 @@ int main(int argc, char **argv) { } } + int return_code = STATE_OK; /* return the status of the cluster */ if (check_type == CHECK_SERVICES) { return_code = get_status(total_services_warning + total_services_unknown + total_services_critical, thresholds); @@ -133,13 +131,10 @@ int main(int argc, char **argv) { total_hosts_up, total_hosts_down, total_hosts_unreachable); } - return return_code; + exit(return_code); } int process_arguments(int argc, char **argv) { - int c; - char *ptr; - int option = 0; static struct option longopts[] = {{"data", required_argument, 0, 'd'}, {"warning", required_argument, 0, 'w'}, {"critical", required_argument, 0, 'c'}, {"label", required_argument, 0, 'l'}, {"host", no_argument, 0, 'h'}, {"service", no_argument, 0, 's'}, @@ -151,36 +146,31 @@ int process_arguments(int argc, char **argv) { return ERROR; } - while (1) { - - c = getopt_long(argc, argv, "hHsvVw:c:d:l:", longopts, &option); + int option = 0; + while (true) { + int option_index = getopt_long(argc, argv, "hHsvVw:c:d:l:", longopts, &option); - if (c == -1 || c == EOF || c == 1) { + if (option_index == -1 || option_index == EOF || option_index == 1) { break; } - switch (c) { - + switch (option_index) { case 'h': /* host cluster */ check_type = CHECK_HOSTS; break; - case 's': /* service cluster */ check_type = CHECK_SERVICES; break; - case 'w': /* warning threshold */ warn_threshold = strdup(optarg); break; - case 'c': /* warning threshold */ crit_threshold = strdup(optarg); break; - case 'd': /* data values */ - data_vals = (char *)strdup(optarg); + data_vals = strdup(optarg); /* validate data */ - for (ptr = data_vals; ptr != NULL; ptr += 2) { + for (char *ptr = data_vals; ptr != NULL; ptr += 2) { if (ptr[0] < '0' || ptr[0] > '3') { return ERROR; } @@ -192,25 +182,20 @@ int process_arguments(int argc, char **argv) { } } break; - case 'l': /* text label */ - label = (char *)strdup(optarg); + label = strdup(optarg); break; - case 'v': /* verbose */ verbose++; break; - case 'V': /* version */ print_revision(progname, NP_VERSION); exit(STATE_UNKNOWN); break; - case 'H': /* help */ print_help(); exit(STATE_UNKNOWN); break; - default: return ERROR; break; -- cgit v1.2.3-74-g34f1 From 2ce110bf57f5a412a48fd8baf4d5e498e0acc6c6 Mon Sep 17 00:00:00 2001 From: Lorenz Kästle <12514511+RincewindsHat@users.noreply.github.com> Date: Mon, 10 Mar 2025 22:49:38 +0100 Subject: refactor check_cluster --- plugins/Makefile.am | 3 +- plugins/check_cluster.c | 100 ++++++++++++++++++++------------------- plugins/check_cluster.d/config.h | 27 +++++++++++ 3 files changed, 81 insertions(+), 49 deletions(-) create mode 100644 plugins/check_cluster.d/config.h diff --git a/plugins/Makefile.am b/plugins/Makefile.am index 41487131..be650089 100644 --- a/plugins/Makefile.am +++ b/plugins/Makefile.am @@ -57,7 +57,8 @@ EXTRA_DIST = t \ check_apt.d \ check_by_ssh.d \ check_smtp.d \ - check_dig.d + check_dig.d \ + check_cluster.d PLUGINHDRS = common.h diff --git a/plugins/check_cluster.c b/plugins/check_cluster.c index 72acde2e..9b695499 100644 --- a/plugins/check_cluster.c +++ b/plugins/check_cluster.c @@ -29,35 +29,18 @@ const char *email = "devel@monitoring-plugins.org"; #include "common.h" #include "utils.h" #include "utils_base.h" - -enum { - CHECK_SERVICES = 1, - CHECK_HOSTS = 2 -}; +#include "check_cluster.d/config.h" static void print_help(void); void print_usage(void); -static int total_services_ok = 0; -static int total_services_warning = 0; -static int total_services_unknown = 0; -static int total_services_critical = 0; - -static int total_hosts_up = 0; -static int total_hosts_down = 0; -static int total_hosts_unreachable = 0; - -static char *warn_threshold; -static char *crit_threshold; - -static int check_type = CHECK_SERVICES; - -static char *data_vals = NULL; -static char *label = NULL; - static int verbose = 0; -static int process_arguments(int /*argc*/, char ** /*argv*/); +typedef struct { + int errorcode; + check_cluster_config config; +} check_cluster_config_wrapper; +static check_cluster_config_wrapper process_arguments(int /*argc*/, char ** /*argv*/); int main(int argc, char **argv) { setlocale(LC_ALL, ""); @@ -67,24 +50,32 @@ 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_cluster_config_wrapper tmp_config = process_arguments(argc, argv); + if (tmp_config.errorcode == ERROR) { usage(_("Could not parse arguments")); } - thresholds *thresholds = NULL; + const check_cluster_config config = tmp_config.config; + /* Initialize the thresholds */ - set_thresholds(&thresholds, warn_threshold, crit_threshold); if (verbose) { - print_thresholds("check_cluster", thresholds); + print_thresholds("check_cluster", config.thresholds); } int data_val; + int total_services_ok = 0; + int total_services_warning = 0; + int total_services_unknown = 0; + int total_services_critical = 0; + int total_hosts_up = 0; + int total_hosts_down = 0; + int total_hosts_unreachable = 0; /* check the data values */ - for (char *ptr = strtok(data_vals, ","); ptr != NULL; ptr = strtok(NULL, ",")) { + for (char *ptr = strtok(config.data_vals, ","); ptr != NULL; ptr = strtok(NULL, ",")) { data_val = atoi(ptr); - if (check_type == CHECK_SERVICES) { + if (config.check_type == CHECK_SERVICES) { switch (data_val) { case 0: total_services_ok++; @@ -120,33 +111,41 @@ int main(int argc, char **argv) { int return_code = STATE_OK; /* return the status of the cluster */ - if (check_type == CHECK_SERVICES) { - return_code = get_status(total_services_warning + total_services_unknown + total_services_critical, thresholds); + if (config.check_type == CHECK_SERVICES) { + return_code = get_status(total_services_warning + total_services_unknown + total_services_critical, config.thresholds); printf("CLUSTER %s: %s: %d ok, %d warning, %d unknown, %d critical\n", state_text(return_code), - (label == NULL) ? "Service cluster" : label, total_services_ok, total_services_warning, total_services_unknown, + (config.label == NULL) ? "Service cluster" : config.label, total_services_ok, total_services_warning, total_services_unknown, total_services_critical); } else { - return_code = get_status(total_hosts_down + total_hosts_unreachable, thresholds); - printf("CLUSTER %s: %s: %d up, %d down, %d unreachable\n", state_text(return_code), (label == NULL) ? "Host cluster" : label, - total_hosts_up, total_hosts_down, total_hosts_unreachable); + return_code = get_status(total_hosts_down + total_hosts_unreachable, config.thresholds); + printf("CLUSTER %s: %s: %d up, %d down, %d unreachable\n", state_text(return_code), + (config.label == NULL) ? "Host cluster" : config.label, total_hosts_up, total_hosts_down, total_hosts_unreachable); } exit(return_code); } -int process_arguments(int argc, char **argv) { +check_cluster_config_wrapper process_arguments(int argc, char **argv) { static struct option longopts[] = {{"data", required_argument, 0, 'd'}, {"warning", required_argument, 0, 'w'}, {"critical", required_argument, 0, 'c'}, {"label", required_argument, 0, 'l'}, {"host", no_argument, 0, 'h'}, {"service", no_argument, 0, 's'}, {"verbose", no_argument, 0, 'v'}, {"version", no_argument, 0, 'V'}, {"help", no_argument, 0, 'H'}, {0, 0, 0, 0}}; + check_cluster_config_wrapper result = { + .errorcode = OK, + .config = check_cluster_config_init(), + }; + /* no options were supplied */ if (argc < 2) { - return ERROR; + result.errorcode = ERROR; + return result; } int option = 0; + char *warn_threshold = NULL; + char *crit_threshold = NULL; while (true) { int option_index = getopt_long(argc, argv, "hHsvVw:c:d:l:", longopts, &option); @@ -156,10 +155,10 @@ int process_arguments(int argc, char **argv) { switch (option_index) { case 'h': /* host cluster */ - check_type = CHECK_HOSTS; + result.config.check_type = CHECK_HOSTS; break; case 's': /* service cluster */ - check_type = CHECK_SERVICES; + result.config.check_type = CHECK_SERVICES; break; case 'w': /* warning threshold */ warn_threshold = strdup(optarg); @@ -168,22 +167,24 @@ int process_arguments(int argc, char **argv) { crit_threshold = strdup(optarg); break; case 'd': /* data values */ - data_vals = strdup(optarg); + result.config.data_vals = strdup(optarg); /* validate data */ - for (char *ptr = data_vals; ptr != NULL; ptr += 2) { + for (char *ptr = result.config.data_vals; ptr != NULL; ptr += 2) { if (ptr[0] < '0' || ptr[0] > '3') { - return ERROR; + result.errorcode = ERROR; + return result; } if (ptr[1] == '\0') { break; } if (ptr[1] != ',') { - return ERROR; + result.errorcode = ERROR; + return result; } } break; case 'l': /* text label */ - label = strdup(optarg); + result.config.label = strdup(optarg); break; case 'v': /* verbose */ verbose++; @@ -197,16 +198,19 @@ int process_arguments(int argc, char **argv) { exit(STATE_UNKNOWN); break; default: - return ERROR; + result.errorcode = ERROR; + return result; break; } } - if (data_vals == NULL) { - return ERROR; + if (result.config.data_vals == NULL) { + result.errorcode = ERROR; + return result; } - return OK; + set_thresholds(&result.config.thresholds, warn_threshold, crit_threshold); + return result; } void print_help(void) { diff --git a/plugins/check_cluster.d/config.h b/plugins/check_cluster.d/config.h new file mode 100644 index 00000000..fc386415 --- /dev/null +++ b/plugins/check_cluster.d/config.h @@ -0,0 +1,27 @@ +#pragma once + +#include "../../config.h" +#include "../../lib/thresholds.h" +#include + +enum { + CHECK_SERVICES = 1, + CHECK_HOSTS = 2 +}; + +typedef struct { + char *data_vals; + thresholds *thresholds; + int check_type; + char *label; +} check_cluster_config; + +check_cluster_config check_cluster_config_init() { + check_cluster_config tmp = { + .data_vals = NULL, + .thresholds = NULL, + .check_type = CHECK_SERVICES, + .label = NULL, + }; + return tmp; +} -- cgit v1.2.3-74-g34f1 From 4f4966220bbdf18cd1d525d0ef53faef708ce2bb Mon Sep 17 00:00:00 2001 From: Lorenz Kästle <12514511+RincewindsHat@users.noreply.github.com> Date: Tue, 11 Mar 2025 02:05:13 +0100 Subject: check_fping: clang-format --- plugins/check_fping.c | 122 +++++++++++++++++++++++++++----------------------- 1 file changed, 67 insertions(+), 55 deletions(-) diff --git a/plugins/check_fping.c b/plugins/check_fping.c index c1d03ece..b85397d5 100644 --- a/plugins/check_fping.c +++ b/plugins/check_fping.c @@ -91,39 +91,47 @@ int main(int argc, char **argv) { /* Parse extra opts if any */ argv = np_extra_opts(&argc, argv, progname); - if (process_arguments(argc, argv) == ERROR) + if (process_arguments(argc, argv) == ERROR) { usage4(_("Could not parse arguments")); + } server = strscpy(server, server_name); /* compose the command */ - if (target_timeout) + if (target_timeout) { xasprintf(&option_string, "%s-t %d ", option_string, target_timeout); - if (packet_interval) + } + if (packet_interval) { xasprintf(&option_string, "%s-p %d ", option_string, packet_interval); - if (sourceip) + } + if (sourceip) { xasprintf(&option_string, "%s-S %s ", option_string, sourceip); - if (sourceif) + } + if (sourceif) { xasprintf(&option_string, "%s-I %s ", option_string, sourceif); - if (dontfrag) + } + if (dontfrag) { xasprintf(&option_string, "%s-M ", option_string); - if (randomize_packet_data) + } + if (randomize_packet_data) { xasprintf(&option_string, "%s-R ", option_string); - + } #ifdef PATH_TO_FPING6 - if (address_family != AF_INET && is_inet6_addr(server)) + if (address_family != AF_INET && is_inet6_addr(server)) { fping_prog = strdup(PATH_TO_FPING6); - else + } else { fping_prog = strdup(PATH_TO_FPING); + } #else fping_prog = strdup(PATH_TO_FPING); #endif xasprintf(&command_line, "%s %s-b %d -c %d %s", fping_prog, option_string, packet_size, packet_count, server); - if (verbose) + if (verbose) { printf("%s\n", command_line); + } /* run the command */ child_process = spopen(command_line); @@ -138,16 +146,18 @@ int main(int argc, char **argv) { } while (fgets(input_buffer, MAX_INPUT_BUFFER - 1, child_process)) { - if (verbose) + if (verbose) { printf("%s", input_buffer); + } status = max_state(status, textscan(input_buffer)); } /* If we get anything on STDERR, at least set warning */ while (fgets(input_buffer, MAX_INPUT_BUFFER - 1, child_stderr)) { status = max_state(status, STATE_WARNING); - if (verbose) + if (verbose) { printf("%s", input_buffer); + } status = max_state(status, textscan(input_buffer)); } (void)fclose(child_stderr); @@ -221,16 +231,17 @@ int textscan(char *buf) { rtastr = 1 + index(rtastr, '/'); loss = strtod(losstr, NULL); rta = strtod(rtastr, NULL); - if (cpl_p && loss > cpl) + if (cpl_p && loss > cpl) { status = STATE_CRITICAL; - else if (crta_p && rta > crta) + } else if (crta_p && rta > crta) { status = STATE_CRITICAL; - else if (wpl_p && loss > wpl) + } else if (wpl_p && loss > wpl) { status = STATE_WARNING; - else if (wrta_p && rta > wrta) + } else if (wrta_p && rta > wrta) { status = STATE_WARNING; - else + } else { status = STATE_OK; + } die(status, _("FPING %s - %s (loss=%.0f%%, rta=%f ms)|%s %s\n"), state_text(status), server_name, loss, rta, perfdata("loss", (long int)loss, "%", wpl_p, wpl, cpl_p, cpl, true, 0, true, 100), fperfdata("rta", rta / 1.0e3, "s", wrta_p, wrta / 1.0e3, crta_p, crta / 1.0e3, true, 0, false, 0)); @@ -241,19 +252,21 @@ int textscan(char *buf) { losstr = strstr(buf, "="); xmtstr = 1 + losstr; xmt = strtod(xmtstr, NULL); - if (xmt == 0) + if (xmt == 0) { die(STATE_CRITICAL, _("FPING CRITICAL - %s is down\n"), server_name); + } losstr = 1 + strstr(losstr, "/"); losstr = 1 + strstr(losstr, "/"); loss = strtod(losstr, NULL); - if (atoi(losstr) == 100) + if (atoi(losstr) == 100) { status = STATE_CRITICAL; - else if (cpl_p && loss > cpl) + } else if (cpl_p && loss > cpl) { status = STATE_CRITICAL; - else if (wpl_p && loss > wpl) + } else if (wpl_p && loss > wpl) { status = STATE_WARNING; - else + } else { status = STATE_OK; + } /* loss=%.0f%%;%d;%d;0;100 */ die(status, _("FPING %s - %s (loss=%.0f%% )|%s\n"), state_text(status), server_name, loss, perfdata("loss", (long int)loss, "%", wpl_p, wpl, cpl_p, cpl, true, 0, true, 100)); @@ -271,30 +284,20 @@ int process_arguments(int argc, char **argv) { char *rv[2]; int option = 0; - static struct option longopts[] = {{"hostname", required_argument, 0, 'H'}, - {"sourceip", required_argument, 0, 'S'}, - {"sourceif", required_argument, 0, 'I'}, - {"critical", required_argument, 0, 'c'}, - {"warning", required_argument, 0, 'w'}, - {"alive", no_argument, 0, 'a'}, - {"bytes", required_argument, 0, 'b'}, - {"number", required_argument, 0, 'n'}, - {"target-timeout", required_argument, 0, 'T'}, - {"interval", required_argument, 0, 'i'}, - {"verbose", no_argument, 0, 'v'}, - {"version", no_argument, 0, 'V'}, - {"help", no_argument, 0, 'h'}, - {"use-ipv4", no_argument, 0, '4'}, - {"use-ipv6", no_argument, 0, '6'}, - {"dontfrag", no_argument, 0, 'M'}, - {"random", no_argument, 0, 'R'}, - {0, 0, 0, 0}}; + static struct option longopts[] = { + {"hostname", required_argument, 0, 'H'}, {"sourceip", required_argument, 0, 'S'}, {"sourceif", required_argument, 0, 'I'}, + {"critical", required_argument, 0, 'c'}, {"warning", required_argument, 0, 'w'}, {"alive", no_argument, 0, 'a'}, + {"bytes", required_argument, 0, 'b'}, {"number", required_argument, 0, 'n'}, {"target-timeout", required_argument, 0, 'T'}, + {"interval", required_argument, 0, 'i'}, {"verbose", no_argument, 0, 'v'}, {"version", no_argument, 0, 'V'}, + {"help", no_argument, 0, 'h'}, {"use-ipv4", no_argument, 0, '4'}, {"use-ipv6", no_argument, 0, '6'}, + {"dontfrag", no_argument, 0, 'M'}, {"random", no_argument, 0, 'R'}, {0, 0, 0, 0}}; rv[PL] = NULL; rv[RTA] = NULL; - if (argc < 2) + if (argc < 2) { return ERROR; + } if (!is_option(argv[1])) { server_name = argv[1]; @@ -306,8 +309,9 @@ int process_arguments(int argc, char **argv) { while (1) { c = getopt_long(argc, argv, "+hVvaH:S:c:w:b:n:T:i:I:M:R:46", longopts, &option); - if (c == -1 || c == EOF || c == 1) + if (c == -1 || c == EOF || c == 1) { break; + } switch (c) { case '?': /* print short usage statement if args not parsable */ @@ -376,28 +380,32 @@ int process_arguments(int argc, char **argv) { } break; case 'b': /* bytes per packet */ - if (is_intpos(optarg)) + if (is_intpos(optarg)) { packet_size = atoi(optarg); - else + } else { usage(_("Packet size must be a positive integer")); + } break; case 'n': /* number of packets */ - if (is_intpos(optarg)) + if (is_intpos(optarg)) { packet_count = atoi(optarg); - else + } else { usage(_("Packet count must be a positive integer")); + } break; case 'T': /* timeout in msec */ - if (is_intpos(optarg)) + if (is_intpos(optarg)) { target_timeout = atoi(optarg); - else + } else { usage(_("Target timeout must be a positive integer")); + } break; case 'i': /* interval in msec */ - if (is_intpos(optarg)) + if (is_intpos(optarg)) { packet_interval = atoi(optarg); - else + } else { usage(_("Interval must be a positive integer")); + } break; case 'R': randomize_packet_data = true; @@ -408,8 +416,9 @@ int process_arguments(int argc, char **argv) { } } - if (server_name == NULL) + if (server_name == NULL) { usage4(_("Hostname was not supplied")); + } return OK; } @@ -419,15 +428,18 @@ int get_threshold(char *arg, char *rv[2]) { char *arg2 = NULL; arg1 = strscpy(arg1, arg); - if (strpbrk(arg1, ",:")) + if (strpbrk(arg1, ",:")) { arg2 = 1 + strpbrk(arg1, ",:"); + } if (arg2) { arg1[strcspn(arg1, ",:")] = 0; - if (strstr(arg1, "%") && strstr(arg2, "%")) + if (strstr(arg1, "%") && strstr(arg2, "%")) { die(STATE_UNKNOWN, _("%s: Only one threshold may be packet loss (%s)\n"), progname, arg); - if (!strstr(arg1, "%") && !strstr(arg2, "%")) + } + if (!strstr(arg1, "%") && !strstr(arg2, "%")) { die(STATE_UNKNOWN, _("%s: Only one threshold must be packet loss (%s)\n"), progname, arg); + } } if (arg2 && strstr(arg2, "%")) { -- cgit v1.2.3-74-g34f1 From cf48162487d6f042af084ee436acdd7a2db0cbfd Mon Sep 17 00:00:00 2001 From: Lorenz Kästle <12514511+RincewindsHat@users.noreply.github.com> Date: Tue, 11 Mar 2025 02:43:51 +0100 Subject: Refactor check_fping --- plugins/Makefile.am | 3 +- plugins/check_fping.c | 182 ++++++++++++++++++++--------------------- plugins/check_fping.d/config.h | 58 +++++++++++++ 3 files changed, 147 insertions(+), 96 deletions(-) create mode 100644 plugins/check_fping.d/config.h diff --git a/plugins/Makefile.am b/plugins/Makefile.am index 41487131..25a286c1 100644 --- a/plugins/Makefile.am +++ b/plugins/Makefile.am @@ -57,7 +57,8 @@ EXTRA_DIST = t \ check_apt.d \ check_by_ssh.d \ check_smtp.d \ - check_dig.d + check_dig.d \ + check_fping.d PLUGINHDRS = common.h diff --git a/plugins/check_fping.c b/plugins/check_fping.c index b85397d5..ec7abb67 100644 --- a/plugins/check_fping.c +++ b/plugins/check_fping.c @@ -38,52 +38,29 @@ const char *email = "devel@monitoring-plugins.org"; #include "netutils.h" #include "utils.h" #include +#include "check_fping.d/config.h" +#include "states.h" enum { - PACKET_COUNT = 1, - PACKET_SIZE = 56, PL = 0, RTA = 1 }; -static int textscan(char *buf); -static int process_arguments(int /*argc*/, char ** /*argv*/); +static mp_state_enum textscan(char *buf, const char * /*server_name*/, bool /*crta_p*/, double /*crta*/, bool /*wrta_p*/, double /*wrta*/, + bool /*cpl_p*/, int /*cpl*/, bool /*wpl_p*/, int /*wpl*/, bool /*alive_p*/); + +typedef struct { + int errorcode; + check_fping_config config; +} check_fping_config_wrapper; +static check_fping_config_wrapper process_arguments(int /*argc*/, char ** /*argv*/); static int get_threshold(char *arg, char *rv[2]); static void print_help(void); void print_usage(void); -static char *server_name = NULL; -static char *sourceip = NULL; -static char *sourceif = NULL; -static int packet_size = PACKET_SIZE; -static int packet_count = PACKET_COUNT; -static int target_timeout = 0; -static int packet_interval = 0; static bool verbose = false; -static bool dontfrag = false; -static bool randomize_packet_data = false; -static int cpl; -static int wpl; -static double crta; -static double wrta; -static bool cpl_p = false; -static bool wpl_p = false; -static bool alive_p = false; -static bool crta_p = false; -static bool wrta_p = false; int main(int argc, char **argv) { - /* normally should be int result = STATE_UNKNOWN; */ - - int status = STATE_UNKNOWN; - int result = 0; - char *fping_prog = NULL; - char *server = NULL; - char *command_line = NULL; - char *input_buffer = NULL; - char *option_string = ""; - input_buffer = malloc(MAX_INPUT_BUFFER); - setlocale(LC_ALL, ""); bindtextdomain(PACKAGE, LOCALEDIR); textdomain(PACKAGE); @@ -91,32 +68,38 @@ 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_fping_config_wrapper tmp_config = process_arguments(argc, argv); + if (tmp_config.errorcode == ERROR) { usage4(_("Could not parse arguments")); } - server = strscpy(server, server_name); + const check_fping_config config = tmp_config.config; + + char *server = NULL; + server = strscpy(server, config.server_name); + char *option_string = ""; /* compose the command */ - if (target_timeout) { - xasprintf(&option_string, "%s-t %d ", option_string, target_timeout); + if (config.target_timeout) { + xasprintf(&option_string, "%s-t %d ", option_string, config.target_timeout); } - if (packet_interval) { - xasprintf(&option_string, "%s-p %d ", option_string, packet_interval); + if (config.packet_interval) { + xasprintf(&option_string, "%s-p %d ", option_string, config.packet_interval); } - if (sourceip) { - xasprintf(&option_string, "%s-S %s ", option_string, sourceip); + if (config.sourceip) { + xasprintf(&option_string, "%s-S %s ", option_string, config.sourceip); } - if (sourceif) { - xasprintf(&option_string, "%s-I %s ", option_string, sourceif); + if (config.sourceif) { + xasprintf(&option_string, "%s-I %s ", option_string, config.sourceif); } - if (dontfrag) { + if (config.dontfrag) { xasprintf(&option_string, "%s-M ", option_string); } - if (randomize_packet_data) { + if (config.randomize_packet_data) { xasprintf(&option_string, "%s-R ", option_string); } + char *fping_prog = NULL; #ifdef PATH_TO_FPING6 if (address_family != AF_INET && is_inet6_addr(server)) { fping_prog = strdup(PATH_TO_FPING6); @@ -127,7 +110,8 @@ int main(int argc, char **argv) { fping_prog = strdup(PATH_TO_FPING); #endif - xasprintf(&command_line, "%s %s-b %d -c %d %s", fping_prog, option_string, packet_size, packet_count, server); + char *command_line = NULL; + xasprintf(&command_line, "%s %s-b %d -c %d %s", fping_prog, option_string, config.packet_size, config.packet_count, server); if (verbose) { printf("%s\n", command_line); @@ -145,11 +129,14 @@ int main(int argc, char **argv) { printf(_("Could not open stderr for %s\n"), command_line); } + char *input_buffer = malloc(MAX_INPUT_BUFFER); + mp_state_enum status = STATE_UNKNOWN; while (fgets(input_buffer, MAX_INPUT_BUFFER - 1, child_process)) { if (verbose) { printf("%s", input_buffer); } - status = max_state(status, textscan(input_buffer)); + status = max_state(status, textscan(input_buffer, config.server_name, config.crta_p, config.crta, config.wrta_p, config.wrta, + config.cpl_p, config.cpl, config.wpl_p, config.wpl, config.alive_p)); } /* If we get anything on STDERR, at least set warning */ @@ -158,12 +145,13 @@ int main(int argc, char **argv) { if (verbose) { printf("%s", input_buffer); } - status = max_state(status, textscan(input_buffer)); + status = max_state(status, textscan(input_buffer, config.server_name, config.crta_p, config.crta, config.wrta_p, config.wrta, + config.cpl_p, config.cpl, config.wpl_p, config.wpl, config.alive_p)); } (void)fclose(child_stderr); /* close the pipe */ - result = spclose(child_process); + int result = spclose(child_process); if (result) { /* need to use max_state not max */ status = max_state(status, STATE_WARNING); @@ -182,21 +170,17 @@ int main(int argc, char **argv) { } } - printf("FPING %s - %s\n", state_text(status), server_name); + printf("FPING %s - %s\n", state_text(status), config.server_name); return status; } -int textscan(char *buf) { - char *rtastr = NULL; - char *losstr = NULL; - char *xmtstr = NULL; - double loss; - double rta; - double xmt; - int status = STATE_UNKNOWN; - +mp_state_enum textscan(char *buf, const char *server_name, bool crta_p, double crta, bool wrta_p, double wrta, bool cpl_p, int cpl, + bool wpl_p, int wpl, bool alive_p) { /* stops testing after the first successful reply. */ + double rta; + double loss; + char *rtastr = NULL; if (alive_p && strstr(buf, "avg, 0% loss)")) { rtastr = strstr(buf, "ms ("); rtastr = 1 + index(rtastr, '('); @@ -208,6 +192,10 @@ int textscan(char *buf) { fperfdata("rta", rta / 1.0e3, "s", wrta_p, wrta / 1.0e3, crta_p, crta / 1.0e3, true, 0, false, 0)); } + mp_state_enum status = STATE_UNKNOWN; + char *xmtstr = NULL; + double xmt; + char *losstr = NULL; if (strstr(buf, "not found")) { die(STATE_CRITICAL, _("FPING UNKNOWN - %s not found\n"), server_name); @@ -243,7 +231,7 @@ int textscan(char *buf) { status = STATE_OK; } die(status, _("FPING %s - %s (loss=%.0f%%, rta=%f ms)|%s %s\n"), state_text(status), server_name, loss, rta, - perfdata("loss", (long int)loss, "%", wpl_p, wpl, cpl_p, cpl, true, 0, true, 100), + perfdata("loss", (long int)loss, "%", wpl_p, wpl, cpl_p, cpl, false, 0, false, 0), fperfdata("rta", rta / 1.0e3, "s", wrta_p, wrta / 1.0e3, crta_p, crta / 1.0e3, true, 0, false, 0)); } else if (strstr(buf, "xmt/rcv/%loss")) { @@ -269,7 +257,7 @@ int textscan(char *buf) { } /* loss=%.0f%%;%d;%d;0;100 */ die(status, _("FPING %s - %s (loss=%.0f%% )|%s\n"), state_text(status), server_name, loss, - perfdata("loss", (long int)loss, "%", wpl_p, wpl, cpl_p, cpl, true, 0, true, 100)); + perfdata("loss", (long int)loss, "%", wpl_p, wpl, cpl_p, cpl, false, 0, false, 0)); } else { status = max_state(status, STATE_WARNING); @@ -279,11 +267,7 @@ int textscan(char *buf) { } /* process command-line arguments */ -int process_arguments(int argc, char **argv) { - int c; - char *rv[2]; - - int option = 0; +check_fping_config_wrapper process_arguments(int argc, char **argv) { static struct option longopts[] = { {"hostname", required_argument, 0, 'H'}, {"sourceip", required_argument, 0, 'S'}, {"sourceif", required_argument, 0, 'I'}, {"critical", required_argument, 0, 'c'}, {"warning", required_argument, 0, 'w'}, {"alive", no_argument, 0, 'a'}, @@ -292,32 +276,41 @@ int process_arguments(int argc, char **argv) { {"help", no_argument, 0, 'h'}, {"use-ipv4", no_argument, 0, '4'}, {"use-ipv6", no_argument, 0, '6'}, {"dontfrag", no_argument, 0, 'M'}, {"random", no_argument, 0, 'R'}, {0, 0, 0, 0}}; + char *rv[2]; rv[PL] = NULL; rv[RTA] = NULL; + int option = 0; + + check_fping_config_wrapper result = { + .errorcode = OK, + .config = check_fping_config_init(), + }; + if (argc < 2) { - return ERROR; + result.errorcode = ERROR; + return result; } if (!is_option(argv[1])) { - server_name = argv[1]; + result.config.server_name = argv[1]; argv[1] = argv[0]; argv = &argv[1]; argc--; } while (1) { - c = getopt_long(argc, argv, "+hVvaH:S:c:w:b:n:T:i:I:M:R:46", longopts, &option); + int option_index = getopt_long(argc, argv, "+hVvaH:S:c:w:b:n:T:i:I:M:R:46", longopts, &option); - if (c == -1 || c == EOF || c == 1) { + if (option_index == -1 || option_index == EOF || option_index == 1) { break; } - switch (c) { + switch (option_index) { case '?': /* print short usage statement if args not parsable */ usage5(); case 'a': /* host alive mode */ - alive_p = true; + result.config.alive_p = true; break; case 'h': /* help */ print_help(); @@ -329,19 +322,19 @@ int process_arguments(int argc, char **argv) { verbose = true; break; case 'H': /* hostname */ - if (is_host(optarg) == false) { + if (!is_host(optarg)) { usage2(_("Invalid hostname/address"), optarg); } - server_name = strscpy(server_name, optarg); + result.config.server_name = optarg; break; case 'S': /* sourceip */ - if (is_host(optarg) == false) { + if (!is_host(optarg)) { usage2(_("Invalid hostname/address"), optarg); } - sourceip = strscpy(sourceip, optarg); + result.config.sourceip = optarg; break; case 'I': /* sourceip */ - sourceif = strscpy(sourceif, optarg); + result.config.sourceif = optarg; break; case '4': /* IPv4 only */ address_family = AF_INET; @@ -356,78 +349,77 @@ int process_arguments(int argc, char **argv) { case 'c': get_threshold(optarg, rv); if (rv[RTA]) { - crta = strtod(rv[RTA], NULL); - crta_p = true; + result.config.crta = strtod(rv[RTA], NULL); + result.config.crta_p = true; rv[RTA] = NULL; } if (rv[PL]) { - cpl = atoi(rv[PL]); - cpl_p = true; + result.config.cpl = atoi(rv[PL]); + result.config.cpl_p = true; rv[PL] = NULL; } break; case 'w': get_threshold(optarg, rv); if (rv[RTA]) { - wrta = strtod(rv[RTA], NULL); - wrta_p = true; + result.config.wrta = strtod(rv[RTA], NULL); + result.config.wrta_p = true; rv[RTA] = NULL; } if (rv[PL]) { - wpl = atoi(rv[PL]); - wpl_p = true; + result.config.wpl = atoi(rv[PL]); + result.config.wpl_p = true; rv[PL] = NULL; } break; case 'b': /* bytes per packet */ if (is_intpos(optarg)) { - packet_size = atoi(optarg); + result.config.packet_size = atoi(optarg); } else { usage(_("Packet size must be a positive integer")); } break; case 'n': /* number of packets */ if (is_intpos(optarg)) { - packet_count = atoi(optarg); + result.config.packet_count = atoi(optarg); } else { usage(_("Packet count must be a positive integer")); } break; case 'T': /* timeout in msec */ if (is_intpos(optarg)) { - target_timeout = atoi(optarg); + result.config.target_timeout = atoi(optarg); } else { usage(_("Target timeout must be a positive integer")); } break; case 'i': /* interval in msec */ if (is_intpos(optarg)) { - packet_interval = atoi(optarg); + result.config.packet_interval = atoi(optarg); } else { usage(_("Interval must be a positive integer")); } break; case 'R': - randomize_packet_data = true; + result.config.randomize_packet_data = true; break; case 'M': - dontfrag = true; + result.config.dontfrag = true; break; } } - if (server_name == NULL) { + if (result.config.server_name == NULL) { usage4(_("Hostname was not supplied")); } - return OK; + return result; } int get_threshold(char *arg, char *rv[2]) { - char *arg1 = NULL; char *arg2 = NULL; - arg1 = strscpy(arg1, arg); + char *arg1 = strdup(arg); if (strpbrk(arg1, ",:")) { arg2 = 1 + strpbrk(arg1, ",:"); } diff --git a/plugins/check_fping.d/config.h b/plugins/check_fping.d/config.h new file mode 100644 index 00000000..a0697bf3 --- /dev/null +++ b/plugins/check_fping.d/config.h @@ -0,0 +1,58 @@ +#pragma once + +#include "../../config.h" +#include + +enum { + PACKET_SIZE = 56, + PACKET_COUNT = 1, +}; + +typedef struct { + char *server_name; + char *sourceip; + char *sourceif; + int packet_size; + int packet_count; + int target_timeout; + int packet_interval; + bool randomize_packet_data; + bool dontfrag; + bool alive_p; + + double crta; + bool crta_p; + double wrta; + bool wrta_p; + + int cpl; + bool cpl_p; + int wpl; + bool wpl_p; +} check_fping_config; + +check_fping_config check_fping_config_init() { + check_fping_config tmp = { + .server_name = NULL, + .sourceip = NULL, + .sourceif = NULL, + .packet_size = PACKET_SIZE, + .packet_count = PACKET_COUNT, + .target_timeout = 0, + .packet_interval = 0, + .randomize_packet_data = false, + .dontfrag = false, + .alive_p = false, + + .crta = 0, + .crta_p = false, + .wrta = 0, + .wrta_p = false, + + .cpl = 0, + .cpl_p = false, + .wpl = 0, + .wpl_p = false, + }; + return tmp; +} -- cgit v1.2.3-74-g34f1 From e001fe5b3e50461b79b7b5ea3180cd11507fd615 Mon Sep 17 00:00:00 2001 From: Lorenz Kästle <12514511+RincewindsHat@users.noreply.github.com> Date: Tue, 11 Mar 2025 10:50:02 +0100 Subject: check_hpjd: clang-format --- plugins/check_hpjd.c | 43 ++++++++++++++++++++++++++++--------------- 1 file changed, 28 insertions(+), 15 deletions(-) diff --git a/plugins/check_hpjd.c b/plugins/check_hpjd.c index b39bccff..78f55b7f 100644 --- a/plugins/check_hpjd.c +++ b/plugins/check_hpjd.c @@ -97,8 +97,9 @@ int main(int argc, char **argv) { /* Parse extra opts if any */ argv = np_extra_opts(&argc, argv, progname); - if (process_arguments(argc, argv) == ERROR) + if (process_arguments(argc, argv) == ERROR) { usage4(_("Could not parse arguments")); + } /* removed ' 2>1' at end of command 10/27/1999 - EG */ /* create the query string */ @@ -127,8 +128,9 @@ int main(int argc, char **argv) { while (fgets(input_buffer, MAX_INPUT_BUFFER - 1, child_process)) { /* strip the newline character from the end of the input */ - if (input_buffer[strlen(input_buffer) - 1] == '\n') + if (input_buffer[strlen(input_buffer) - 1] == '\n') { input_buffer[strlen(input_buffer) - 1] = 0; + } line++; @@ -186,16 +188,18 @@ int main(int argc, char **argv) { } /* break out of the read loop if we encounter an error */ - if (result != STATE_OK) + if (result != STATE_OK) { break; + } } /* WARNING if output found on stderr */ if (fgets(input_buffer, MAX_INPUT_BUFFER - 1, child_stderr)) { result = max_state(result, STATE_WARNING); /* remove CRLF */ - if (input_buffer[strlen(input_buffer) - 1] == '\n') + if (input_buffer[strlen(input_buffer) - 1] == '\n') { input_buffer[strlen(input_buffer) - 1] = 0; + } sprintf(errmsg, "%s", input_buffer); } @@ -203,8 +207,9 @@ int main(int argc, char **argv) { (void)fclose(child_stderr); /* close the pipe */ - if (spclose(child_process)) + if (spclose(child_process)) { result = max_state(result, STATE_WARNING); + } /* if there wasn't any output, display an error */ if (line == 0) { @@ -221,8 +226,9 @@ int main(int argc, char **argv) { result = STATE_WARNING; strcpy(errmsg, _("Paper Jam")); } else if (paper_out) { - if (check_paper_out) + if (check_paper_out) { result = STATE_WARNING; + } strcpy(errmsg, _("Out of Paper")); } else if (line_status == OFFLINE) { if (strcmp(errmsg, "POWERSAVE ON") != 0) { @@ -256,20 +262,23 @@ int main(int argc, char **argv) { } } - if (result == STATE_OK) + if (result == STATE_OK) { printf(_("Printer ok - (%s)\n"), display_message); + } else if (result == STATE_UNKNOWN) { printf("%s\n", errmsg); /* if printer could not be reached, escalate to critical */ - if (strstr(errmsg, "Timeout")) + if (strstr(errmsg, "Timeout")) { result = STATE_CRITICAL; + } } - else if (result == STATE_WARNING) + else if (result == STATE_WARNING) { printf("%s (%s)\n", errmsg, display_message); + } return result; } @@ -288,14 +297,16 @@ int process_arguments(int argc, char **argv) { {"help", no_argument, 0, 'h'}, {0, 0, 0, 0}}; - if (argc < 2) + if (argc < 2) { return ERROR; + } while (1) { c = getopt_long(argc, argv, "+hVH:C:p:D", longopts, &option); - if (c == -1 || c == EOF || c == 1) + if (c == -1 || c == EOF || c == 1) { break; + } switch (c) { case 'H': /* hostname */ @@ -309,10 +320,11 @@ int process_arguments(int argc, char **argv) { community = strscpy(community, optarg); break; case 'p': - if (!is_intpos(optarg)) + if (!is_intpos(optarg)) { usage2(_("Port must be a positive short integer"), optarg); - else + } else { port = atoi(optarg); + } break; case 'D': /* disable paper out check*/ check_paper_out = 0; @@ -338,10 +350,11 @@ int process_arguments(int argc, char **argv) { } if (community == NULL) { - if (argv[c] != NULL) + if (argv[c] != NULL) { community = argv[c]; - else + } else { community = strdup(DEFAULT_COMMUNITY); + } } if (port == 0) { -- cgit v1.2.3-74-g34f1 From a2ce9e962d52ebaffc275379c82ce29229a1fba8 Mon Sep 17 00:00:00 2001 From: Lorenz Kästle <12514511+RincewindsHat@users.noreply.github.com> Date: Tue, 11 Mar 2025 11:07:26 +0100 Subject: Refactor check_hpjd --- plugins/Makefile.am | 1 + plugins/check_hpjd.c | 141 +++++++++++++++++++----------------------- plugins/check_hpjd.d/config.h | 25 ++++++++ 3 files changed, 89 insertions(+), 78 deletions(-) create mode 100644 plugins/check_hpjd.d/config.h diff --git a/plugins/Makefile.am b/plugins/Makefile.am index be650089..1b40b91c 100644 --- a/plugins/Makefile.am +++ b/plugins/Makefile.am @@ -50,6 +50,7 @@ EXTRA_DIST = t \ tests \ $(np_test_scripts) \ check_swap.d \ + check_hpjd.d \ check_game.d \ check_dbi.d \ check_ssh.d \ diff --git a/plugins/check_hpjd.c b/plugins/check_hpjd.c index 78f55b7f..62417fd6 100644 --- a/plugins/check_hpjd.c +++ b/plugins/check_hpjd.c @@ -37,9 +37,10 @@ const char *email = "devel@monitoring-plugins.org"; #include "popen.h" #include "utils.h" #include "netutils.h" +#include "states.h" +#include "check_hpjd.d/config.h" #define DEFAULT_COMMUNITY "public" -#define DEFAULT_PORT "161" #define HPJD_LINE_STATUS ".1.3.6.1.4.1.11.2.3.9.1.1.2.1" #define HPJD_PAPER_STATUS ".1.3.6.1.4.1.11.2.3.9.1.1.2.2" @@ -57,39 +58,15 @@ const char *email = "devel@monitoring-plugins.org"; #define ONLINE 0 #define OFFLINE 1 -static int process_arguments(int /*argc*/, char ** /*argv*/); -static int validate_arguments(void); +typedef struct { + int errorcode; + check_hpjd_config config; +} check_hpjd_config_wrapper; +static check_hpjd_config_wrapper process_arguments(int /*argc*/, char ** /*argv*/); static void print_help(void); void print_usage(void); -static char *community = NULL; -static char *address = NULL; -static unsigned int port = 0; -static int check_paper_out = 1; - int main(int argc, char **argv) { - char command_line[1024]; - int result = STATE_UNKNOWN; - int line; - char input_buffer[MAX_INPUT_BUFFER]; - char query_string[512]; - char *errmsg; - char *temp_buffer; - int line_status = ONLINE; - int paper_status = 0; - int intervention_required = 0; - int peripheral_error = 0; - int paper_jam = 0; - int paper_out = 0; - int toner_low = 0; - int page_punt = 0; - int memory_out = 0; - int door_open = 0; - int paper_output = 0; - char display_message[MAX_INPUT_BUFFER]; - - errmsg = malloc(MAX_INPUT_BUFFER); - setlocale(LC_ALL, ""); bindtextdomain(PACKAGE, LOCALEDIR); textdomain(PACKAGE); @@ -97,10 +74,15 @@ 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_hpjd_config_wrapper tmp_config = process_arguments(argc, argv); + + if (tmp_config.errorcode == ERROR) { usage4(_("Could not parse arguments")); } + const check_hpjd_config config = tmp_config.config; + + char query_string[512]; /* removed ' 2>1' at end of command 10/27/1999 - EG */ /* create the query string */ sprintf(query_string, "%s.0 %s.0 %s.0 %s.0 %s.0 %s.0 %s.0 %s.0 %s.0 %s.0 %s.0 %s.0", HPJD_LINE_STATUS, HPJD_PAPER_STATUS, @@ -108,7 +90,8 @@ int main(int argc, char **argv) { HPJD_GD_PAGE_PUNT, HPJD_GD_MEMORY_OUT, HPJD_GD_DOOR_OPEN, HPJD_GD_PAPER_OUTPUT, HPJD_GD_STATUS_DISPLAY); /* get the command to run */ - sprintf(command_line, "%s -OQa -m : -v 1 -c %s %s:%u %s", PATH_TO_SNMPGET, community, address, port, query_string); + char command_line[1024]; + sprintf(command_line, "%s -OQa -m : -v 1 -c %s %s:%u %s", PATH_TO_SNMPGET, config.community, config.address, config.port, query_string); /* run the command */ child_process = spopen(command_line); @@ -122,11 +105,26 @@ int main(int argc, char **argv) { printf(_("Could not open stderr for %s\n"), command_line); } - result = STATE_OK; + mp_state_enum result = STATE_OK; - line = 0; - while (fgets(input_buffer, MAX_INPUT_BUFFER - 1, child_process)) { + int line_status = ONLINE; + int paper_status = 0; + int intervention_required = 0; + int peripheral_error = 0; + int paper_jam = 0; + int paper_out = 0; + int toner_low = 0; + int page_punt = 0; + int memory_out = 0; + int door_open = 0; + int paper_output = 0; + char display_message[MAX_INPUT_BUFFER]; + + char input_buffer[MAX_INPUT_BUFFER]; + char *errmsg = malloc(MAX_INPUT_BUFFER); + int line = 0; + while (fgets(input_buffer, MAX_INPUT_BUFFER - 1, child_process)) { /* strip the newline character from the end of the input */ if (input_buffer[strlen(input_buffer) - 1] == '\n') { input_buffer[strlen(input_buffer) - 1] = 0; @@ -134,18 +132,14 @@ int main(int argc, char **argv) { line++; - temp_buffer = strtok(input_buffer, "="); + char *temp_buffer = strtok(input_buffer, "="); temp_buffer = strtok(NULL, "="); if (temp_buffer == NULL && line < 13) { - result = STATE_UNKNOWN; strcpy(errmsg, input_buffer); - } else { - switch (line) { - case 1: /* 1st line should contain the line status */ line_status = atoi(temp_buffer); break; @@ -213,10 +207,9 @@ int main(int argc, char **argv) { /* if there wasn't any output, display an error */ if (line == 0) { - /* might not be the problem, but most likely is. */ result = STATE_UNKNOWN; - xasprintf(&errmsg, "%s : Timeout from host %s\n", errmsg, address); + xasprintf(&errmsg, "%s : Timeout from host %s\n", errmsg, config.address); } /* if we had no read errors, check the printer status results... */ @@ -226,7 +219,7 @@ int main(int argc, char **argv) { result = STATE_WARNING; strcpy(errmsg, _("Paper Jam")); } else if (paper_out) { - if (check_paper_out) { + if (config.check_paper_out) { result = STATE_WARNING; } strcpy(errmsg, _("Out of Paper")); @@ -264,30 +257,21 @@ int main(int argc, char **argv) { if (result == STATE_OK) { printf(_("Printer ok - (%s)\n"), display_message); - } - - else if (result == STATE_UNKNOWN) { - + } else if (result == STATE_UNKNOWN) { printf("%s\n", errmsg); - /* if printer could not be reached, escalate to critical */ if (strstr(errmsg, "Timeout")) { result = STATE_CRITICAL; } - } - - else if (result == STATE_WARNING) { + } else if (result == STATE_WARNING) { printf("%s (%s)\n", errmsg, display_message); } - return result; + exit(result); } /* process command-line arguments */ -int process_arguments(int argc, char **argv) { - int c; - - int option = 0; +check_hpjd_config_wrapper process_arguments(int argc, char **argv) { static struct option longopts[] = {{"hostname", required_argument, 0, 'H'}, {"community", required_argument, 0, 'C'}, /* {"critical", required_argument,0,'c'}, */ @@ -297,37 +281,44 @@ int process_arguments(int argc, char **argv) { {"help", no_argument, 0, 'h'}, {0, 0, 0, 0}}; + check_hpjd_config_wrapper result = { + .errorcode = OK, + .config = check_hpjd_config_init(), + }; + if (argc < 2) { - return ERROR; + result.errorcode = ERROR; + return result; } - while (1) { - c = getopt_long(argc, argv, "+hVH:C:p:D", longopts, &option); + int option = 0; + while (true) { + int option_index = getopt_long(argc, argv, "+hVH:C:p:D", longopts, &option); - if (c == -1 || c == EOF || c == 1) { + if (option_index == -1 || option_index == EOF || option_index == 1) { break; } - switch (c) { + switch (option_index) { case 'H': /* hostname */ if (is_host(optarg)) { - address = strscpy(address, optarg); + result.config.address = strscpy(result.config.address, optarg); } else { usage2(_("Invalid hostname/address"), optarg); } break; case 'C': /* community */ - community = strscpy(community, optarg); + result.config.community = strscpy(result.config.community, optarg); break; case 'p': if (!is_intpos(optarg)) { usage2(_("Port must be a positive short integer"), optarg); } else { - port = atoi(optarg); + result.config.port = atoi(optarg); } break; case 'D': /* disable paper out check*/ - check_paper_out = 0; + result.config.check_paper_out = false; break; case 'V': /* version */ print_revision(progname, NP_VERSION); @@ -340,32 +331,26 @@ int process_arguments(int argc, char **argv) { } } - c = optind; - if (address == NULL) { + int c = optind; + if (result.config.address == NULL) { if (is_host(argv[c])) { - address = argv[c++]; + result.config.address = argv[c++]; } else { usage2(_("Invalid hostname/address"), argv[c]); } } - if (community == NULL) { + if (result.config.community == NULL) { if (argv[c] != NULL) { - community = argv[c]; + result.config.community = argv[c]; } else { - community = strdup(DEFAULT_COMMUNITY); + result.config.community = strdup(DEFAULT_COMMUNITY); } } - if (port == 0) { - port = atoi(DEFAULT_PORT); - } - - return validate_arguments(); + return result; } -int validate_arguments(void) { return OK; } - void print_help(void) { print_revision(progname, NP_VERSION); diff --git a/plugins/check_hpjd.d/config.h b/plugins/check_hpjd.d/config.h new file mode 100644 index 00000000..e36b7972 --- /dev/null +++ b/plugins/check_hpjd.d/config.h @@ -0,0 +1,25 @@ +#pragma once + +#include "../../config.h" +#include +#include + +#define DEFAULT_PORT "161" + +typedef struct { + char *address; + char *community; + unsigned int port; + bool check_paper_out; + +} check_hpjd_config; + +check_hpjd_config check_hpjd_config_init() { + check_hpjd_config tmp = { + .address = NULL, + .community = NULL, + .port = (unsigned int)atoi(DEFAULT_PORT), + .check_paper_out = true, + }; + return tmp; +} -- cgit v1.2.3-74-g34f1 From 590c190bd88d5907b9e649fc45f8d8997227c4c4 Mon Sep 17 00:00:00 2001 From: Lorenz Kästle <12514511+RincewindsHat@users.noreply.github.com> Date: Tue, 11 Mar 2025 11:15:45 +0100 Subject: check_ldap: clang-format --- plugins/check_ldap.c | 460 +++++++++++++++++++++++++-------------------------- 1 file changed, 223 insertions(+), 237 deletions(-) diff --git a/plugins/check_ldap.c b/plugins/check_ldap.c index 87818da6..fc8eccec 100644 --- a/plugins/check_ldap.c +++ b/plugins/check_ldap.c @@ -1,30 +1,30 @@ /***************************************************************************** -* -* Monitoring check_ldap plugin -* -* License: GPL -* Copyright (c) 2000-2024 Monitoring Plugins Development Team -* -* Description: -* -* This file contains the check_ldap plugin -* -* -* This program is free software: you can redistribute it and/or modify -* it under the terms of the GNU General Public License as published by -* the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU General Public License for more details. -* -* You should have received a copy of the GNU General Public License -* along with this program. If not, see . -* -* -*****************************************************************************/ + * + * Monitoring check_ldap plugin + * + * License: GPL + * Copyright (c) 2000-2024 Monitoring Plugins Development Team + * + * Description: + * + * This file contains the check_ldap plugin + * + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + * + *****************************************************************************/ /* progname may be check_ldaps */ char *progname = "check_ldap"; @@ -47,10 +47,10 @@ enum { DEFAULT_PORT = 389 }; -static int process_arguments (int, char **); -static int validate_arguments (void); -static void print_help (void); -void print_usage (void); +static int process_arguments(int, char **); +static int validate_arguments(void); +static void print_help(void); +void print_usage(void); static char ld_defattr[] = "(objectclass=*)"; static char *ld_attr = ld_defattr; @@ -63,14 +63,14 @@ static int ld_port = -1; static int ld_protocol = DEFAULT_PROTOCOL; #endif #ifndef LDAP_OPT_SUCCESS -# define LDAP_OPT_SUCCESS LDAP_SUCCESS +# define LDAP_OPT_SUCCESS LDAP_SUCCESS #endif static double warn_time = UNDEFINED; static double crit_time = UNDEFINED; static thresholds *entries_thresholds = NULL; static struct timeval tv; -static char* warn_entries = NULL; -static char* crit_entries = NULL; +static char *warn_entries = NULL; +static char *crit_entries = NULL; static bool starttls = false; static bool ssl_on_connect = false; static bool verbose = false; @@ -79,9 +79,7 @@ static bool verbose = false; static char *SERVICE = "LDAP"; -int -main (int argc, char *argv[]) -{ +int main(int argc, char *argv[]) { LDAP *ld; LDAPMessage *result; @@ -95,145 +93,147 @@ main (int argc, char *argv[]) /* for ldap tls */ int tls; - int version=3; + int version = 3; int status_entries = STATE_OK; int num_entries = 0; - setlocale (LC_ALL, ""); - bindtextdomain (PACKAGE, LOCALEDIR); - textdomain (PACKAGE); + setlocale(LC_ALL, ""); + bindtextdomain(PACKAGE, LOCALEDIR); + textdomain(PACKAGE); - if (strstr(argv[0],"check_ldaps")) { - xasprintf (&progname, "check_ldaps"); - } + if (strstr(argv[0], "check_ldaps")) { + xasprintf(&progname, "check_ldaps"); + } /* Parse extra opts if any */ - argv=np_extra_opts (&argc, argv, progname); + argv = np_extra_opts(&argc, argv, progname); - if (process_arguments (argc, argv) == ERROR) - usage4 (_("Could not parse arguments")); + if (process_arguments(argc, argv) == ERROR) { + usage4(_("Could not parse arguments")); + } - if (strstr(argv[0],"check_ldaps") && ! starttls && ! ssl_on_connect) + if (strstr(argv[0], "check_ldaps") && !starttls && !ssl_on_connect) { starttls = true; + } /* initialize alarm signal handling */ - signal (SIGALRM, socket_timeout_alarm_handler); + signal(SIGALRM, socket_timeout_alarm_handler); /* set socket timeout */ - alarm (socket_timeout); + alarm(socket_timeout); /* get the start time */ - gettimeofday (&tv, NULL); + gettimeofday(&tv, NULL); /* initialize ldap */ #ifdef HAVE_LDAP_INIT - if (!(ld = ldap_init (ld_host, ld_port))) { - printf ("Could not connect to the server at port %i\n", ld_port); + if (!(ld = ldap_init(ld_host, ld_port))) { + printf("Could not connect to the server at port %i\n", ld_port); return STATE_CRITICAL; } #else - if (!(ld = ldap_open (ld_host, ld_port))) { - if (verbose) + if (!(ld = ldap_open(ld_host, ld_port))) { + if (verbose) { ldap_perror(ld, "ldap_open"); - printf (_("Could not connect to the server at port %i\n"), ld_port); + } + printf(_("Could not connect to the server at port %i\n"), ld_port); return STATE_CRITICAL; } #endif /* HAVE_LDAP_INIT */ #ifdef HAVE_LDAP_SET_OPTION /* set ldap options */ - if (ldap_set_option (ld, LDAP_OPT_PROTOCOL_VERSION, &ld_protocol) != - LDAP_OPT_SUCCESS ) { + if (ldap_set_option(ld, LDAP_OPT_PROTOCOL_VERSION, &ld_protocol) != LDAP_OPT_SUCCESS) { printf(_("Could not set protocol version %d\n"), ld_protocol); return STATE_CRITICAL; } #endif if (ld_port == LDAPS_PORT || ssl_on_connect) { - xasprintf (&SERVICE, "LDAPS"); + xasprintf(&SERVICE, "LDAPS"); #if defined(HAVE_LDAP_SET_OPTION) && defined(LDAP_OPT_X_TLS) /* ldaps: set option tls */ tls = LDAP_OPT_X_TLS_HARD; - if (ldap_set_option (ld, LDAP_OPT_X_TLS, &tls) != LDAP_SUCCESS) - { - if (verbose) + if (ldap_set_option(ld, LDAP_OPT_X_TLS, &tls) != LDAP_SUCCESS) { + if (verbose) { ldap_perror(ld, "ldaps_option"); - printf (_("Could not init TLS at port %i!\n"), ld_port); + } + printf(_("Could not init TLS at port %i!\n"), ld_port); return STATE_CRITICAL; } #else - printf (_("TLS not supported by the libraries!\n")); + printf(_("TLS not supported by the libraries!\n")); return STATE_CRITICAL; #endif /* LDAP_OPT_X_TLS */ } else if (starttls) { - xasprintf (&SERVICE, "LDAP-TLS"); + xasprintf(&SERVICE, "LDAP-TLS"); #if defined(HAVE_LDAP_SET_OPTION) && defined(HAVE_LDAP_START_TLS_S) /* ldap with startTLS: set option version */ - if (ldap_get_option(ld,LDAP_OPT_PROTOCOL_VERSION, &version) == LDAP_OPT_SUCCESS ) - { - if (version < LDAP_VERSION3) - { + if (ldap_get_option(ld, LDAP_OPT_PROTOCOL_VERSION, &version) == LDAP_OPT_SUCCESS) { + if (version < LDAP_VERSION3) { version = LDAP_VERSION3; ldap_set_option(ld, LDAP_OPT_PROTOCOL_VERSION, &version); } } /* call start_tls */ - if (ldap_start_tls_s(ld, NULL, NULL) != LDAP_SUCCESS) - { - if (verbose) + if (ldap_start_tls_s(ld, NULL, NULL) != LDAP_SUCCESS) { + if (verbose) { ldap_perror(ld, "ldap_start_tls"); - printf (_("Could not init startTLS at port %i!\n"), ld_port); + } + printf(_("Could not init startTLS at port %i!\n"), ld_port); return STATE_CRITICAL; } #else - printf (_("startTLS not supported by the library, needs LDAPv3!\n")); + printf(_("startTLS not supported by the library, needs LDAPv3!\n")); return STATE_CRITICAL; #endif /* HAVE_LDAP_START_TLS_S */ } /* bind to the ldap server */ - if (ldap_bind_s (ld, ld_binddn, ld_passwd, LDAP_AUTH_SIMPLE) != - LDAP_SUCCESS) { - if (verbose) + if (ldap_bind_s(ld, ld_binddn, ld_passwd, LDAP_AUTH_SIMPLE) != LDAP_SUCCESS) { + if (verbose) { ldap_perror(ld, "ldap_bind"); - printf (_("Could not bind to the LDAP server\n")); + } + printf(_("Could not bind to the LDAP server\n")); return STATE_CRITICAL; } /* do a search of all objectclasses in the base dn */ - if (ldap_search_s (ld, ld_base, (crit_entries!=NULL || warn_entries!=NULL) ? LDAP_SCOPE_SUBTREE : LDAP_SCOPE_BASE, ld_attr, NULL, 0, &result) - != LDAP_SUCCESS) { - if (verbose) + if (ldap_search_s(ld, ld_base, (crit_entries != NULL || warn_entries != NULL) ? LDAP_SCOPE_SUBTREE : LDAP_SCOPE_BASE, ld_attr, NULL, 0, + &result) != LDAP_SUCCESS) { + if (verbose) { ldap_perror(ld, "ldap_search"); - printf (_("Could not search/find objectclasses in %s\n"), ld_base); + } + printf(_("Could not search/find objectclasses in %s\n"), ld_base); return STATE_CRITICAL; - } else if (crit_entries!=NULL || warn_entries!=NULL) { + } else if (crit_entries != NULL || warn_entries != NULL) { num_entries = ldap_count_entries(ld, result); } /* unbind from the ldap server */ - ldap_unbind (ld); + ldap_unbind(ld); /* reset the alarm handler */ - alarm (0); + alarm(0); /* calculate the elapsed time and compare to thresholds */ - microsec = deltime (tv); + microsec = deltime(tv); elapsed_time = (double)microsec / 1.0e6; - if (crit_time!=UNDEFINED && elapsed_time>crit_time) + if (crit_time != UNDEFINED && elapsed_time > crit_time) { status = STATE_CRITICAL; - else if (warn_time!=UNDEFINED && elapsed_time>warn_time) + } else if (warn_time != UNDEFINED && elapsed_time > warn_time) { status = STATE_WARNING; - else + } else { status = STATE_OK; + } - if(entries_thresholds != NULL) { + if (entries_thresholds != NULL) { if (verbose) { - printf ("entries found: %d\n", num_entries); + printf("entries found: %d\n", num_entries); print_thresholds("entry thresholds", entries_thresholds); } status_entries = get_status(num_entries, entries_thresholds); @@ -245,92 +245,78 @@ main (int argc, char *argv[]) } /* print out the result */ - if (crit_entries!=NULL || warn_entries!=NULL) { - printf (_("LDAP %s - found %d entries in %.3f seconds|%s %s\n"), - state_text (status), - num_entries, - elapsed_time, - fperfdata ("time", elapsed_time, "s", - (int)warn_time, warn_time, - (int)crit_time, crit_time, - true, 0, false, 0), - sperfdata ("entries", (double)num_entries, "", - warn_entries, - crit_entries, - true, 0.0, false, 0.0)); + if (crit_entries != NULL || warn_entries != NULL) { + printf(_("LDAP %s - found %d entries in %.3f seconds|%s %s\n"), state_text(status), num_entries, elapsed_time, + fperfdata("time", elapsed_time, "s", (int)warn_time, warn_time, (int)crit_time, crit_time, true, 0, false, 0), + sperfdata("entries", (double)num_entries, "", warn_entries, crit_entries, true, 0.0, false, 0.0)); } else { - printf (_("LDAP %s - %.3f seconds response time|%s\n"), - state_text (status), - elapsed_time, - fperfdata ("time", elapsed_time, "s", - (int)warn_time, warn_time, - (int)crit_time, crit_time, - true, 0, false, 0)); + printf(_("LDAP %s - %.3f seconds response time|%s\n"), state_text(status), elapsed_time, + fperfdata("time", elapsed_time, "s", (int)warn_time, warn_time, (int)crit_time, crit_time, true, 0, false, 0)); } return status; } /* process command-line arguments */ -int -process_arguments (int argc, char **argv) -{ +int process_arguments(int argc, char **argv) { int c; int option = 0; /* initialize the long option struct */ - static struct option longopts[] = { - {"help", no_argument, 0, 'h'}, - {"version", no_argument, 0, 'V'}, - {"timeout", required_argument, 0, 't'}, - {"hostname", required_argument, 0, 'H'}, - {"base", required_argument, 0, 'b'}, - {"attr", required_argument, 0, 'a'}, - {"bind", required_argument, 0, 'D'}, - {"pass", required_argument, 0, 'P'}, + static struct option longopts[] = {{"help", no_argument, 0, 'h'}, + {"version", no_argument, 0, 'V'}, + {"timeout", required_argument, 0, 't'}, + {"hostname", required_argument, 0, 'H'}, + {"base", required_argument, 0, 'b'}, + {"attr", required_argument, 0, 'a'}, + {"bind", required_argument, 0, 'D'}, + {"pass", required_argument, 0, 'P'}, #ifdef HAVE_LDAP_SET_OPTION - {"ver2", no_argument, 0, '2'}, - {"ver3", no_argument, 0, '3'}, + {"ver2", no_argument, 0, '2'}, + {"ver3", no_argument, 0, '3'}, #endif - {"starttls", no_argument, 0, 'T'}, - {"ssl", no_argument, 0, 'S'}, - {"use-ipv4", no_argument, 0, '4'}, - {"use-ipv6", no_argument, 0, '6'}, - {"port", required_argument, 0, 'p'}, - {"warn", required_argument, 0, 'w'}, - {"crit", required_argument, 0, 'c'}, - {"warn-entries", required_argument, 0, 'W'}, - {"crit-entries", required_argument, 0, 'C'}, - {"verbose", no_argument, 0, 'v'}, - {0, 0, 0, 0} - }; - - if (argc < 2) + {"starttls", no_argument, 0, 'T'}, + {"ssl", no_argument, 0, 'S'}, + {"use-ipv4", no_argument, 0, '4'}, + {"use-ipv6", no_argument, 0, '6'}, + {"port", required_argument, 0, 'p'}, + {"warn", required_argument, 0, 'w'}, + {"crit", required_argument, 0, 'c'}, + {"warn-entries", required_argument, 0, 'W'}, + {"crit-entries", required_argument, 0, 'C'}, + {"verbose", no_argument, 0, 'v'}, + {0, 0, 0, 0}}; + + if (argc < 2) { return ERROR; + } for (c = 1; c < argc; c++) { - if (strcmp ("-to", argv[c]) == 0) - strcpy (argv[c], "-t"); + if (strcmp("-to", argv[c]) == 0) { + strcpy(argv[c], "-t"); + } } while (true) { - c = getopt_long (argc, argv, "hvV234TS6t:c:w:H:b:p:a:D:P:C:W:", longopts, &option); + c = getopt_long(argc, argv, "hvV234TS6t:c:w:H:b:p:a:D:P:C:W:", longopts, &option); - if (c == -1 || c == EOF) + if (c == -1 || c == EOF) { break; + } switch (c) { - case 'h': /* help */ - print_help (); - exit (STATE_UNKNOWN); - case 'V': /* version */ - print_revision (progname, NP_VERSION); - exit (STATE_UNKNOWN); - case 't': /* timeout period */ - if (!is_intnonneg (optarg)) - usage2 (_("Timeout interval must be a positive integer"), optarg); - else - socket_timeout = atoi (optarg); + case 'h': /* help */ + print_help(); + exit(STATE_UNKNOWN); + case 'V': /* version */ + print_revision(progname, NP_VERSION); + exit(STATE_UNKNOWN); + case 't': /* timeout period */ + if (!is_intnonneg(optarg)) { + usage2(_("Timeout interval must be a positive integer"), optarg); + } else { + socket_timeout = atoi(optarg); + } break; case 'H': ld_host = optarg; @@ -339,7 +325,7 @@ process_arguments (int argc, char **argv) ld_base = optarg; break; case 'p': - ld_port = atoi (optarg); + ld_port = atoi(optarg); break; case 'a': ld_attr = optarg; @@ -351,10 +337,10 @@ process_arguments (int argc, char **argv) ld_passwd = optarg; break; case 'w': - warn_time = strtod (optarg, NULL); + warn_time = strtod(optarg, NULL); break; case 'c': - crit_time = strtod (optarg, NULL); + crit_time = strtod(optarg, NULL); break; case 'W': warn_entries = optarg; @@ -377,141 +363,141 @@ process_arguments (int argc, char **argv) verbose = true; break; case 'T': - if (! ssl_on_connect) + if (!ssl_on_connect) { starttls = true; - else + } else { usage_va(_("%s cannot be combined with %s"), "-T/--starttls", "-S/--ssl"); + } break; case 'S': - if (! starttls) { + if (!starttls) { ssl_on_connect = true; - if (ld_port == -1) + if (ld_port == -1) { ld_port = LDAPS_PORT; - } else + } + } else { usage_va(_("%s cannot be combined with %s"), "-S/--ssl", "-T/--starttls"); + } break; case '6': #ifdef USE_IPV6 address_family = AF_INET6; #else - usage (_("IPv6 support not available\n")); + usage(_("IPv6 support not available\n")); #endif break; default: - usage5 (); + usage5(); } } c = optind; - if (ld_host == NULL && is_host(argv[c])) - ld_host = strdup (argv[c++]); + if (ld_host == NULL && is_host(argv[c])) { + ld_host = strdup(argv[c++]); + } - if (ld_base == NULL && argv[c]) - ld_base = strdup (argv[c++]); + if (ld_base == NULL && argv[c]) { + ld_base = strdup(argv[c++]); + } - if (ld_port == -1) + if (ld_port == -1) { ld_port = DEFAULT_PORT; + } - return validate_arguments (); + return validate_arguments(); } +int validate_arguments() { + if (ld_host == NULL || strlen(ld_host) == 0) { + usage4(_("Please specify the host name\n")); + } -int -validate_arguments () -{ - if (ld_host==NULL || strlen(ld_host)==0) - usage4 (_("Please specify the host name\n")); - - if (ld_base==NULL) - usage4 (_("Please specify the LDAP base\n")); + if (ld_base == NULL) { + usage4(_("Please specify the LDAP base\n")); + } - if (crit_entries!=NULL || warn_entries!=NULL) { - set_thresholds(&entries_thresholds, - warn_entries, crit_entries); + if (crit_entries != NULL || warn_entries != NULL) { + set_thresholds(&entries_thresholds, warn_entries, crit_entries); } - if (ld_passwd==NULL) + if (ld_passwd == NULL) { ld_passwd = getenv("LDAP_PASSWORD"); + } return OK; } - -void -print_help (void) -{ +void print_help(void) { char *myport; - xasprintf (&myport, "%d", DEFAULT_PORT); + xasprintf(&myport, "%d", DEFAULT_PORT); - print_revision (progname, NP_VERSION); + print_revision(progname, NP_VERSION); - printf ("Copyright (c) 1999 Didi Rieder (adrieder@sbox.tu-graz.ac.at)\n"); - printf (COPYRIGHT, copyright, email); + printf("Copyright (c) 1999 Didi Rieder (adrieder@sbox.tu-graz.ac.at)\n"); + printf(COPYRIGHT, copyright, email); - printf ("\n\n"); + printf("\n\n"); - print_usage (); + print_usage(); - printf (UT_HELP_VRSN); - printf (UT_EXTRA_OPTS); + printf(UT_HELP_VRSN); + printf(UT_EXTRA_OPTS); - printf (UT_HOST_PORT, 'p', myport); + printf(UT_HOST_PORT, 'p', myport); - printf (UT_IPv46); + printf(UT_IPv46); - printf (" %s\n", "-a [--attr]"); - printf (" %s\n", _("ldap attribute to search (default: \"(objectclass=*)\"")); - printf (" %s\n", "-b [--base]"); - printf (" %s\n", _("ldap base (eg. ou=my unit, o=my org, c=at")); - printf (" %s\n", "-D [--bind]"); - printf (" %s\n", _("ldap bind DN (if required)")); - printf (" %s\n", "-P [--pass]"); - printf (" %s\n", _("ldap password (if required, or set the password through environment variable 'LDAP_PASSWORD')")); - printf (" %s\n", "-T [--starttls]"); - printf (" %s\n", _("use starttls mechanism introduced in protocol version 3")); - printf (" %s\n", "-S [--ssl]"); - printf (" %s %i\n", _("use ldaps (ldap v2 ssl method). this also sets the default port to"), LDAPS_PORT); + printf(" %s\n", "-a [--attr]"); + printf(" %s\n", _("ldap attribute to search (default: \"(objectclass=*)\"")); + printf(" %s\n", "-b [--base]"); + printf(" %s\n", _("ldap base (eg. ou=my unit, o=my org, c=at")); + printf(" %s\n", "-D [--bind]"); + printf(" %s\n", _("ldap bind DN (if required)")); + printf(" %s\n", "-P [--pass]"); + printf(" %s\n", _("ldap password (if required, or set the password through environment variable 'LDAP_PASSWORD')")); + printf(" %s\n", "-T [--starttls]"); + printf(" %s\n", _("use starttls mechanism introduced in protocol version 3")); + printf(" %s\n", "-S [--ssl]"); + printf(" %s %i\n", _("use ldaps (ldap v2 ssl method). this also sets the default port to"), LDAPS_PORT); #ifdef HAVE_LDAP_SET_OPTION - printf (" %s\n", "-2 [--ver2]"); - printf (" %s\n", _("use ldap protocol version 2")); - printf (" %s\n", "-3 [--ver3]"); - printf (" %s\n", _("use ldap protocol version 3")); - printf (" (%s %d)\n", _("default protocol version:"), DEFAULT_PROTOCOL); + printf(" %s\n", "-2 [--ver2]"); + printf(" %s\n", _("use ldap protocol version 2")); + printf(" %s\n", "-3 [--ver3]"); + printf(" %s\n", _("use ldap protocol version 3")); + printf(" (%s %d)\n", _("default protocol version:"), DEFAULT_PROTOCOL); #endif - printf (UT_WARN_CRIT); + printf(UT_WARN_CRIT); - printf (" %s\n", "-W [--warn-entries]"); - printf (" %s\n", _("Number of found entries to result in warning status")); - printf (" %s\n", "-C [--crit-entries]"); - printf (" %s\n", _("Number of found entries to result in critical status")); + printf(" %s\n", "-W [--warn-entries]"); + printf(" %s\n", _("Number of found entries to result in warning status")); + printf(" %s\n", "-C [--crit-entries]"); + printf(" %s\n", _("Number of found entries to result in critical status")); - printf (UT_CONN_TIMEOUT, DEFAULT_SOCKET_TIMEOUT); + printf(UT_CONN_TIMEOUT, DEFAULT_SOCKET_TIMEOUT); - printf (UT_VERBOSE); + printf(UT_VERBOSE); - printf ("\n"); - printf ("%s\n", _("Notes:")); - printf (" %s\n", _("If this plugin is called via 'check_ldaps', method 'STARTTLS' will be")); - printf (_(" implied (using default port %i) unless --port=636 is specified. In that case\n"), DEFAULT_PORT); - printf (" %s\n", _("'SSL on connect' will be used no matter how the plugin was called.")); - printf (" %s\n", _("This detection is deprecated, please use 'check_ldap' with the '--starttls' or '--ssl' flags")); - printf (" %s\n", _("to define the behaviour explicitly instead.")); - printf (" %s\n", _("The parameters --warn-entries and --crit-entries are optional.")); + printf("\n"); + printf("%s\n", _("Notes:")); + printf(" %s\n", _("If this plugin is called via 'check_ldaps', method 'STARTTLS' will be")); + printf(_(" implied (using default port %i) unless --port=636 is specified. In that case\n"), DEFAULT_PORT); + printf(" %s\n", _("'SSL on connect' will be used no matter how the plugin was called.")); + printf(" %s\n", _("This detection is deprecated, please use 'check_ldap' with the '--starttls' or '--ssl' flags")); + printf(" %s\n", _("to define the behaviour explicitly instead.")); + printf(" %s\n", _("The parameters --warn-entries and --crit-entries are optional.")); - printf (UT_SUPPORT); + printf(UT_SUPPORT); } -void -print_usage (void) -{ - printf ("%s\n", _("Usage:")); - printf (" %s -H -b [-p ] [-a ] [-D ]",progname); - printf ("\n [-P ] [-w ] [-c ] [-t timeout]%s\n", +void print_usage(void) { + printf("%s\n", _("Usage:")); + printf(" %s -H -b [-p ] [-a ] [-D ]", progname); + printf("\n [-P ] [-w ] [-c ] [-t timeout]%s\n", #ifdef HAVE_LDAP_SET_OPTION - "\n [-2|-3] [-4|-6]" + "\n [-2|-3] [-4|-6]" #else - "" + "" #endif - ); + ); } -- cgit v1.2.3-74-g34f1 From 7a518f99a57a6ee169cedd062e4e2e1e7c3fc2d2 Mon Sep 17 00:00:00 2001 From: Lorenz Kästle <12514511+RincewindsHat@users.noreply.github.com> Date: Tue, 11 Mar 2025 12:12:32 +0100 Subject: Refactor check_ldap --- plugins/Makefile.am | 1 + plugins/check_ldap.c | 262 ++++++++++++++++++++---------------------- plugins/check_ldap.d/config.h | 61 ++++++++++ 3 files changed, 184 insertions(+), 140 deletions(-) create mode 100644 plugins/check_ldap.d/config.h diff --git a/plugins/Makefile.am b/plugins/Makefile.am index be650089..9f7266ad 100644 --- a/plugins/Makefile.am +++ b/plugins/Makefile.am @@ -50,6 +50,7 @@ EXTRA_DIST = t \ tests \ $(np_test_scripts) \ check_swap.d \ + check_ldap.d \ check_game.d \ check_dbi.d \ check_ssh.d \ diff --git a/plugins/check_ldap.c b/plugins/check_ldap.c index fc8eccec..597644bd 100644 --- a/plugins/check_ldap.c +++ b/plugins/check_ldap.c @@ -34,70 +34,33 @@ const char *email = "devel@monitoring-plugins.org"; #include "common.h" #include "netutils.h" #include "utils.h" +#include "check_ldap.d/config.h" +#include "states.h" #include #define LDAP_DEPRECATED 1 #include enum { - UNDEFINED = 0, -#ifdef HAVE_LDAP_SET_OPTION - DEFAULT_PROTOCOL = 2, -#endif DEFAULT_PORT = 389 }; -static int process_arguments(int, char **); -static int validate_arguments(void); +typedef struct { + int errorcode; + check_ldap_config config; +} check_ldap_config_wrapper; +static check_ldap_config_wrapper process_arguments(int /*argc*/, char ** /*argv*/); +static check_ldap_config_wrapper validate_arguments(check_ldap_config_wrapper /*config_wrapper*/); + static void print_help(void); void print_usage(void); -static char ld_defattr[] = "(objectclass=*)"; -static char *ld_attr = ld_defattr; -static char *ld_host = NULL; -static char *ld_base = NULL; -static char *ld_passwd = NULL; -static char *ld_binddn = NULL; -static int ld_port = -1; -#ifdef HAVE_LDAP_SET_OPTION -static int ld_protocol = DEFAULT_PROTOCOL; -#endif #ifndef LDAP_OPT_SUCCESS # define LDAP_OPT_SUCCESS LDAP_SUCCESS #endif -static double warn_time = UNDEFINED; -static double crit_time = UNDEFINED; -static thresholds *entries_thresholds = NULL; -static struct timeval tv; -static char *warn_entries = NULL; -static char *crit_entries = NULL; -static bool starttls = false; -static bool ssl_on_connect = false; -static bool verbose = false; - -/* for ldap tls */ - -static char *SERVICE = "LDAP"; +static int verbose = 0; int main(int argc, char *argv[]) { - - LDAP *ld; - LDAPMessage *result; - - /* should be int result = STATE_UNKNOWN; */ - - int status = STATE_UNKNOWN; - long microsec; - double elapsed_time; - - /* for ldap tls */ - - int tls; - int version = 3; - - int status_entries = STATE_OK; - int num_entries = 0; - setlocale(LC_ALL, ""); bindtextdomain(PACKAGE, LOCALEDIR); textdomain(PACKAGE); @@ -109,13 +72,12 @@ 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_ldap_config_wrapper tmp_config = process_arguments(argc, argv); + if (tmp_config.errorcode == ERROR) { usage4(_("Could not parse arguments")); } - if (strstr(argv[0], "check_ldaps") && !starttls && !ssl_on_connect) { - starttls = true; - } + const check_ldap_config config = tmp_config.config; /* initialize alarm signal handling */ signal(SIGALRM, socket_timeout_alarm_handler); @@ -124,65 +86,67 @@ int main(int argc, char *argv[]) { alarm(socket_timeout); /* get the start time */ - gettimeofday(&tv, NULL); + struct timeval start_time; + gettimeofday(&start_time, NULL); + LDAP *ldap_connection; /* initialize ldap */ #ifdef HAVE_LDAP_INIT - if (!(ld = ldap_init(ld_host, ld_port))) { - printf("Could not connect to the server at port %i\n", ld_port); + if (!(ldap_connection = ldap_init(config.ld_host, config.ld_port))) { + printf("Could not connect to the server at port %i\n", config.ld_port); return STATE_CRITICAL; } #else - if (!(ld = ldap_open(ld_host, ld_port))) { + if (!(ld = ldap_open(config.ld_host, config.ld_port))) { if (verbose) { - ldap_perror(ld, "ldap_open"); + ldap_perror(ldap_connection, "ldap_open"); } - printf(_("Could not connect to the server at port %i\n"), ld_port); + printf(_("Could not connect to the server at port %i\n"), config.ld_port); return STATE_CRITICAL; } #endif /* HAVE_LDAP_INIT */ #ifdef HAVE_LDAP_SET_OPTION /* set ldap options */ - if (ldap_set_option(ld, LDAP_OPT_PROTOCOL_VERSION, &ld_protocol) != LDAP_OPT_SUCCESS) { - printf(_("Could not set protocol version %d\n"), ld_protocol); + if (ldap_set_option(ldap_connection, LDAP_OPT_PROTOCOL_VERSION, &config.ld_protocol) != LDAP_OPT_SUCCESS) { + printf(_("Could not set protocol version %d\n"), config.ld_protocol); return STATE_CRITICAL; } #endif - if (ld_port == LDAPS_PORT || ssl_on_connect) { - xasprintf(&SERVICE, "LDAPS"); + int version = 3; + int tls; + if (config.ld_port == LDAPS_PORT || config.ssl_on_connect) { #if defined(HAVE_LDAP_SET_OPTION) && defined(LDAP_OPT_X_TLS) /* ldaps: set option tls */ tls = LDAP_OPT_X_TLS_HARD; - if (ldap_set_option(ld, LDAP_OPT_X_TLS, &tls) != LDAP_SUCCESS) { + if (ldap_set_option(ldap_connection, LDAP_OPT_X_TLS, &tls) != LDAP_SUCCESS) { if (verbose) { - ldap_perror(ld, "ldaps_option"); + ldap_perror(ldap_connection, "ldaps_option"); } - printf(_("Could not init TLS at port %i!\n"), ld_port); + printf(_("Could not init TLS at port %i!\n"), config.ld_port); return STATE_CRITICAL; } #else printf(_("TLS not supported by the libraries!\n")); return STATE_CRITICAL; #endif /* LDAP_OPT_X_TLS */ - } else if (starttls) { - xasprintf(&SERVICE, "LDAP-TLS"); + } else if (config.starttls) { #if defined(HAVE_LDAP_SET_OPTION) && defined(HAVE_LDAP_START_TLS_S) /* ldap with startTLS: set option version */ - if (ldap_get_option(ld, LDAP_OPT_PROTOCOL_VERSION, &version) == LDAP_OPT_SUCCESS) { + if (ldap_get_option(ldap_connection, LDAP_OPT_PROTOCOL_VERSION, &version) == LDAP_OPT_SUCCESS) { if (version < LDAP_VERSION3) { version = LDAP_VERSION3; - ldap_set_option(ld, LDAP_OPT_PROTOCOL_VERSION, &version); + ldap_set_option(ldap_connection, LDAP_OPT_PROTOCOL_VERSION, &version); } } /* call start_tls */ - if (ldap_start_tls_s(ld, NULL, NULL) != LDAP_SUCCESS) { + if (ldap_start_tls_s(ldap_connection, NULL, NULL) != LDAP_SUCCESS) { if (verbose) { - ldap_perror(ld, "ldap_start_tls"); + ldap_perror(ldap_connection, "ldap_start_tls"); } - printf(_("Could not init startTLS at port %i!\n"), ld_port); + printf(_("Could not init startTLS at port %i!\n"), config.ld_port); return STATE_CRITICAL; } #else @@ -192,51 +156,56 @@ int main(int argc, char *argv[]) { } /* bind to the ldap server */ - if (ldap_bind_s(ld, ld_binddn, ld_passwd, LDAP_AUTH_SIMPLE) != LDAP_SUCCESS) { + if (ldap_bind_s(ldap_connection, config.ld_binddn, config.ld_passwd, LDAP_AUTH_SIMPLE) != LDAP_SUCCESS) { if (verbose) { - ldap_perror(ld, "ldap_bind"); + ldap_perror(ldap_connection, "ldap_bind"); } printf(_("Could not bind to the LDAP server\n")); return STATE_CRITICAL; } + LDAPMessage *result; + int num_entries = 0; /* do a search of all objectclasses in the base dn */ - if (ldap_search_s(ld, ld_base, (crit_entries != NULL || warn_entries != NULL) ? LDAP_SCOPE_SUBTREE : LDAP_SCOPE_BASE, ld_attr, NULL, 0, - &result) != LDAP_SUCCESS) { + if (ldap_search_s(ldap_connection, config.ld_base, + (config.crit_entries != NULL || config.warn_entries != NULL) ? LDAP_SCOPE_SUBTREE : LDAP_SCOPE_BASE, config.ld_attr, + NULL, 0, &result) != LDAP_SUCCESS) { if (verbose) { - ldap_perror(ld, "ldap_search"); + ldap_perror(ldap_connection, "ldap_search"); } - printf(_("Could not search/find objectclasses in %s\n"), ld_base); + printf(_("Could not search/find objectclasses in %s\n"), config.ld_base); return STATE_CRITICAL; - } else if (crit_entries != NULL || warn_entries != NULL) { - num_entries = ldap_count_entries(ld, result); + } + + if (config.crit_entries != NULL || config.warn_entries != NULL) { + num_entries = ldap_count_entries(ldap_connection, result); } /* unbind from the ldap server */ - ldap_unbind(ld); + ldap_unbind(ldap_connection); /* reset the alarm handler */ alarm(0); /* calculate the elapsed time and compare to thresholds */ - microsec = deltime(tv); - elapsed_time = (double)microsec / 1.0e6; - - if (crit_time != UNDEFINED && elapsed_time > crit_time) { + long microsec = deltime(start_time); + double elapsed_time = (double)microsec / 1.0e6; + mp_state_enum status = STATE_UNKNOWN; + if (config.crit_time_set && elapsed_time > config.crit_time) { status = STATE_CRITICAL; - } else if (warn_time != UNDEFINED && elapsed_time > warn_time) { + } else if (config.warn_time_set && elapsed_time > config.warn_time) { status = STATE_WARNING; } else { status = STATE_OK; } - if (entries_thresholds != NULL) { + if (config.entries_thresholds != NULL) { if (verbose) { printf("entries found: %d\n", num_entries); - print_thresholds("entry thresholds", entries_thresholds); + print_thresholds("entry thresholds", config.entries_thresholds); } - status_entries = get_status(num_entries, entries_thresholds); + mp_state_enum status_entries = get_status(num_entries, config.entries_thresholds); if (status_entries == STATE_CRITICAL) { status = STATE_CRITICAL; } else if (status != STATE_CRITICAL) { @@ -245,23 +214,22 @@ int main(int argc, char *argv[]) { } /* print out the result */ - if (crit_entries != NULL || warn_entries != NULL) { + if (config.crit_entries != NULL || config.warn_entries != NULL) { printf(_("LDAP %s - found %d entries in %.3f seconds|%s %s\n"), state_text(status), num_entries, elapsed_time, - fperfdata("time", elapsed_time, "s", (int)warn_time, warn_time, (int)crit_time, crit_time, true, 0, false, 0), - sperfdata("entries", (double)num_entries, "", warn_entries, crit_entries, true, 0.0, false, 0.0)); + fperfdata("time", elapsed_time, "s", config.warn_time_set, config.warn_time, config.crit_time_set, config.crit_time, true, 0, + false, 0), + sperfdata("entries", (double)num_entries, "", config.warn_entries, config.crit_entries, true, 0.0, false, 0.0)); } else { printf(_("LDAP %s - %.3f seconds response time|%s\n"), state_text(status), elapsed_time, - fperfdata("time", elapsed_time, "s", (int)warn_time, warn_time, (int)crit_time, crit_time, true, 0, false, 0)); + fperfdata("time", elapsed_time, "s", config.warn_time_set, config.warn_time, config.crit_time_set, config.crit_time, true, 0, + false, 0)); } - return status; + exit(status); } /* process command-line arguments */ -int process_arguments(int argc, char **argv) { - int c; - - int option = 0; +check_ldap_config_wrapper process_arguments(int argc, char **argv) { /* initialize the long option struct */ static struct option longopts[] = {{"help", no_argument, 0, 'h'}, {"version", no_argument, 0, 'V'}, @@ -287,24 +255,31 @@ int process_arguments(int argc, char **argv) { {"verbose", no_argument, 0, 'v'}, {0, 0, 0, 0}}; + check_ldap_config_wrapper result = { + .errorcode = OK, + .config = check_ldap_config_init(), + }; + if (argc < 2) { - return ERROR; + result.errorcode = ERROR; + return result; } - for (c = 1; c < argc; c++) { - if (strcmp("-to", argv[c]) == 0) { - strcpy(argv[c], "-t"); + for (int index = 1; index < argc; index++) { + if (strcmp("-to", argv[index]) == 0) { + strcpy(argv[index], "-t"); } } + int option = 0; while (true) { - c = getopt_long(argc, argv, "hvV234TS6t:c:w:H:b:p:a:D:P:C:W:", longopts, &option); + int option_index = getopt_long(argc, argv, "hvV234TS6t:c:w:H:b:p:a:D:P:C:W:", longopts, &option); - 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); @@ -319,61 +294,63 @@ int process_arguments(int argc, char **argv) { } break; case 'H': - ld_host = optarg; + result.config.ld_host = optarg; break; case 'b': - ld_base = optarg; + result.config.ld_base = optarg; break; case 'p': - ld_port = atoi(optarg); + result.config.ld_port = atoi(optarg); break; case 'a': - ld_attr = optarg; + result.config.ld_attr = optarg; break; case 'D': - ld_binddn = optarg; + result.config.ld_binddn = optarg; break; case 'P': - ld_passwd = optarg; + result.config.ld_passwd = optarg; break; case 'w': - warn_time = strtod(optarg, NULL); + result.config.warn_time_set = true; + result.config.warn_time = strtod(optarg, NULL); break; case 'c': - crit_time = strtod(optarg, NULL); + result.config.crit_time_set = true; + result.config.crit_time = strtod(optarg, NULL); break; case 'W': - warn_entries = optarg; + result.config.warn_entries = optarg; break; case 'C': - crit_entries = optarg; + result.config.crit_entries = optarg; break; #ifdef HAVE_LDAP_SET_OPTION case '2': - ld_protocol = 2; + result.config.ld_protocol = 2; break; case '3': - ld_protocol = 3; + result.config.ld_protocol = 3; break; -#endif +#endif // HAVE_LDAP_SET_OPTION case '4': address_family = AF_INET; break; case 'v': - verbose = true; + verbose++; break; case 'T': - if (!ssl_on_connect) { - starttls = true; + if (!result.config.ssl_on_connect) { + result.config.starttls = true; } else { usage_va(_("%s cannot be combined with %s"), "-T/--starttls", "-S/--ssl"); } break; case 'S': - if (!starttls) { - ssl_on_connect = true; - if (ld_port == -1) { - ld_port = LDAPS_PORT; + if (!result.config.starttls) { + result.config.ssl_on_connect = true; + if (result.config.ld_port == -1) { + result.config.ld_port = LDAPS_PORT; } } else { usage_va(_("%s cannot be combined with %s"), "-S/--ssl", "-T/--starttls"); @@ -391,39 +368,44 @@ int process_arguments(int argc, char **argv) { } } - c = optind; - if (ld_host == NULL && is_host(argv[c])) { - ld_host = strdup(argv[c++]); + int index = optind; + if ((result.config.ld_host == NULL) && is_host(argv[index])) { + result.config.ld_host = strdup(argv[index++]); + } + + if ((result.config.ld_base == NULL) && argv[index]) { + result.config.ld_base = strdup(argv[index++]); } - if (ld_base == NULL && argv[c]) { - ld_base = strdup(argv[c++]); + if (result.config.ld_port == -1) { + result.config.ld_port = DEFAULT_PORT; } - if (ld_port == -1) { - ld_port = DEFAULT_PORT; + if (strstr(argv[0], "check_ldaps") && !result.config.starttls && !result.config.ssl_on_connect) { + result.config.starttls = true; } - return validate_arguments(); + return validate_arguments(result); } -int validate_arguments() { - if (ld_host == NULL || strlen(ld_host) == 0) { +check_ldap_config_wrapper validate_arguments(check_ldap_config_wrapper config_wrapper) { + if (config_wrapper.config.ld_host == NULL || strlen(config_wrapper.config.ld_host) == 0) { usage4(_("Please specify the host name\n")); } - if (ld_base == NULL) { + if (config_wrapper.config.ld_base == NULL) { usage4(_("Please specify the LDAP base\n")); } - if (crit_entries != NULL || warn_entries != NULL) { - set_thresholds(&entries_thresholds, warn_entries, crit_entries); + if (config_wrapper.config.crit_entries != NULL || config_wrapper.config.warn_entries != NULL) { + set_thresholds(&config_wrapper.config.entries_thresholds, config_wrapper.config.warn_entries, config_wrapper.config.crit_entries); } - if (ld_passwd == NULL) { - ld_passwd = getenv("LDAP_PASSWORD"); + + if (config_wrapper.config.ld_passwd == NULL) { + config_wrapper.config.ld_passwd = getenv("LDAP_PASSWORD"); } - return OK; + return config_wrapper; } void print_help(void) { diff --git a/plugins/check_ldap.d/config.h b/plugins/check_ldap.d/config.h new file mode 100644 index 00000000..97a9cfa7 --- /dev/null +++ b/plugins/check_ldap.d/config.h @@ -0,0 +1,61 @@ +#pragma once + +#include "../../config.h" +#include "thresholds.h" +#include +#include + +static char ld_defattr[] = "(objectclass=*)"; + +enum { +#ifdef HAVE_LDAP_SET_OPTION + DEFAULT_PROTOCOL = 2, +#endif +}; + +typedef struct { + char *ld_host; + char *ld_base; + char *ld_passwd; + char *ld_binddn; + char *ld_attr; + int ld_port; + bool starttls; + bool ssl_on_connect; +#ifdef HAVE_LDAP_SET_OPTION + int ld_protocol; +#endif + + char *warn_entries; + char *crit_entries; + thresholds *entries_thresholds; + bool warn_time_set; + double warn_time; + bool crit_time_set; + double crit_time; +} check_ldap_config; + +check_ldap_config check_ldap_config_init() { + check_ldap_config tmp = { + .ld_host = NULL, + .ld_base = NULL, + .ld_passwd = NULL, + .ld_binddn = NULL, + .ld_attr = ld_defattr, + .ld_port = -1, + .starttls = false, + .ssl_on_connect = false, +#ifdef HAVE_LDAP_SET_OPTION + .ld_protocol = DEFAULT_PROTOCOL, +#endif + + .warn_entries = NULL, + .crit_entries = NULL, + .entries_thresholds = NULL, + .warn_time_set = false, + .warn_time = 0, + .crit_time_set = false, + .crit_time = 0, + }; + return tmp; +} -- cgit v1.2.3-74-g34f1 From b3cb1bb45ae30ccf0e1266022c96ee6c24dfe754 Mon Sep 17 00:00:00 2001 From: Lorenz Kästle <12514511+RincewindsHat@users.noreply.github.com> Date: Tue, 11 Mar 2025 12:16:43 +0100 Subject: check_mrtg: clang-format --- plugins/check_mrtg.c | 66 +++++++++++++++++++++++++++++++++------------------- 1 file changed, 42 insertions(+), 24 deletions(-) diff --git a/plugins/check_mrtg.c b/plugins/check_mrtg.c index 632e66fb..e355fa11 100644 --- a/plugins/check_mrtg.c +++ b/plugins/check_mrtg.c @@ -58,8 +58,9 @@ int main(int argc, char **argv) { /* Parse extra opts if any */ argv = np_extra_opts(&argc, argv, progname); - if (process_arguments(argc, argv) == ERROR) + if (process_arguments(argc, argv) == ERROR) { usage4(_("Could not parse arguments\n")); + } /* open the MRTG log file for reading */ FILE *mtrg_log_file = fopen(log_file, "r"); @@ -78,12 +79,14 @@ int main(int argc, char **argv) { line++; /* skip the first line of the log file */ - if (line == 1) + if (line == 1) { continue; + } /* break out of read loop if we've passed the number of entries we want to read */ - if (line > 2) + if (line > 2) { break; + } /* grab the timestamp */ char *temp_buffer = strtok(input_buffer, " "); @@ -91,23 +94,27 @@ int main(int argc, char **argv) { /* grab the average value 1 rate */ temp_buffer = strtok(NULL, " "); - if (variable_number == 1) + if (variable_number == 1) { average_value_rate = strtoul(temp_buffer, NULL, 10); + } /* grab the average value 2 rate */ temp_buffer = strtok(NULL, " "); - if (variable_number == 2) + if (variable_number == 2) { average_value_rate = strtoul(temp_buffer, NULL, 10); + } /* grab the maximum value 1 rate */ temp_buffer = strtok(NULL, " "); - if (variable_number == 1) + if (variable_number == 1) { maximum_value_rate = strtoul(temp_buffer, NULL, 10); + } /* grab the maximum value 2 rate */ temp_buffer = strtok(NULL, " "); - if (variable_number == 2) + if (variable_number == 2) { maximum_value_rate = strtoul(temp_buffer, NULL, 10); + } } /* close the log file */ @@ -129,16 +136,18 @@ int main(int argc, char **argv) { unsigned long rate = 0L; /* else check the incoming/outgoing rates */ - if (use_average) + if (use_average) { rate = average_value_rate; - else + } else { rate = maximum_value_rate; + } int result = STATE_OK; - if (rate > value_critical_threshold) + if (rate > value_critical_threshold) { result = STATE_CRITICAL; - else if (rate > value_warning_threshold) + } else if (rate > value_warning_threshold) { result = STATE_WARNING; + } printf("%s. %s = %lu %s|%s\n", (use_average) ? _("Avg") : _("Max"), label, rate, units, perfdata(label, (long)rate, units, (int)value_warning_threshold, (long)value_warning_threshold, (int)value_critical_threshold, @@ -155,16 +164,18 @@ int process_arguments(int argc, char **argv) { {"label", required_argument, 0, 'l'}, {"units", required_argument, 0, 'u'}, {"variable", required_argument, 0, 'v'}, {"version", no_argument, 0, 'V'}, {"help", no_argument, 0, 'h'}, {0, 0, 0, 0}}; - if (argc < 2) + if (argc < 2) { return ERROR; + } for (int i = 1; i < argc; i++) { - if (strcmp("-to", argv[i]) == 0) + if (strcmp("-to", argv[i]) == 0) { strcpy(argv[i], "-t"); - else if (strcmp("-wt", argv[i]) == 0) + } else if (strcmp("-wt", argv[i]) == 0) { strcpy(argv[i], "-w"); - else if (strcmp("-ct", argv[i]) == 0) + } else if (strcmp("-ct", argv[i]) == 0) { strcpy(argv[i], "-c"); + } } int option_char; @@ -172,8 +183,9 @@ int process_arguments(int argc, char **argv) { while (1) { option_char = getopt_long(argc, argv, "hVF:e:a:v:c:w:l:u:", longopts, &option); - if (option_char == -1 || option_char == EOF) + if (option_char == -1 || option_char == EOF) { break; + } switch (option_char) { case 'F': /* input file */ @@ -183,15 +195,17 @@ int process_arguments(int argc, char **argv) { expire_minutes = atoi(optarg); break; case 'a': /* port */ - if (!strcmp(optarg, "MAX")) + if (!strcmp(optarg, "MAX")) { use_average = false; - else + } else { use_average = true; + } break; case 'v': variable_number = atoi(optarg); - if (variable_number < 1 || variable_number > 2) + if (variable_number < 1 || variable_number > 2) { usage4(_("Invalid variable number")); + } break; case 'w': /* critical time threshold */ value_warning_threshold = strtoul(optarg, NULL, 10); @@ -222,10 +236,11 @@ int process_arguments(int argc, char **argv) { } if (expire_minutes <= 0 && argc > option_char) { - if (is_intpos(argv[option_char])) + if (is_intpos(argv[option_char])) { expire_minutes = atoi(argv[option_char++]); - else + } else { die(STATE_UNKNOWN, _("%s is not a valid expiration time\nUse '%s -h' for additional help\n"), argv[option_char], progname); + } } if (argc > option_char && strcmp(argv[option_char], "MAX") == 0) { @@ -264,14 +279,17 @@ int process_arguments(int argc, char **argv) { } int validate_arguments(void) { - if (variable_number == -1) + if (variable_number == -1) { usage4(_("You must supply the variable number")); + } - if (label == NULL) + if (label == NULL) { label = strdup("value"); + } - if (units == NULL) + if (units == NULL) { units = strdup(""); + } return OK; } -- cgit v1.2.3-74-g34f1 From 23da18f10ce32c899f266ae703f0b9c2b3991d70 Mon Sep 17 00:00:00 2001 From: Lorenz Kästle <12514511+RincewindsHat@users.noreply.github.com> Date: Tue, 11 Mar 2025 12:39:14 +0100 Subject: Refactor check_mrtg --- plugins/Makefile.am | 1 + plugins/check_mrtg.c | 141 ++++++++++++++++++++++-------------------- plugins/check_mrtg.d/config.h | 36 +++++++++++ 3 files changed, 110 insertions(+), 68 deletions(-) create mode 100644 plugins/check_mrtg.d/config.h diff --git a/plugins/Makefile.am b/plugins/Makefile.am index 9d310a15..5e636f9b 100644 --- a/plugins/Makefile.am +++ b/plugins/Makefile.am @@ -55,6 +55,7 @@ EXTRA_DIST = t \ check_dbi.d \ check_ssh.d \ check_dns.d \ + check_mrtg.d \ check_apt.d \ check_by_ssh.d \ check_smtp.d \ diff --git a/plugins/check_mrtg.c b/plugins/check_mrtg.c index e355fa11..5bd276dc 100644 --- a/plugins/check_mrtg.c +++ b/plugins/check_mrtg.c @@ -35,21 +35,18 @@ const char *email = "devel@monitoring-plugins.org"; #include "common.h" #include "utils.h" +#include "check_mrtg.d/config.h" + +typedef struct { + int errorcode; + check_mrtg_config config; +} check_mrtg_config_wrapper; +static check_mrtg_config_wrapper process_arguments(int /*argc*/, char ** /*argv*/); +static check_mrtg_config_wrapper validate_arguments(check_mrtg_config_wrapper /*config_wrapper*/); -static int process_arguments(int /*argc*/, char ** /*argv*/); -static int validate_arguments(void); static void print_help(void); void print_usage(void); -static char *log_file = NULL; -static int expire_minutes = 0; -static bool use_average = true; -static int variable_number = -1; -static unsigned long value_warning_threshold = 0L; -static unsigned long value_critical_threshold = 0L; -static char *label; -static char *units; - int main(int argc, char **argv) { setlocale(LC_ALL, ""); bindtextdomain(PACKAGE, LOCALEDIR); @@ -58,24 +55,26 @@ 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_mrtg_config_wrapper tmp_config = process_arguments(argc, argv); + if (tmp_config.errorcode == ERROR) { usage4(_("Could not parse arguments\n")); } + const check_mrtg_config config = tmp_config.config; + /* open the MRTG log file for reading */ - FILE *mtrg_log_file = fopen(log_file, "r"); + FILE *mtrg_log_file = fopen(config.log_file, "r"); if (mtrg_log_file == NULL) { printf(_("Unable to open MRTG log file\n")); return STATE_UNKNOWN; } - time_t timestamp = 0L; - unsigned long average_value_rate = 0L; - unsigned long maximum_value_rate = 0L; + time_t timestamp = 0; + unsigned long average_value_rate = 0; + unsigned long maximum_value_rate = 0; char input_buffer[MAX_INPUT_BUFFER]; int line = 0; while (fgets(input_buffer, MAX_INPUT_BUFFER - 1, mtrg_log_file)) { - line++; /* skip the first line of the log file */ @@ -94,25 +93,25 @@ int main(int argc, char **argv) { /* grab the average value 1 rate */ temp_buffer = strtok(NULL, " "); - if (variable_number == 1) { + if (config.variable_number == 1) { average_value_rate = strtoul(temp_buffer, NULL, 10); } /* grab the average value 2 rate */ temp_buffer = strtok(NULL, " "); - if (variable_number == 2) { + if (config.variable_number == 2) { average_value_rate = strtoul(temp_buffer, NULL, 10); } /* grab the maximum value 1 rate */ temp_buffer = strtok(NULL, " "); - if (variable_number == 1) { + if (config.variable_number == 1) { maximum_value_rate = strtoul(temp_buffer, NULL, 10); } /* grab the maximum value 2 rate */ temp_buffer = strtok(NULL, " "); - if (variable_number == 2) { + if (config.variable_number == 2) { maximum_value_rate = strtoul(temp_buffer, NULL, 10); } } @@ -129,43 +128,49 @@ int main(int argc, char **argv) { /* make sure the MRTG data isn't too old */ time_t current_time; time(¤t_time); - if (expire_minutes > 0 && (current_time - timestamp) > (expire_minutes * 60)) { + if (config.expire_minutes > 0 && (current_time - timestamp) > (config.expire_minutes * 60)) { printf(_("MRTG data has expired (%d minutes old)\n"), (int)((current_time - timestamp) / 60)); return STATE_WARNING; } unsigned long rate = 0L; /* else check the incoming/outgoing rates */ - if (use_average) { + if (config.use_average) { rate = average_value_rate; } else { rate = maximum_value_rate; } int result = STATE_OK; - if (rate > value_critical_threshold) { + if (config.value_critical_threshold_set && rate > config.value_critical_threshold) { result = STATE_CRITICAL; - } else if (rate > value_warning_threshold) { + } else if (config.value_warning_threshold_set && rate > config.value_warning_threshold) { result = STATE_WARNING; } - printf("%s. %s = %lu %s|%s\n", (use_average) ? _("Avg") : _("Max"), label, rate, units, - perfdata(label, (long)rate, units, (int)value_warning_threshold, (long)value_warning_threshold, (int)value_critical_threshold, - (long)value_critical_threshold, 0, 0, 0, 0)); + printf("%s. %s = %lu %s|%s\n", (config.use_average) ? _("Avg") : _("Max"), config.label, rate, config.units, + perfdata(config.label, (long)rate, config.units, config.value_warning_threshold_set, (long)config.value_warning_threshold, + config.value_critical_threshold_set, (long)config.value_critical_threshold, 0, 0, 0, 0)); return result; } /* process command-line arguments */ -int process_arguments(int argc, char **argv) { +check_mrtg_config_wrapper process_arguments(int argc, char **argv) { static struct option longopts[] = { {"logfile", required_argument, 0, 'F'}, {"expires", required_argument, 0, 'e'}, {"aggregation", required_argument, 0, 'a'}, {"variable", required_argument, 0, 'v'}, {"critical", required_argument, 0, 'c'}, {"warning", required_argument, 0, 'w'}, {"label", required_argument, 0, 'l'}, {"units", required_argument, 0, 'u'}, {"variable", required_argument, 0, 'v'}, {"version", no_argument, 0, 'V'}, {"help", no_argument, 0, 'h'}, {0, 0, 0, 0}}; + check_mrtg_config_wrapper result = { + .errorcode = OK, + .config = check_mrtg_config_init(), + }; + if (argc < 2) { - return ERROR; + result.errorcode = ERROR; + return result; } for (int i = 1; i < argc; i++) { @@ -189,35 +194,33 @@ int process_arguments(int argc, char **argv) { switch (option_char) { case 'F': /* input file */ - log_file = optarg; + result.config.log_file = optarg; break; case 'e': /* ups name */ - expire_minutes = atoi(optarg); + result.config.expire_minutes = atoi(optarg); break; case 'a': /* port */ - if (!strcmp(optarg, "MAX")) { - use_average = false; - } else { - use_average = true; - } + result.config.use_average = (bool)(strcmp(optarg, "MAX")); break; case 'v': - variable_number = atoi(optarg); - if (variable_number < 1 || variable_number > 2) { + result.config.variable_number = atoi(optarg); + if (result.config.variable_number < 1 || result.config.variable_number > 2) { usage4(_("Invalid variable number")); } break; case 'w': /* critical time threshold */ - value_warning_threshold = strtoul(optarg, NULL, 10); + result.config.value_warning_threshold_set = true; + result.config.value_warning_threshold = strtoul(optarg, NULL, 10); break; case 'c': /* warning time threshold */ - value_critical_threshold = strtoul(optarg, NULL, 10); + result.config.value_critical_threshold_set = true; + result.config.value_critical_threshold = strtoul(optarg, NULL, 10); break; case 'l': /* label */ - label = optarg; + result.config.label = optarg; break; case 'u': /* timeout */ - units = optarg; + result.config.units = optarg; break; case 'V': /* version */ print_revision(progname, NP_VERSION); @@ -231,67 +234,69 @@ int process_arguments(int argc, char **argv) { } option_char = optind; - if (log_file == NULL && argc > option_char) { - log_file = argv[option_char++]; + if (result.config.log_file == NULL && argc > option_char) { + result.config.log_file = argv[option_char++]; } - if (expire_minutes <= 0 && argc > option_char) { + if (result.config.expire_minutes <= 0 && argc > option_char) { if (is_intpos(argv[option_char])) { - expire_minutes = atoi(argv[option_char++]); + result.config.expire_minutes = atoi(argv[option_char++]); } else { die(STATE_UNKNOWN, _("%s is not a valid expiration time\nUse '%s -h' for additional help\n"), argv[option_char], progname); } } if (argc > option_char && strcmp(argv[option_char], "MAX") == 0) { - use_average = false; + result.config.use_average = false; option_char++; } else if (argc > option_char && strcmp(argv[option_char], "AVG") == 0) { - use_average = true; + result.config.use_average = true; option_char++; } - if (argc > option_char && variable_number == -1) { - variable_number = atoi(argv[option_char++]); - if (variable_number < 1 || variable_number > 2) { + if (argc > option_char && result.config.variable_number == -1) { + result.config.variable_number = atoi(argv[option_char++]); + if (result.config.variable_number < 1 || result.config.variable_number > 2) { printf("%s :", argv[option_char]); usage(_("Invalid variable number\n")); } } - if (argc > option_char && value_warning_threshold == 0) { - value_warning_threshold = strtoul(argv[option_char++], NULL, 10); + if (argc > option_char && !result.config.value_warning_threshold_set) { + result.config.value_warning_threshold_set = true; + result.config.value_warning_threshold = strtoul(argv[option_char++], NULL, 10); } - if (argc > option_char && value_critical_threshold == 0) { - value_critical_threshold = strtoul(argv[option_char++], NULL, 10); + if (argc > option_char && !result.config.value_critical_threshold_set) { + result.config.value_critical_threshold_set = true; + result.config.value_critical_threshold = strtoul(argv[option_char++], NULL, 10); } - if (argc > option_char && strlen(label) == 0) { - label = argv[option_char++]; + if (argc > option_char && strlen(result.config.label) == 0) { + result.config.label = argv[option_char++]; } - if (argc > option_char && strlen(units) == 0) { - units = argv[option_char++]; + if (argc > option_char && strlen(result.config.units) == 0) { + result.config.units = argv[option_char++]; } - return validate_arguments(); + return validate_arguments(result); } -int validate_arguments(void) { - if (variable_number == -1) { +check_mrtg_config_wrapper validate_arguments(check_mrtg_config_wrapper config_wrapper) { + if (config_wrapper.config.variable_number == -1) { usage4(_("You must supply the variable number")); } - if (label == NULL) { - label = strdup("value"); + if (config_wrapper.config.label == NULL) { + config_wrapper.config.label = strdup("value"); } - if (units == NULL) { - units = strdup(""); + if (config_wrapper.config.units == NULL) { + config_wrapper.config.units = strdup(""); } - return OK; + return config_wrapper; } void print_help(void) { diff --git a/plugins/check_mrtg.d/config.h b/plugins/check_mrtg.d/config.h new file mode 100644 index 00000000..96b849a2 --- /dev/null +++ b/plugins/check_mrtg.d/config.h @@ -0,0 +1,36 @@ +#pragma once + +#include "../../config.h" +#include +#include + +typedef struct { + bool use_average; + int variable_number; + int expire_minutes; + char *label; + char *units; + char *log_file; + + bool value_warning_threshold_set; + unsigned long value_warning_threshold; + bool value_critical_threshold_set; + unsigned long value_critical_threshold; +} check_mrtg_config; + +check_mrtg_config check_mrtg_config_init() { + check_mrtg_config tmp = { + .use_average = true, + .variable_number = -1, + .expire_minutes = 0, + .label = NULL, + .units = NULL, + .log_file = NULL, + + .value_warning_threshold_set = false, + .value_warning_threshold = 0, + .value_critical_threshold_set = false, + .value_critical_threshold = 0, + }; + return tmp; +} -- cgit v1.2.3-74-g34f1 From e2b806ebf51c443909bea24a8f3a1daa6afe9723 Mon Sep 17 00:00:00 2001 From: Lorenz Kästle <12514511+RincewindsHat@users.noreply.github.com> Date: Tue, 11 Mar 2025 12:40:32 +0100 Subject: Remove unintented import --- plugins/check_ldap.d/config.h | 1 - 1 file changed, 1 deletion(-) diff --git a/plugins/check_ldap.d/config.h b/plugins/check_ldap.d/config.h index 97a9cfa7..c8a40610 100644 --- a/plugins/check_ldap.d/config.h +++ b/plugins/check_ldap.d/config.h @@ -2,7 +2,6 @@ #include "../../config.h" #include "thresholds.h" -#include #include static char ld_defattr[] = "(objectclass=*)"; -- cgit v1.2.3-74-g34f1 From 4d81e7942081834a5ef5334ae840d9f2843a4c5b Mon Sep 17 00:00:00 2001 From: Lorenz Kästle <12514511+RincewindsHat@users.noreply.github.com> Date: Tue, 11 Mar 2025 12:44:10 +0100 Subject: check_mrtgraf: clang-format --- plugins/check_mrtgtraf.c | 36 +++++++++++++++++++++++------------- 1 file changed, 23 insertions(+), 13 deletions(-) diff --git a/plugins/check_mrtgtraf.c b/plugins/check_mrtgtraf.c index e5a2e2ad..78dcda0d 100644 --- a/plugins/check_mrtgtraf.c +++ b/plugins/check_mrtgtraf.c @@ -56,13 +56,15 @@ int main(int argc, char **argv) { /* Parse extra opts if any */ argv = np_extra_opts(&argc, argv, progname); - if (process_arguments(argc, argv) == ERROR) + if (process_arguments(argc, argv) == ERROR) { usage4(_("Could not parse arguments")); + } /* open the MRTG log file for reading */ FILE *mrtg_log_file_ptr = fopen(log_file, "r"); - if (mrtg_log_file_ptr == NULL) + if (mrtg_log_file_ptr == NULL) { usage4(_("Unable to open MRTG log file")); + } time_t timestamp = 0L; char input_buffer[MAX_INPUT_BUFFER]; @@ -76,13 +78,15 @@ int main(int argc, char **argv) { line++; /* skip the first line of the log file */ - if (line == 1) + if (line == 1) { continue; + } /* break out of read loop */ /* if we've passed the number of entries we want to read */ - if (line > 2) + if (line > 2) { break; + } /* grab the timestamp */ char *temp_buffer = strtok(input_buffer, " "); @@ -109,14 +113,16 @@ int main(int argc, char **argv) { fclose(mrtg_log_file_ptr); /* if we couldn't read enough data, return an unknown error */ - if (line <= 2) + if (line <= 2) { usage4(_("Unable to process MRTG log file")); + } /* make sure the MRTG data isn't too old */ time_t current_time; time(¤t_time); - if ((expire_minutes > 0) && (current_time - timestamp) > (expire_minutes * 60)) + if ((expire_minutes > 0) && (current_time - timestamp) > (expire_minutes * 60)) { die(STATE_WARNING, _("MRTG data has expired (%d minutes old)\n"), (int)((current_time - timestamp) / 60)); + } unsigned long incoming_rate = 0L; unsigned long outgoing_rate = 0L; @@ -201,16 +207,18 @@ int process_arguments(int argc, char **argv) { {"help", no_argument, 0, 'h'}, {0, 0, 0, 0}}; - if (argc < 2) + if (argc < 2) { return ERROR; + } for (int i = 1; i < argc; i++) { - if (strcmp("-to", argv[i]) == 0) + if (strcmp("-to", argv[i]) == 0) { strcpy(argv[i], "-t"); - else if (strcmp("-wt", argv[i]) == 0) + } else if (strcmp("-wt", argv[i]) == 0) { strcpy(argv[i], "-w"); - else if (strcmp("-ct", argv[i]) == 0) + } else if (strcmp("-ct", argv[i]) == 0) { strcpy(argv[i], "-c"); + } } int option_char; @@ -218,8 +226,9 @@ int process_arguments(int argc, char **argv) { while (1) { option_char = getopt_long(argc, argv, "hVF:e:a:c:w:", longopts, &option); - if (option_char == -1 || option_char == EOF) + if (option_char == -1 || option_char == EOF) { break; + } switch (option_char) { case 'F': /* input file */ @@ -229,10 +238,11 @@ int process_arguments(int argc, char **argv) { expire_minutes = atoi(optarg); break; case 'a': /* aggregation (AVE or MAX) */ - if (!strcmp(optarg, "MAX")) + if (!strcmp(optarg, "MAX")) { use_average = false; - else + } else { use_average = true; + } break; case 'c': /* warning threshold */ sscanf(optarg, "%lu,%lu", &incoming_critical_threshold, &outgoing_critical_threshold); -- cgit v1.2.3-74-g34f1 From 94f81f6fc78003d4f6f7d75789e3c4b364747d8b Mon Sep 17 00:00:00 2001 From: Lorenz Kästle <12514511+RincewindsHat@users.noreply.github.com> Date: Tue, 11 Mar 2025 12:53:48 +0100 Subject: Refactor check_mrtgraf --- plugins/Makefile.am | 1 + plugins/check_mrtgraf.d/config.h | 30 +++++++++++ plugins/check_mrtgtraf.c | 108 ++++++++++++++++++++------------------- 3 files changed, 87 insertions(+), 52 deletions(-) create mode 100644 plugins/check_mrtgraf.d/config.h diff --git a/plugins/Makefile.am b/plugins/Makefile.am index 9d310a15..38e2ed28 100644 --- a/plugins/Makefile.am +++ b/plugins/Makefile.am @@ -55,6 +55,7 @@ EXTRA_DIST = t \ check_dbi.d \ check_ssh.d \ check_dns.d \ + check_mrtgraf.d \ check_apt.d \ check_by_ssh.d \ check_smtp.d \ diff --git a/plugins/check_mrtgraf.d/config.h b/plugins/check_mrtgraf.d/config.h new file mode 100644 index 00000000..6d949b50 --- /dev/null +++ b/plugins/check_mrtgraf.d/config.h @@ -0,0 +1,30 @@ +#pragma once + +#include "../../config.h" +#include +#include + +typedef struct { + char *log_file; + int expire_minutes; + bool use_average; + unsigned long incoming_warning_threshold; + unsigned long incoming_critical_threshold; + unsigned long outgoing_warning_threshold; + unsigned long outgoing_critical_threshold; + +} check_mrtgraf_config; + +check_mrtgraf_config check_mrtgraf_config_init() { + check_mrtgraf_config tmp = { + .log_file = NULL, + .expire_minutes = -1, + .use_average = true, + + .incoming_warning_threshold = 0, + .incoming_critical_threshold = 0, + .outgoing_warning_threshold = 0, + .outgoing_critical_threshold = 0, + }; + return tmp; +} diff --git a/plugins/check_mrtgtraf.c b/plugins/check_mrtgtraf.c index 78dcda0d..c9e26099 100644 --- a/plugins/check_mrtgtraf.c +++ b/plugins/check_mrtgtraf.c @@ -29,25 +29,23 @@ * *****************************************************************************/ -#include "common.h" -#include "utils.h" - const char *progname = "check_mrtgtraf"; const char *copyright = "1999-2024"; const char *email = "devel@monitoring-plugins.org"; -static int process_arguments(int /*argc*/, char ** /*argv*/); +#include "check_mrtgraf.d/config.h" +#include "common.h" +#include "utils.h" + +typedef struct { + int errorcode; + check_mrtgraf_config config; +} check_mrtgraf_config_wrapper; + +static check_mrtgraf_config_wrapper process_arguments(int /*argc*/, char ** /*argv*/); static void print_help(void); void print_usage(void); -static char *log_file = NULL; -static int expire_minutes = -1; -static bool use_average = true; -static unsigned long incoming_warning_threshold = 0L; -static unsigned long incoming_critical_threshold = 0L; -static unsigned long outgoing_warning_threshold = 0L; -static unsigned long outgoing_critical_threshold = 0L; - int main(int argc, char **argv) { setlocale(LC_ALL, ""); bindtextdomain(PACKAGE, LOCALEDIR); @@ -56,12 +54,15 @@ 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_mrtgraf_config_wrapper tmp_config = process_arguments(argc, argv); + if (tmp_config.errorcode == ERROR) { usage4(_("Could not parse arguments")); } + const check_mrtgraf_config config = tmp_config.config; + /* open the MRTG log file for reading */ - FILE *mrtg_log_file_ptr = fopen(log_file, "r"); + FILE *mrtg_log_file_ptr = fopen(config.log_file, "r"); if (mrtg_log_file_ptr == NULL) { usage4(_("Unable to open MRTG log file")); } @@ -120,14 +121,14 @@ int main(int argc, char **argv) { /* make sure the MRTG data isn't too old */ time_t current_time; time(¤t_time); - if ((expire_minutes > 0) && (current_time - timestamp) > (expire_minutes * 60)) { + if ((config.expire_minutes > 0) && (current_time - timestamp) > (config.expire_minutes * 60)) { die(STATE_WARNING, _("MRTG data has expired (%d minutes old)\n"), (int)((current_time - timestamp) / 60)); } unsigned long incoming_rate = 0L; unsigned long outgoing_rate = 0L; /* else check the incoming/outgoing rates */ - if (use_average) { + if (config.use_average) { incoming_rate = average_incoming_rate; outgoing_rate = average_outgoing_rate; } else { @@ -172,24 +173,26 @@ int main(int argc, char **argv) { /* report outgoing traffic in MBytes/sec */ else { strcpy(outgoing_speed_rating, "MB"); - adjusted_outgoing_rate = (double)(outgoing_rate / 1024.0 / 1024.0); + adjusted_outgoing_rate = (outgoing_rate / 1024.0 / 1024.0); } int result = STATE_OK; - if (incoming_rate > incoming_critical_threshold || outgoing_rate > outgoing_critical_threshold) { + if (incoming_rate > config.incoming_critical_threshold || outgoing_rate > config.outgoing_critical_threshold) { result = STATE_CRITICAL; - } else if (incoming_rate > incoming_warning_threshold || outgoing_rate > outgoing_warning_threshold) { + } else if (incoming_rate > config.incoming_warning_threshold || outgoing_rate > config.outgoing_warning_threshold) { result = STATE_WARNING; } char *error_message; - xasprintf(&error_message, _("%s. In = %0.1f %s/s, %s. Out = %0.1f %s/s|%s %s\n"), (use_average) ? _("Avg") : _("Max"), - adjusted_incoming_rate, incoming_speed_rating, (use_average) ? _("Avg") : _("Max"), adjusted_outgoing_rate, + xasprintf(&error_message, _("%s. In = %0.1f %s/s, %s. Out = %0.1f %s/s|%s %s\n"), (config.use_average) ? _("Avg") : _("Max"), + adjusted_incoming_rate, incoming_speed_rating, (config.use_average) ? _("Avg") : _("Max"), adjusted_outgoing_rate, outgoing_speed_rating, - fperfdata("in", adjusted_incoming_rate, incoming_speed_rating, (int)incoming_warning_threshold, incoming_warning_threshold, - (int)incoming_critical_threshold, incoming_critical_threshold, true, 0, false, 0), - fperfdata("out", adjusted_outgoing_rate, outgoing_speed_rating, (int)outgoing_warning_threshold, outgoing_warning_threshold, - (int)outgoing_critical_threshold, outgoing_critical_threshold, true, 0, false, 0)); + fperfdata("in", adjusted_incoming_rate, incoming_speed_rating, (int)config.incoming_warning_threshold, + config.incoming_warning_threshold, (int)config.incoming_critical_threshold, config.incoming_critical_threshold, + true, 0, false, 0), + fperfdata("out", adjusted_outgoing_rate, outgoing_speed_rating, (int)config.outgoing_warning_threshold, + config.outgoing_warning_threshold, (int)config.outgoing_critical_threshold, config.outgoing_critical_threshold, + true, 0, false, 0)); printf(_("Traffic %s - %s\n"), state_text(result), error_message); @@ -197,7 +200,7 @@ int main(int argc, char **argv) { } /* process command-line arguments */ -int process_arguments(int argc, char **argv) { +check_mrtgraf_config_wrapper process_arguments(int argc, char **argv) { static struct option longopts[] = {{"filename", required_argument, 0, 'F'}, {"expires", required_argument, 0, 'e'}, {"aggregation", required_argument, 0, 'a'}, @@ -207,8 +210,13 @@ int process_arguments(int argc, char **argv) { {"help", no_argument, 0, 'h'}, {0, 0, 0, 0}}; + check_mrtgraf_config_wrapper result = { + .errorcode = OK, + .config = check_mrtgraf_config_init(), + }; if (argc < 2) { - return ERROR; + result.errorcode = ERROR; + return result; } for (int i = 1; i < argc; i++) { @@ -223,7 +231,7 @@ int process_arguments(int argc, char **argv) { int option_char; int option = 0; - while (1) { + while (true) { option_char = getopt_long(argc, argv, "hVF:e:a:c:w:", longopts, &option); if (option_char == -1 || option_char == EOF) { @@ -232,23 +240,19 @@ int process_arguments(int argc, char **argv) { switch (option_char) { case 'F': /* input file */ - log_file = optarg; + result.config.log_file = optarg; break; case 'e': /* expiration time */ - expire_minutes = atoi(optarg); + result.config.expire_minutes = atoi(optarg); break; case 'a': /* aggregation (AVE or MAX) */ - if (!strcmp(optarg, "MAX")) { - use_average = false; - } else { - use_average = true; - } + result.config.use_average = (bool)(strcmp(optarg, "MAX")); break; case 'c': /* warning threshold */ - sscanf(optarg, "%lu,%lu", &incoming_critical_threshold, &outgoing_critical_threshold); + sscanf(optarg, "%lu,%lu", &result.config.incoming_critical_threshold, &result.config.outgoing_critical_threshold); break; case 'w': /* critical threshold */ - sscanf(optarg, "%lu,%lu", &incoming_warning_threshold, &outgoing_warning_threshold); + sscanf(optarg, "%lu,%lu", &result.config.incoming_warning_threshold, &result.config.outgoing_warning_threshold); break; case 'V': /* version */ print_revision(progname, NP_VERSION); @@ -262,39 +266,39 @@ int process_arguments(int argc, char **argv) { } option_char = optind; - if (argc > option_char && log_file == NULL) { - log_file = argv[option_char++]; + if (argc > option_char && result.config.log_file == NULL) { + result.config.log_file = argv[option_char++]; } - if (argc > option_char && expire_minutes == -1) { - expire_minutes = atoi(argv[option_char++]); + if (argc > option_char && result.config.expire_minutes == -1) { + result.config.expire_minutes = atoi(argv[option_char++]); } if (argc > option_char && strcmp(argv[option_char], "MAX") == 0) { - use_average = false; + result.config.use_average = false; option_char++; } else if (argc > option_char && strcmp(argv[option_char], "AVG") == 0) { - use_average = true; + result.config.use_average = true; option_char++; } - if (argc > option_char && incoming_warning_threshold == 0) { - incoming_warning_threshold = strtoul(argv[option_char++], NULL, 10); + if (argc > option_char && result.config.incoming_warning_threshold == 0) { + result.config.incoming_warning_threshold = strtoul(argv[option_char++], NULL, 10); } - if (argc > option_char && incoming_critical_threshold == 0) { - incoming_critical_threshold = strtoul(argv[option_char++], NULL, 10); + if (argc > option_char && result.config.incoming_critical_threshold == 0) { + result.config.incoming_critical_threshold = strtoul(argv[option_char++], NULL, 10); } - if (argc > option_char && outgoing_warning_threshold == 0) { - outgoing_warning_threshold = strtoul(argv[option_char++], NULL, 10); + if (argc > option_char && result.config.outgoing_warning_threshold == 0) { + result.config.outgoing_warning_threshold = strtoul(argv[option_char++], NULL, 10); } - if (argc > option_char && outgoing_critical_threshold == 0) { - outgoing_critical_threshold = strtoul(argv[option_char++], NULL, 10); + if (argc > option_char && result.config.outgoing_critical_threshold == 0) { + result.config.outgoing_critical_threshold = strtoul(argv[option_char++], NULL, 10); } - return OK; + return result; } void print_help(void) { -- cgit v1.2.3-74-g34f1 From 3143b5217cf1c71a085e6c4c7d22a5b699c4ff07 Mon Sep 17 00:00:00 2001 From: Lorenz Kästle <12514511+RincewindsHat@users.noreply.github.com> Date: Tue, 11 Mar 2025 13:22:13 +0100 Subject: Refactor check_mysql --- plugins/Makefile.am | 1 + plugins/check_mysql.c | 217 +++++++++++++++++++---------------------- plugins/check_mysql.d/config.h | 58 +++++++++++ 3 files changed, 160 insertions(+), 116 deletions(-) create mode 100644 plugins/check_mysql.d/config.h diff --git a/plugins/Makefile.am b/plugins/Makefile.am index 06958849..9449f051 100644 --- a/plugins/Makefile.am +++ b/plugins/Makefile.am @@ -60,6 +60,7 @@ EXTRA_DIST = t \ check_apt.d \ check_by_ssh.d \ check_smtp.d \ + check_mysql.d \ check_dig.d \ check_cluster.d \ check_fping.d diff --git a/plugins/check_mysql.c b/plugins/check_mysql.c index 2b6cfeaf..ca3422b5 100644 --- a/plugins/check_mysql.c +++ b/plugins/check_mysql.c @@ -40,32 +40,14 @@ const char *email = "devel@monitoring-plugins.org"; #include "utils.h" #include "utils_base.h" #include "netutils.h" +#include "check_mysql.d/config.h" #include #include #include -static char *db_user = NULL; -static char *db_host = NULL; -static char *db_socket = NULL; -static char *db_pass = NULL; -static char *db = NULL; -static char *ca_cert = NULL; -static char *ca_dir = NULL; -static char *cert = NULL; -static char *key = NULL; -static char *ciphers = NULL; -static bool ssl = false; -static char *opt_file = NULL; -static char *opt_group = NULL; -static unsigned int db_port = MYSQL_PORT; -static bool check_replica = false; -static bool ignore_auth = false; static int verbose = 0; -static double warning_time = 0; -static double critical_time = 0; - #define LENGTH_METRIC_UNIT 6 static const char *metric_unit[LENGTH_METRIC_UNIT] = { "Open_files", "Open_tables", "Qcache_free_memory", "Qcache_queries_in_cache", "Threads_connected", "Threads_running"}; @@ -78,28 +60,16 @@ static const char *metric_counter[LENGTH_METRIC_COUNTER] = { #define MYSQLDUMP_THREADS_QUERY \ "SELECT COUNT(1) mysqldumpThreads FROM information_schema.processlist WHERE info LIKE 'SELECT /*!40001 SQL_NO_CACHE */%'" -static thresholds *my_threshold = NULL; - -static int process_arguments(int, char **); -static int validate_arguments(void); +typedef struct { + int errorcode; + check_mysql_config config; +} check_mysql_config_wrapper; +static check_mysql_config_wrapper process_arguments(int /*argc*/, char ** /*argv*/); +static check_mysql_config_wrapper validate_arguments(check_mysql_config_wrapper /*config_wrapper*/); static void print_help(void); void print_usage(void); int main(int argc, char **argv) { - - MYSQL mysql; - MYSQL_RES *res; - MYSQL_ROW row; - - /* should be status */ - - char *result = NULL; - char *error = NULL; - char replica_result[REPLICA_RESULTSIZE] = {0}; - char *perf; - - perf = strdup(""); - setlocale(LC_ALL, ""); bindtextdomain(PACKAGE, LOCALEDIR); textdomain(PACKAGE); @@ -107,36 +77,43 @@ 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_mysql_config_wrapper tmp_config = process_arguments(argc, argv); + if (tmp_config.errorcode == ERROR) { usage4(_("Could not parse arguments")); } + const check_mysql_config config = tmp_config.config; + + MYSQL mysql; /* initialize mysql */ mysql_init(&mysql); - if (opt_file != NULL) { - mysql_options(&mysql, MYSQL_READ_DEFAULT_FILE, opt_file); + if (config.opt_file != NULL) { + mysql_options(&mysql, MYSQL_READ_DEFAULT_FILE, config.opt_file); } - if (opt_group != NULL) { - mysql_options(&mysql, MYSQL_READ_DEFAULT_GROUP, opt_group); + if (config.opt_group != NULL) { + mysql_options(&mysql, MYSQL_READ_DEFAULT_GROUP, config.opt_group); } else { mysql_options(&mysql, MYSQL_READ_DEFAULT_GROUP, "client"); } - if (ssl) { - mysql_ssl_set(&mysql, key, cert, ca_cert, ca_dir, ciphers); + if (config.ssl) { + mysql_ssl_set(&mysql, config.key, config.cert, config.ca_cert, config.ca_dir, config.ciphers); } /* establish a connection to the server and error checking */ - if (!mysql_real_connect(&mysql, db_host, db_user, db_pass, db, db_port, db_socket, 0)) { + if (!mysql_real_connect(&mysql, config.db_host, config.db_user, config.db_pass, config.db, config.db_port, config.db_socket, 0)) { /* Depending on internally-selected auth plugin MySQL might return */ /* ER_ACCESS_DENIED_NO_PASSWORD_ERROR or ER_ACCESS_DENIED_ERROR. */ /* Semantically these errors are the same. */ - if (ignore_auth && (mysql_errno(&mysql) == ER_ACCESS_DENIED_ERROR || mysql_errno(&mysql) == ER_ACCESS_DENIED_NO_PASSWORD_ERROR)) { + if (config.ignore_auth && + (mysql_errno(&mysql) == ER_ACCESS_DENIED_ERROR || mysql_errno(&mysql) == ER_ACCESS_DENIED_NO_PASSWORD_ERROR)) { printf("MySQL OK - Version: %s (protocol %d)\n", mysql_get_server_info(&mysql), mysql_get_proto_info(&mysql)); mysql_close(&mysql); return STATE_OK; - } else if (mysql_errno(&mysql) == CR_UNKNOWN_HOST) { + } + + if (mysql_errno(&mysql) == CR_UNKNOWN_HOST) { die(STATE_WARNING, "%s\n", mysql_error(&mysql)); } else if (mysql_errno(&mysql) == CR_VERSION_ERROR) { die(STATE_WARNING, "%s\n", mysql_error(&mysql)); @@ -152,7 +129,7 @@ int main(int argc, char **argv) { } /* get the server stats */ - result = strdup(mysql_stat(&mysql)); + char *result = strdup(mysql_stat(&mysql)); /* error checking once more */ if (mysql_error(&mysql)) { @@ -165,6 +142,10 @@ int main(int argc, char **argv) { } } + char *perf = strdup(""); + char *error = NULL; + MYSQL_RES *res; + MYSQL_ROW row; /* try to fetch some perf data */ if (mysql_query(&mysql, "show global status") == 0) { if ((res = mysql_store_result(&mysql)) == NULL) { @@ -174,15 +155,13 @@ int main(int argc, char **argv) { } while ((row = mysql_fetch_row(res)) != NULL) { - int i; - - for (i = 0; i < LENGTH_METRIC_UNIT; i++) { + for (int i = 0; i < LENGTH_METRIC_UNIT; i++) { if (strcmp(row[0], metric_unit[i]) == 0) { xasprintf(&perf, "%s%s ", perf, perfdata(metric_unit[i], atol(row[1]), "", false, 0, false, 0, false, 0, false, 0)); continue; } } - for (i = 0; i < LENGTH_METRIC_COUNTER; i++) { + for (int i = 0; i < LENGTH_METRIC_COUNTER; i++) { if (strcmp(row[0], metric_counter[i]) == 0) { xasprintf(&perf, "%s%s ", perf, perfdata(metric_counter[i], atol(row[1]), "c", false, 0, false, 0, false, 0, false, 0)); continue; @@ -195,8 +174,8 @@ int main(int argc, char **argv) { } } - if (check_replica) { - + char replica_result[REPLICA_RESULTSIZE] = {0}; + if (config.check_replica) { // Detect which version we are, on older version // "show slave status" should work, on newer ones // "show replica status" @@ -283,12 +262,14 @@ int main(int argc, char **argv) { } else { /* mysql 4.x.x and mysql 5.x.x */ - int replica_io_field = -1, replica_sql_field = -1, seconds_behind_field = -1, i, num_fields; + int replica_io_field = -1; + int replica_sql_field = -1; + int seconds_behind_field = -1; + int num_fields; MYSQL_FIELD *fields; - num_fields = mysql_num_fields(res); fields = mysql_fetch_fields(res); - for (i = 0; i < num_fields; i++) { + for (int i = 0; i < num_fields; i++) { if (strcmp(fields[i].name, "Slave_IO_Running") == 0) { replica_io_field = i; continue; @@ -353,11 +334,11 @@ int main(int argc, char **argv) { double value = atof(row[seconds_behind_field]); int status; - status = get_status(value, my_threshold); + status = get_status(value, config.my_threshold); xasprintf(&perf, "%s %s", perf, - fperfdata("seconds behind master", value, "s", true, (double)warning_time, true, (double)critical_time, false, 0, - false, 0)); + fperfdata("seconds behind master", value, "s", true, (double)config.warning_time, true, + (double)config.critical_time, false, 0, false, 0)); if (status == STATE_WARNING) { printf("SLOW_REPLICA %s: %s|%s\n", _("WARNING"), replica_result, perf); @@ -377,7 +358,7 @@ int main(int argc, char **argv) { mysql_close(&mysql); /* print out the result of stats */ - if (check_replica) { + if (config.check_replica) { printf("%s %s|%s\n", result, replica_result, perf); } else { printf("%s|%s\n", result, perf); @@ -389,12 +370,7 @@ int main(int argc, char **argv) { #define CHECK_REPLICA_OPT CHAR_MAX + 1 /* process command-line arguments */ -int process_arguments(int argc, char **argv) { - int c; - char *warning = NULL; - char *critical = NULL; - - int option = 0; +check_mysql_config_wrapper process_arguments(int argc, char **argv) { static struct option longopts[] = {{"hostname", required_argument, 0, 'H'}, {"socket", required_argument, 0, 's'}, {"database", required_argument, 0, 'd'}, @@ -419,56 +395,66 @@ int process_arguments(int argc, char **argv) { {"ciphers", required_argument, 0, 'L'}, {0, 0, 0, 0}}; + check_mysql_config_wrapper result = { + .errorcode = OK, + .config = check_mysql_config_init(), + }; + if (argc < 1) { - return ERROR; + result.errorcode = ERROR; + return result; } - while (1) { - c = getopt_long(argc, argv, "hlvVnSP:p:u:d:H:s:c:w:a:k:C:D:L:f:g:", longopts, &option); + char *warning = NULL; + char *critical = NULL; + + int option = 0; + while (true) { + int option_index = getopt_long(argc, argv, "hlvVnSP:p:u:d:H:s:c:w:a:k:C:D:L:f:g:", longopts, &option); - if (c == -1 || c == EOF) { + if (option_index == -1 || option_index == EOF) { break; } - switch (c) { + switch (option_index) { case 'H': /* hostname */ if (is_host(optarg)) { - db_host = optarg; + result.config.db_host = optarg; } else if (*optarg == '/') { - db_socket = optarg; + result.config.db_socket = optarg; } else { usage2(_("Invalid hostname/address"), optarg); } break; case 's': /* socket */ - db_socket = optarg; + result.config.db_socket = optarg; break; case 'd': /* database */ - db = optarg; + result.config.db = optarg; break; case 'l': - ssl = true; + result.config.ssl = true; break; case 'C': - ca_cert = optarg; + result.config.ca_cert = optarg; break; case 'a': - cert = optarg; + result.config.cert = optarg; break; case 'k': - key = optarg; + result.config.key = optarg; break; case 'D': - ca_dir = optarg; + result.config.ca_dir = optarg; break; case 'L': - ciphers = optarg; + result.config.ciphers = optarg; break; case 'u': /* username */ - db_user = optarg; + result.config.db_user = optarg; break; case 'p': /* authentication information: password */ - db_pass = strdup(optarg); + result.config.db_pass = strdup(optarg); /* Delete the password from process list */ while (*optarg != '\0') { @@ -477,28 +463,28 @@ int process_arguments(int argc, char **argv) { } break; case 'f': /* client options file */ - opt_file = optarg; + result.config.opt_file = optarg; break; case 'g': /* client options group */ - opt_group = optarg; + result.config.opt_group = optarg; break; case 'P': /* critical time threshold */ - db_port = atoi(optarg); + result.config.db_port = atoi(optarg); break; case 'S': case CHECK_REPLICA_OPT: - check_replica = true; /* check-slave */ + result.config.check_replica = true; /* check-slave */ break; case 'n': - ignore_auth = true; /* ignore-auth */ + result.config.ignore_auth = true; /* ignore-auth */ break; case 'w': warning = optarg; - warning_time = strtod(warning, NULL); + result.config.warning_time = strtod(warning, NULL); break; case 'c': critical = optarg; - critical_time = strtod(critical, NULL); + result.config.critical_time = strtod(critical, NULL); break; case 'V': /* version */ print_revision(progname, NP_VERSION); @@ -514,48 +500,47 @@ int process_arguments(int argc, char **argv) { } } - c = optind; - - set_thresholds(&my_threshold, warning, critical); + int index = optind; - while (argc > c) { + set_thresholds(&result.config.my_threshold, warning, critical); - if (db_host == NULL) { - if (is_host(argv[c])) { - db_host = argv[c++]; + while (argc > index) { + if (result.config.db_host == NULL) { + if (is_host(argv[index])) { + result.config.db_host = argv[index++]; } else { - usage2(_("Invalid hostname/address"), argv[c]); + usage2(_("Invalid hostname/address"), argv[index]); } - } else if (db_user == NULL) { - db_user = argv[c++]; - } else if (db_pass == NULL) { - db_pass = argv[c++]; - } else if (db == NULL) { - db = argv[c++]; - } else if (is_intnonneg(argv[c])) { - db_port = atoi(argv[c++]); + } else if (result.config.db_user == NULL) { + result.config.db_user = argv[index++]; + } else if (result.config.db_pass == NULL) { + result.config.db_pass = argv[index++]; + } else if (result.config.db == NULL) { + result.config.db = argv[index++]; + } else if (is_intnonneg(argv[index])) { + result.config.db_port = atoi(argv[index++]); } else { break; } } - return validate_arguments(); + return validate_arguments(result); } -int validate_arguments(void) { - if (db_user == NULL) { - db_user = strdup(""); +check_mysql_config_wrapper validate_arguments(check_mysql_config_wrapper config_wrapper) { + if (config_wrapper.config.db_user == NULL) { + config_wrapper.config.db_user = strdup(""); } - if (db_host == NULL) { - db_host = strdup(""); + if (config_wrapper.config.db_host == NULL) { + config_wrapper.config.db_host = strdup(""); } - if (db == NULL) { - db = strdup(""); + if (config_wrapper.config.db == NULL) { + config_wrapper.config.db = strdup(""); } - return OK; + return config_wrapper; } void print_help(void) { diff --git a/plugins/check_mysql.d/config.h b/plugins/check_mysql.d/config.h new file mode 100644 index 00000000..71ddbe8d --- /dev/null +++ b/plugins/check_mysql.d/config.h @@ -0,0 +1,58 @@ +#pragma once + +#include "../../config.h" +#include "thresholds.h" +#include +#include + +typedef struct { + char *db_host; + unsigned int db_port; + char *db_user; + char *db_socket; + char *db_pass; + char *db; + char *ca_cert; + char *ca_dir; + char *cert; + char *key; + char *ciphers; + bool ssl; + char *opt_file; + char *opt_group; + + bool check_replica; + bool ignore_auth; + + double warning_time; + double critical_time; + thresholds *my_threshold; + +} check_mysql_config; + +check_mysql_config check_mysql_config_init() { + check_mysql_config tmp = { + .db_host = NULL, + .db_port = MYSQL_PORT, + .db = NULL, + .db_pass = NULL, + .db_socket = NULL, + .db_user = NULL, + .ca_cert = NULL, + .ca_dir = NULL, + .cert = NULL, + .key = NULL, + .ciphers = NULL, + .ssl = false, + .opt_file = NULL, + .opt_group = NULL, + + .check_replica = false, + .ignore_auth = false, + + .warning_time = 0, + .critical_time = 0, + .my_threshold = NULL, + }; + return tmp; +} -- cgit v1.2.3-74-g34f1 From e227016ac79a715301cac7eb41df7c752c882332 Mon Sep 17 00:00:00 2001 From: Lorenz Kästle <12514511+RincewindsHat@users.noreply.github.com> Date: Tue, 11 Mar 2025 13:33:38 +0100 Subject: check_mysql_query: clang-format --- plugins/check_mysql_query.c | 45 ++++++++++++++++++++++++++++----------------- 1 file changed, 28 insertions(+), 17 deletions(-) diff --git a/plugins/check_mysql_query.c b/plugins/check_mysql_query.c index 79b6e2f4..480453b1 100644 --- a/plugins/check_mysql_query.c +++ b/plugins/check_mysql_query.c @@ -67,35 +67,39 @@ int main(int argc, char **argv) { /* Parse extra opts if any */ argv = np_extra_opts(&argc, argv, progname); - if (process_arguments(argc, argv) == ERROR) + if (process_arguments(argc, argv) == ERROR) { usage4(_("Could not parse arguments")); + } MYSQL mysql; /* initialize mysql */ mysql_init(&mysql); - if (opt_file != NULL) + if (opt_file != NULL) { mysql_options(&mysql, MYSQL_READ_DEFAULT_FILE, opt_file); + } - if (opt_group != NULL) + if (opt_group != NULL) { mysql_options(&mysql, MYSQL_READ_DEFAULT_GROUP, opt_group); - else + } else { mysql_options(&mysql, MYSQL_READ_DEFAULT_GROUP, "client"); + } /* establish a connection to the server and error checking */ if (!mysql_real_connect(&mysql, db_host, db_user, db_pass, db, db_port, db_socket, 0)) { - if (mysql_errno(&mysql) == CR_UNKNOWN_HOST) + if (mysql_errno(&mysql) == CR_UNKNOWN_HOST) { die(STATE_WARNING, "QUERY %s: %s\n", _("WARNING"), mysql_error(&mysql)); - else if (mysql_errno(&mysql) == CR_VERSION_ERROR) + } else if (mysql_errno(&mysql) == CR_VERSION_ERROR) { die(STATE_WARNING, "QUERY %s: %s\n", _("WARNING"), mysql_error(&mysql)); - else if (mysql_errno(&mysql) == CR_OUT_OF_MEMORY) + } else if (mysql_errno(&mysql) == CR_OUT_OF_MEMORY) { die(STATE_WARNING, "QUERY %s: %s\n", _("WARNING"), mysql_error(&mysql)); - else if (mysql_errno(&mysql) == CR_IPSOCK_ERROR) + } else if (mysql_errno(&mysql) == CR_IPSOCK_ERROR) { die(STATE_WARNING, "QUERY %s: %s\n", _("WARNING"), mysql_error(&mysql)); - else if (mysql_errno(&mysql) == CR_SOCKET_CREATE_ERROR) + } else if (mysql_errno(&mysql) == CR_SOCKET_CREATE_ERROR) { die(STATE_WARNING, "QUERY %s: %s\n", _("WARNING"), mysql_error(&mysql)); - else + } else { die(STATE_CRITICAL, "QUERY %s: %s\n", _("CRITICAL"), mysql_error(&mysql)); + } } char *error = NULL; @@ -140,8 +144,9 @@ int main(int argc, char **argv) { /* close the connection */ mysql_close(&mysql); - if (verbose >= 3) + if (verbose >= 3) { printf("mysql result: %f\n", value); + } int status = get_status(value, my_thresholds); @@ -170,8 +175,9 @@ int process_arguments(int argc, char **argv) { {"version", no_argument, 0, 'V'}, {"help", no_argument, 0, 'h'}, {"query", required_argument, 0, 'q'}, {"warning", required_argument, 0, 'w'}, {"critical", required_argument, 0, 'c'}, {0, 0, 0, 0}}; - if (argc < 1) + if (argc < 1) { return ERROR; + } char *warning = NULL; char *critical = NULL; @@ -180,8 +186,9 @@ int process_arguments(int argc, char **argv) { int option = 0; int option_char = getopt_long(argc, argv, "hvVP:p:u:d:H:s:q:w:c:f:g:", longopts, &option); - if (option_char == -1 || option_char == EOF) + if (option_char == -1 || option_char == EOF) { break; + } switch (option_char) { case 'H': /* hostname */ @@ -247,17 +254,21 @@ int process_arguments(int argc, char **argv) { } int validate_arguments(void) { - if (sql_query == NULL) + if (sql_query == NULL) { usage("Must specify a SQL query to run"); + } - if (db_user == NULL) + if (db_user == NULL) { db_user = strdup(""); + } - if (db_host == NULL) + if (db_host == NULL) { db_host = strdup(""); + } - if (db == NULL) + if (db == NULL) { db = strdup(""); + } return OK; } -- cgit v1.2.3-74-g34f1 From 013b4d64899c22532f9578b4d64fa3b646e4a0c4 Mon Sep 17 00:00:00 2001 From: Lorenz Kästle <12514511+RincewindsHat@users.noreply.github.com> Date: Tue, 11 Mar 2025 13:44:55 +0100 Subject: Refactor check_mysql_query --- plugins/Makefile.am | 1 + plugins/check_mysql_query.c | 96 ++++++++++++++++++------------------ plugins/check_mysql_query.d/config.h | 36 ++++++++++++++ 3 files changed, 86 insertions(+), 47 deletions(-) create mode 100644 plugins/check_mysql_query.d/config.h diff --git a/plugins/Makefile.am b/plugins/Makefile.am index 19b3d172..1e4789ff 100644 --- a/plugins/Makefile.am +++ b/plugins/Makefile.am @@ -57,6 +57,7 @@ EXTRA_DIST = t \ check_ssh.d \ check_dns.d \ check_mrtgraf.d \ + check_mysql_query.d \ check_mrtg.d \ check_apt.d \ check_by_ssh.d \ diff --git a/plugins/check_mysql_query.c b/plugins/check_mysql_query.c index 480453b1..5e04a94b 100644 --- a/plugins/check_mysql_query.c +++ b/plugins/check_mysql_query.c @@ -37,27 +37,21 @@ const char *email = "devel@monitoring-plugins.org"; #include "utils.h" #include "utils_base.h" #include "netutils.h" +#include "check_mysql_query.d/config.h" #include #include -static char *db_user = NULL; -static char *db_host = NULL; -static char *db_socket = NULL; -static char *db_pass = NULL; -static char *db = NULL; -static char *opt_file = NULL; -static char *opt_group = NULL; -static unsigned int db_port = MYSQL_PORT; - -static int process_arguments(int /*argc*/, char ** /*argv*/); -static int validate_arguments(void); +typedef struct { + int errorcode; + check_mysql_query_config config; +} check_mysql_query_config_wrapper; +static check_mysql_query_config_wrapper process_arguments(int /*argc*/, char ** /*argv*/); +static check_mysql_query_config_wrapper validate_arguments(check_mysql_query_config_wrapper /*config_wrapper*/); static void print_help(void); void print_usage(void); -static char *sql_query = NULL; static int verbose = 0; -static thresholds *my_thresholds = NULL; int main(int argc, char **argv) { setlocale(LC_ALL, ""); @@ -67,26 +61,29 @@ 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_mysql_query_config_wrapper tmp_config = process_arguments(argc, argv); + if (tmp_config.errorcode == ERROR) { usage4(_("Could not parse arguments")); } + const check_mysql_query_config config = tmp_config.config; + MYSQL mysql; /* initialize mysql */ mysql_init(&mysql); - if (opt_file != NULL) { - mysql_options(&mysql, MYSQL_READ_DEFAULT_FILE, opt_file); + if (config.opt_file != NULL) { + mysql_options(&mysql, MYSQL_READ_DEFAULT_FILE, config.opt_file); } - if (opt_group != NULL) { - mysql_options(&mysql, MYSQL_READ_DEFAULT_GROUP, opt_group); + if (config.opt_group != NULL) { + mysql_options(&mysql, MYSQL_READ_DEFAULT_GROUP, config.opt_group); } else { mysql_options(&mysql, MYSQL_READ_DEFAULT_GROUP, "client"); } /* establish a connection to the server and error checking */ - if (!mysql_real_connect(&mysql, db_host, db_user, db_pass, db, db_port, db_socket, 0)) { + if (!mysql_real_connect(&mysql, config.db_host, config.db_user, config.db_pass, config.db, config.db_port, config.db_socket, 0)) { if (mysql_errno(&mysql) == CR_UNKNOWN_HOST) { die(STATE_WARNING, "QUERY %s: %s\n", _("WARNING"), mysql_error(&mysql)); } else if (mysql_errno(&mysql) == CR_VERSION_ERROR) { @@ -103,7 +100,7 @@ int main(int argc, char **argv) { } char *error = NULL; - if (mysql_query(&mysql, sql_query) != 0) { + if (mysql_query(&mysql, config.sql_query) != 0) { error = strdup(mysql_error(&mysql)); mysql_close(&mysql); die(STATE_CRITICAL, "QUERY %s: %s - %s\n", _("CRITICAL"), _("Error with query"), error); @@ -148,7 +145,7 @@ int main(int argc, char **argv) { printf("mysql result: %f\n", value); } - int status = get_status(value, my_thresholds); + int status = get_status(value, config.my_thresholds); if (status == STATE_OK) { printf("QUERY %s: ", _("OK")); @@ -157,17 +154,16 @@ int main(int argc, char **argv) { } else if (status == STATE_CRITICAL) { printf("QUERY %s: ", _("CRITICAL")); } - printf(_("'%s' returned %f | %s"), sql_query, value, - fperfdata("result", value, "", my_thresholds->warning ? true : false, my_thresholds->warning ? my_thresholds->warning->end : 0, - my_thresholds->critical ? true : false, my_thresholds->critical ? my_thresholds->critical->end : 0, false, 0, false, - 0)); + printf(_("'%s' returned %f | %s"), config.sql_query, value, + fperfdata("result", value, "", config.my_thresholds->warning, config.my_thresholds->warning ? config.my_thresholds->warning->end : 0, + config.my_thresholds->critical, config.my_thresholds->critical ? config.my_thresholds->critical->end : 0, false, 0, false, 0)); printf("\n"); return status; } /* process command-line arguments */ -int process_arguments(int argc, char **argv) { +check_mysql_query_config_wrapper process_arguments(int argc, char **argv) { static struct option longopts[] = { {"hostname", required_argument, 0, 'H'}, {"socket", required_argument, 0, 's'}, {"database", required_argument, 0, 'd'}, {"username", required_argument, 0, 'u'}, {"password", required_argument, 0, 'p'}, {"file", required_argument, 0, 'f'}, @@ -175,8 +171,14 @@ int process_arguments(int argc, char **argv) { {"version", no_argument, 0, 'V'}, {"help", no_argument, 0, 'h'}, {"query", required_argument, 0, 'q'}, {"warning", required_argument, 0, 'w'}, {"critical", required_argument, 0, 'c'}, {0, 0, 0, 0}}; + check_mysql_query_config_wrapper result = { + .errorcode = OK, + .config = check_mysql_query_config_init(), + }; + if (argc < 1) { - return ERROR; + result.errorcode = ERROR; + return result; } char *warning = NULL; @@ -193,22 +195,22 @@ int process_arguments(int argc, char **argv) { switch (option_char) { case 'H': /* hostname */ if (is_host(optarg)) { - db_host = optarg; + result.config.db_host = optarg; } else { usage2(_("Invalid hostname/address"), optarg); } break; case 's': /* socket */ - db_socket = optarg; + result.config.db_socket = optarg; break; case 'd': /* database */ - db = optarg; + result.config.db = optarg; break; case 'u': /* username */ - db_user = optarg; + result.config.db_user = optarg; break; case 'p': /* authentication information: password */ - db_pass = strdup(optarg); + result.config.db_pass = strdup(optarg); /* Delete the password from process list */ while (*optarg != '\0') { @@ -217,13 +219,13 @@ int process_arguments(int argc, char **argv) { } break; case 'f': /* client options file */ - opt_file = optarg; + result.config.opt_file = optarg; break; case 'g': /* client options group */ - opt_group = optarg; + result.config.opt_group = optarg; break; case 'P': /* critical time threshold */ - db_port = atoi(optarg); + result.config.db_port = atoi(optarg); break; case 'v': verbose++; @@ -235,7 +237,7 @@ int process_arguments(int argc, char **argv) { print_help(); exit(STATE_UNKNOWN); case 'q': - xasprintf(&sql_query, "%s", optarg); + xasprintf(&result.config.sql_query, "%s", optarg); break; case 'w': warning = optarg; @@ -248,29 +250,29 @@ int process_arguments(int argc, char **argv) { } } - set_thresholds(&my_thresholds, warning, critical); + set_thresholds(&result.config.my_thresholds, warning, critical); - return validate_arguments(); + return validate_arguments(result); } -int validate_arguments(void) { - if (sql_query == NULL) { +check_mysql_query_config_wrapper validate_arguments(check_mysql_query_config_wrapper config_wrapper) { + if (config_wrapper.config.sql_query == NULL) { usage("Must specify a SQL query to run"); } - if (db_user == NULL) { - db_user = strdup(""); + if (config_wrapper.config.db_user == NULL) { + config_wrapper.config.db_user = strdup(""); } - if (db_host == NULL) { - db_host = strdup(""); + if (config_wrapper.config.db_host == NULL) { + config_wrapper.config.db_host = strdup(""); } - if (db == NULL) { - db = strdup(""); + if (config_wrapper.config.db == NULL) { + config_wrapper.config.db = strdup(""); } - return OK; + return config_wrapper; } void print_help(void) { diff --git a/plugins/check_mysql_query.d/config.h b/plugins/check_mysql_query.d/config.h new file mode 100644 index 00000000..be019160 --- /dev/null +++ b/plugins/check_mysql_query.d/config.h @@ -0,0 +1,36 @@ +#pragma once + +#include "../../config.h" +#include "thresholds.h" +#include + +typedef struct { + char *db_host; + char *db_socket; + char *db; + char *db_user; + char *db_pass; + char *opt_file; + char *opt_group; + unsigned int db_port; + + char *sql_query; + thresholds *my_thresholds; +} check_mysql_query_config; + +check_mysql_query_config check_mysql_query_config_init() { + check_mysql_query_config tmp = { + .db_host = NULL, + .db_socket = NULL, + .db = NULL, + .db_user = NULL, + .db_pass = NULL, + .opt_file = NULL, + .opt_group = NULL, + .db_port = MYSQL_PORT, + + .sql_query = NULL, + .my_thresholds = NULL, + }; + return tmp; +} -- cgit v1.2.3-74-g34f1 From 69c61625e4f8977cb06a2514a26fc5805f29c531 Mon Sep 17 00:00:00 2001 From: Lorenz Kästle <12514511+RincewindsHat@users.noreply.github.com> Date: Tue, 11 Mar 2025 16:02:24 +0100 Subject: typo: mrtgraf -> mrtgtraf --- plugins/Makefile.am | 2 +- plugins/check_mrtgraf.d/config.h | 30 ------------------------------ plugins/check_mrtgtraf.c | 18 +++++++++--------- plugins/check_mrtgtraf.d/config.h | 30 ++++++++++++++++++++++++++++++ 4 files changed, 40 insertions(+), 40 deletions(-) delete mode 100644 plugins/check_mrtgraf.d/config.h create mode 100644 plugins/check_mrtgtraf.d/config.h diff --git a/plugins/Makefile.am b/plugins/Makefile.am index 1e4789ff..305924bf 100644 --- a/plugins/Makefile.am +++ b/plugins/Makefile.am @@ -56,7 +56,7 @@ EXTRA_DIST = t \ check_dbi.d \ check_ssh.d \ check_dns.d \ - check_mrtgraf.d \ + check_mrtgtraf.d \ check_mysql_query.d \ check_mrtg.d \ check_apt.d \ diff --git a/plugins/check_mrtgraf.d/config.h b/plugins/check_mrtgraf.d/config.h deleted file mode 100644 index 6d949b50..00000000 --- a/plugins/check_mrtgraf.d/config.h +++ /dev/null @@ -1,30 +0,0 @@ -#pragma once - -#include "../../config.h" -#include -#include - -typedef struct { - char *log_file; - int expire_minutes; - bool use_average; - unsigned long incoming_warning_threshold; - unsigned long incoming_critical_threshold; - unsigned long outgoing_warning_threshold; - unsigned long outgoing_critical_threshold; - -} check_mrtgraf_config; - -check_mrtgraf_config check_mrtgraf_config_init() { - check_mrtgraf_config tmp = { - .log_file = NULL, - .expire_minutes = -1, - .use_average = true, - - .incoming_warning_threshold = 0, - .incoming_critical_threshold = 0, - .outgoing_warning_threshold = 0, - .outgoing_critical_threshold = 0, - }; - return tmp; -} diff --git a/plugins/check_mrtgtraf.c b/plugins/check_mrtgtraf.c index c9e26099..8c7cf8aa 100644 --- a/plugins/check_mrtgtraf.c +++ b/plugins/check_mrtgtraf.c @@ -33,16 +33,16 @@ const char *progname = "check_mrtgtraf"; const char *copyright = "1999-2024"; const char *email = "devel@monitoring-plugins.org"; -#include "check_mrtgraf.d/config.h" +#include "check_mrtgtraf.d/config.h" #include "common.h" #include "utils.h" typedef struct { int errorcode; - check_mrtgraf_config config; -} check_mrtgraf_config_wrapper; + check_mrtgtraf_config config; +} check_mrtgtraf_config_wrapper; -static check_mrtgraf_config_wrapper process_arguments(int /*argc*/, char ** /*argv*/); +static check_mrtgtraf_config_wrapper process_arguments(int /*argc*/, char ** /*argv*/); static void print_help(void); void print_usage(void); @@ -54,12 +54,12 @@ int main(int argc, char **argv) { /* Parse extra opts if any */ argv = np_extra_opts(&argc, argv, progname); - check_mrtgraf_config_wrapper tmp_config = process_arguments(argc, argv); + check_mrtgtraf_config_wrapper tmp_config = process_arguments(argc, argv); if (tmp_config.errorcode == ERROR) { usage4(_("Could not parse arguments")); } - const check_mrtgraf_config config = tmp_config.config; + const check_mrtgtraf_config config = tmp_config.config; /* open the MRTG log file for reading */ FILE *mrtg_log_file_ptr = fopen(config.log_file, "r"); @@ -200,7 +200,7 @@ int main(int argc, char **argv) { } /* process command-line arguments */ -check_mrtgraf_config_wrapper process_arguments(int argc, char **argv) { +check_mrtgtraf_config_wrapper process_arguments(int argc, char **argv) { static struct option longopts[] = {{"filename", required_argument, 0, 'F'}, {"expires", required_argument, 0, 'e'}, {"aggregation", required_argument, 0, 'a'}, @@ -210,9 +210,9 @@ check_mrtgraf_config_wrapper process_arguments(int argc, char **argv) { {"help", no_argument, 0, 'h'}, {0, 0, 0, 0}}; - check_mrtgraf_config_wrapper result = { + check_mrtgtraf_config_wrapper result = { .errorcode = OK, - .config = check_mrtgraf_config_init(), + .config = check_mrtgtraf_config_init(), }; if (argc < 2) { result.errorcode = ERROR; diff --git a/plugins/check_mrtgtraf.d/config.h b/plugins/check_mrtgtraf.d/config.h new file mode 100644 index 00000000..94929ff7 --- /dev/null +++ b/plugins/check_mrtgtraf.d/config.h @@ -0,0 +1,30 @@ +#pragma once + +#include "../../config.h" +#include +#include + +typedef struct { + char *log_file; + int expire_minutes; + bool use_average; + unsigned long incoming_warning_threshold; + unsigned long incoming_critical_threshold; + unsigned long outgoing_warning_threshold; + unsigned long outgoing_critical_threshold; + +} check_mrtgtraf_config; + +check_mrtgtraf_config check_mrtgtraf_config_init() { + check_mrtgtraf_config tmp = { + .log_file = NULL, + .expire_minutes = -1, + .use_average = true, + + .incoming_warning_threshold = 0, + .incoming_critical_threshold = 0, + .outgoing_warning_threshold = 0, + .outgoing_critical_threshold = 0, + }; + return tmp; +} -- cgit v1.2.3-74-g34f1 From bc003d5e2ea837f7c49ce17d3be62b6a3ef24f85 Mon Sep 17 00:00:00 2001 From: Lorenz Kästle <12514511+RincewindsHat@users.noreply.github.com> Date: Tue, 11 Mar 2025 16:04:48 +0100 Subject: check_nagios: clang-format --- plugins/check_nagios.c | 42 +++++++++++++++++++++++++++--------------- 1 file changed, 27 insertions(+), 15 deletions(-) diff --git a/plugins/check_nagios.c b/plugins/check_nagios.c index 48629be3..72613f97 100644 --- a/plugins/check_nagios.c +++ b/plugins/check_nagios.c @@ -87,8 +87,9 @@ int main(int argc, char **argv) { /* Parse extra opts if any */ argv = np_extra_opts(&argc, argv, progname); - if (process_arguments(argc, argv) == ERROR) + if (process_arguments(argc, argv) == ERROR) { usage_va(_("Could not parse arguments")); + } /* Set signal handling and alarm timeout */ if (signal(SIGALRM, timeout_alarm_handler) == SIG_ERR) { @@ -113,18 +114,21 @@ int main(int argc, char **argv) { } if ((temp_ptr = strtok(input_buffer, "]")) != NULL) { temp_entry_time = strtoul(temp_ptr + 1, NULL, 10); - if (temp_entry_time > latest_entry_time) + if (temp_entry_time > latest_entry_time) { latest_entry_time = temp_entry_time; + } } } fclose(fp); - if (verbose >= 2) + if (verbose >= 2) { printf("command: %s\n", PS_COMMAND); + } /* run the command to check for the Nagios process.. */ - if ((result = np_runcmd(PS_COMMAND, &chld_out, &chld_err, 0)) != 0) + if ((result = np_runcmd(PS_COMMAND, &chld_out, &chld_err, 0)) != 0) { result = STATE_WARNING; + } /* count the number of matching Nagios processes... */ for (i = 0; i < chld_out.lines; i++) { @@ -159,8 +163,9 @@ int main(int argc, char **argv) { } /* If we get anything on stderr, at least set warning */ - if (chld_err.buflen) + if (chld_err.buflen) { result = max_state(result, STATE_WARNING); + } /* reset the alarm handler */ alarm(0); @@ -200,15 +205,17 @@ int process_arguments(int argc, char **argv) { {"version", no_argument, 0, 'V'}, {"help", no_argument, 0, 'h'}, {"verbose", no_argument, 0, 'v'}, {0, 0, 0, 0}}; - if (argc < 2) + if (argc < 2) { return ERROR; + } if (!is_option(argv[1])) { status_log = argv[1]; - if (is_intnonneg(argv[2])) + if (is_intnonneg(argv[2])) { expire_minutes = atoi(argv[2]); - else + } else { die(STATE_UNKNOWN, _("Expiration time must be an integer (seconds)\n")); + } process_string = argv[3]; return OK; } @@ -216,8 +223,9 @@ int process_arguments(int argc, char **argv) { while (1) { c = getopt_long(argc, argv, "+hVvF:C:e:t:", longopts, &option); - if (c == -1 || c == EOF || c == 1) + if (c == -1 || c == EOF || c == 1) { break; + } switch (c) { case 'h': /* help */ @@ -233,16 +241,18 @@ int process_arguments(int argc, char **argv) { process_string = optarg; break; case 'e': /* expiry time */ - if (is_intnonneg(optarg)) + if (is_intnonneg(optarg)) { expire_minutes = atoi(optarg); - else + } else { die(STATE_UNKNOWN, _("Expiration time must be an integer (seconds)\n")); + } break; case 't': /* timeout */ - if (is_intnonneg(optarg)) + if (is_intnonneg(optarg)) { timeout_interval = atoi(optarg); - else + } else { die(STATE_UNKNOWN, _("Timeout must be an integer (seconds)\n")); + } break; case 'v': verbose++; @@ -252,11 +262,13 @@ int process_arguments(int argc, char **argv) { } } - if (status_log == NULL) + if (status_log == NULL) { die(STATE_UNKNOWN, _("You must provide the status_log\n")); + } - if (process_string == NULL) + if (process_string == NULL) { die(STATE_UNKNOWN, _("You must provide a process string\n")); + } return OK; } -- cgit v1.2.3-74-g34f1 From b16360eede8d370698ba8836808a3b1dbd805edf Mon Sep 17 00:00:00 2001 From: Lorenz Kästle <12514511+RincewindsHat@users.noreply.github.com> Date: Tue, 11 Mar 2025 16:18:03 +0100 Subject: Refactor check_nagios --- plugins/Makefile.am | 1 + plugins/check_nagios.c | 134 +++++++++++++++++++++------------------- plugins/check_nagios.d/config.h | 19 ++++++ 3 files changed, 89 insertions(+), 65 deletions(-) create mode 100644 plugins/check_nagios.d/config.h diff --git a/plugins/Makefile.am b/plugins/Makefile.am index 1e4789ff..d27c9efd 100644 --- a/plugins/Makefile.am +++ b/plugins/Makefile.am @@ -53,6 +53,7 @@ EXTRA_DIST = t \ check_ldap.d \ check_hpjd.d \ check_game.d \ + check_nagios.d \ check_dbi.d \ check_ssh.d \ check_dns.d \ diff --git a/plugins/check_nagios.c b/plugins/check_nagios.c index 72613f97..a46dc1ed 100644 --- a/plugins/check_nagios.c +++ b/plugins/check_nagios.c @@ -39,47 +39,20 @@ const char *email = "devel@monitoring-plugins.org"; #include "common.h" #include "runcmd.h" #include "utils.h" - -static int process_arguments(int /*argc*/, char ** /*argv*/); +#include "states.h" +#include "check_nagios.d/config.h" + +typedef struct { + int errorcode; + check_nagios_config config; +} check_nagios_config_wrapper; +static check_nagios_config_wrapper process_arguments(int /*argc*/, char ** /*argv*/); static void print_help(void); void print_usage(void); -static char *status_log = NULL; -static char *process_string = NULL; -static int expire_minutes = 0; - static int verbose = 0; int main(int argc, char **argv) { - int result = STATE_UNKNOWN; - char input_buffer[MAX_INPUT_BUFFER]; - unsigned long latest_entry_time = 0L; - unsigned long temp_entry_time = 0L; - int proc_entries = 0; - time_t current_time; - char *temp_ptr; - FILE *fp; - int procuid = 0; - int procpid = 0; - int procppid = 0; - int procvsz = 0; - int procrss = 0; - float procpcpu = 0; - char procstat[8]; -#ifdef PS_USES_PROCETIME - char procetime[MAX_INPUT_BUFFER]; -#endif /* PS_USES_PROCETIME */ - char procprog[MAX_INPUT_BUFFER]; - char *procargs; - int pos; - int cols; - int expected_cols = PS_COLS - 1; - const char *zombie = "Z"; - char *temp_string; - output chld_out; - output chld_err; - size_t i; - setlocale(LC_ALL, ""); bindtextdomain(PACKAGE, LOCALEDIR); textdomain(PACKAGE); @@ -87,10 +60,14 @@ 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_nagios_config_wrapper tmp_config = process_arguments(argc, argv); + + if (tmp_config.errorcode == ERROR) { usage_va(_("Could not parse arguments")); } + const check_nagios_config config = tmp_config.config; + /* Set signal handling and alarm timeout */ if (signal(SIGALRM, timeout_alarm_handler) == SIG_ERR) { usage_va(_("Cannot catch SIGALRM")); @@ -100,13 +77,17 @@ int main(int argc, char **argv) { alarm(timeout_interval); /* open the status log */ - fp = fopen(status_log, "r"); - if (fp == NULL) { + FILE *log_file = fopen(config.status_log, "r"); + if (log_file == NULL) { die(STATE_CRITICAL, "NAGIOS %s: %s\n", _("CRITICAL"), _("Cannot open status log for reading!")); } + unsigned long latest_entry_time = 0L; + unsigned long temp_entry_time = 0L; + char input_buffer[MAX_INPUT_BUFFER]; + char *temp_ptr; /* get the date/time of the last item updated in the log */ - while (fgets(input_buffer, MAX_INPUT_BUFFER - 1, fp)) { + while (fgets(input_buffer, MAX_INPUT_BUFFER - 1, log_file)) { if ((temp_ptr = strstr(input_buffer, "created=")) != NULL) { temp_entry_time = strtoul(temp_ptr + 8, NULL, 10); latest_entry_time = temp_entry_time; @@ -119,20 +100,39 @@ int main(int argc, char **argv) { } } } - fclose(fp); + fclose(log_file); if (verbose >= 2) { printf("command: %s\n", PS_COMMAND); } /* run the command to check for the Nagios process.. */ + mp_state_enum result = STATE_UNKNOWN; + output chld_out; + output chld_err; if ((result = np_runcmd(PS_COMMAND, &chld_out, &chld_err, 0)) != 0) { result = STATE_WARNING; } + int procuid = 0; + int procpid = 0; + int procppid = 0; + int procvsz = 0; + int procrss = 0; + int proc_entries = 0; + float procpcpu = 0; + char procstat[8]; + char procprog[MAX_INPUT_BUFFER]; + char *procargs; +#ifdef PS_USES_PROCETIME + char procetime[MAX_INPUT_BUFFER]; +#endif /* PS_USES_PROCETIME */ + int pos; + int expected_cols = PS_COLS - 1; + const char *zombie = "Z"; /* count the number of matching Nagios processes... */ - for (i = 0; i < chld_out.lines; i++) { - cols = sscanf(chld_out.line[i], PS_FORMAT, PS_VARLIST); + for (size_t i = 0; i < chld_out.lines; i++) { + int cols = sscanf(chld_out.line[i], PS_FORMAT, PS_VARLIST); /* Zombie processes do not give a procprog command */ if (cols == (expected_cols - 1) && strstr(procstat, zombie)) { cols = expected_cols; @@ -146,14 +146,14 @@ int main(int argc, char **argv) { strip(procargs); /* Some ps return full pathname for command. This removes path */ - temp_string = strtok((char *)procprog, "/"); + char *temp_string = strtok((char *)procprog, "/"); while (temp_string) { strcpy(procprog, temp_string); temp_string = strtok(NULL, "/"); } /* May get empty procargs */ - if (!strstr(procargs, argv[0]) && strstr(procargs, process_string) && strcmp(procargs, "")) { + if (!strstr(procargs, argv[0]) && strstr(procargs, config.process_string) && strcmp(procargs, "")) { proc_entries++; if (verbose >= 2) { printf(_("Found process: %s %s\n"), procprog, procargs); @@ -178,8 +178,9 @@ int main(int argc, char **argv) { die(STATE_CRITICAL, "NAGIOS %s: %s\n", _("CRITICAL"), _("Cannot parse Nagios log file for valid time")); } + time_t current_time; time(¤t_time); - if ((int)(current_time - latest_entry_time) > (expire_minutes * 60)) { + if ((int)(current_time - latest_entry_time) > (config.expire_minutes * 60)) { result = STATE_WARNING; } else { result = STATE_OK; @@ -192,42 +193,45 @@ int main(int argc, char **argv) { (int)(current_time - latest_entry_time)); printf("\n"); - return result; + exit(result); } /* process command-line arguments */ -int process_arguments(int argc, char **argv) { - int c; - - int option = 0; +check_nagios_config_wrapper process_arguments(int argc, char **argv) { static struct option longopts[] = {{"filename", required_argument, 0, 'F'}, {"expires", required_argument, 0, 'e'}, {"command", required_argument, 0, 'C'}, {"timeout", optional_argument, 0, 't'}, {"version", no_argument, 0, 'V'}, {"help", no_argument, 0, 'h'}, {"verbose", no_argument, 0, 'v'}, {0, 0, 0, 0}}; + check_nagios_config_wrapper result = { + .errorcode = OK, + .config = check_nagios_config_init(), + }; if (argc < 2) { - return ERROR; + result.errorcode = ERROR; + return result; } if (!is_option(argv[1])) { - status_log = argv[1]; + result.config.status_log = argv[1]; if (is_intnonneg(argv[2])) { - expire_minutes = atoi(argv[2]); + result.config.expire_minutes = atoi(argv[2]); } else { die(STATE_UNKNOWN, _("Expiration time must be an integer (seconds)\n")); } - process_string = argv[3]; - return OK; + result.config.process_string = argv[3]; + return result; } - while (1) { - c = getopt_long(argc, argv, "+hVvF:C:e:t:", longopts, &option); + int option = 0; + while (true) { + int option_index = getopt_long(argc, argv, "+hVvF:C:e:t:", longopts, &option); - if (c == -1 || c == EOF || c == 1) { + if (option_index == -1 || option_index == EOF || option_index == 1) { break; } - switch (c) { + switch (option_index) { case 'h': /* help */ print_help(); exit(STATE_UNKNOWN); @@ -235,14 +239,14 @@ int process_arguments(int argc, char **argv) { print_revision(progname, NP_VERSION); exit(STATE_UNKNOWN); case 'F': /* status log */ - status_log = optarg; + result.config.status_log = optarg; break; case 'C': /* command */ - process_string = optarg; + result.config.process_string = optarg; break; case 'e': /* expiry time */ if (is_intnonneg(optarg)) { - expire_minutes = atoi(optarg); + result.config.expire_minutes = atoi(optarg); } else { die(STATE_UNKNOWN, _("Expiration time must be an integer (seconds)\n")); } @@ -262,15 +266,15 @@ int process_arguments(int argc, char **argv) { } } - if (status_log == NULL) { + if (result.config.status_log == NULL) { die(STATE_UNKNOWN, _("You must provide the status_log\n")); } - if (process_string == NULL) { + if (result.config.process_string == NULL) { die(STATE_UNKNOWN, _("You must provide a process string\n")); } - return OK; + return result; } void print_help(void) { diff --git a/plugins/check_nagios.d/config.h b/plugins/check_nagios.d/config.h new file mode 100644 index 00000000..efe139f9 --- /dev/null +++ b/plugins/check_nagios.d/config.h @@ -0,0 +1,19 @@ +#pragma once + +#include "../../config.h" +#include + +typedef struct { + char *status_log; + char *process_string; + int expire_minutes; +} check_nagios_config; + +check_nagios_config check_nagios_config_init() { + check_nagios_config tmp = { + .status_log = NULL, + .process_string = NULL, + .expire_minutes = 0, + }; + return tmp; +} -- cgit v1.2.3-74-g34f1 From 79f9d8b2dcc9a32d60a4a15f9c64e073a52a407e Mon Sep 17 00:00:00 2001 From: Lorenz Kästle <12514511+RincewindsHat@users.noreply.github.com> Date: Tue, 11 Mar 2025 23:36:24 +0100 Subject: check_nt: clang-format --- plugins/check_nt.c | 201 +++++++++++++++++++++++++++++++---------------------- 1 file changed, 118 insertions(+), 83 deletions(-) diff --git a/plugins/check_nt.c b/plugins/check_nt.c index dec0b668..fb9a7b94 100644 --- a/plugins/check_nt.c +++ b/plugins/check_nt.c @@ -122,8 +122,9 @@ int main(int argc, char **argv) { /* Parse extra opts if any */ argv = np_extra_opts(&argc, argv, progname); - if (process_arguments(argc, argv) == ERROR) + if (process_arguments(argc, argv) == ERROR) { usage4(_("Could not parse arguments")); + } /* initialize alarm signal handling */ signal(SIGALRM, socket_timeout_alarm_handler); @@ -148,11 +149,11 @@ int main(int argc, char **argv) { case CHECK_CPULOAD: - if (value_list == NULL) + if (value_list == NULL) { output_message = strdup(_("missing -l parameters")); - else if (!strtoularray(lvalue_list, value_list, ",")) + } else if (!strtoularray(lvalue_list, value_list, ",")) { output_message = strdup(_("wrong -l parameter.")); - else { + } else { /* -l parameters is present with only integers */ return_code = STATE_OK; temp_string = strdup(_("CPU Load")); @@ -170,10 +171,11 @@ int main(int argc, char **argv) { utilization = strtoul(recv_buffer, NULL, 10); /* Check if any of the request is in a warning or critical state */ - if (utilization >= lvalue_list[2 + offset]) + if (utilization >= lvalue_list[2 + offset]) { return_code = STATE_CRITICAL; - else if (utilization >= lvalue_list[1 + offset] && return_code < STATE_WARNING) + } else if (utilization >= lvalue_list[1 + offset] && return_code < STATE_WARNING) { return_code = STATE_WARNING; + } xasprintf(&output_message, _(" %lu%% (%lu min average)"), utilization, lvalue_list[0 + offset]); xasprintf(&temp_string, "%s%s", temp_string, output_message); @@ -186,8 +188,9 @@ int main(int argc, char **argv) { if (strlen(temp_string) > 10) { /* we had at least one loop */ output_message = strdup(temp_string); perfdata = temp_string_perf; - } else + } else { output_message = strdup(_("not enough values for -l parameters")); + } } break; @@ -208,41 +211,45 @@ int main(int argc, char **argv) { uphours = (uptime % 86400) / 3600; upminutes = ((uptime % 86400) % 3600) / 60; - if (!strncmp(value_list, "minutes", strlen("minutes"))) + if (!strncmp(value_list, "minutes", strlen("minutes"))) { uptime = uptime / 60; - else if (!strncmp(value_list, "hours", strlen("hours"))) + } else if (!strncmp(value_list, "hours", strlen("hours"))) { uptime = uptime / 3600; - else if (!strncmp(value_list, "days", strlen("days"))) + } else if (!strncmp(value_list, "days", strlen("days"))) { uptime = uptime / 86400; + } /* else uptime in seconds, nothing to do */ xasprintf(&output_message, _("System Uptime - %u day(s) %u hour(s) %u minute(s) |uptime=%lu"), updays, uphours, upminutes, uptime); - if (check_critical_value && uptime <= critical_value) + if (check_critical_value && uptime <= critical_value) { return_code = STATE_CRITICAL; - else if (check_warning_value && uptime <= warning_value) + } else if (check_warning_value && uptime <= warning_value) { return_code = STATE_WARNING; - else + } else { return_code = STATE_OK; + } } break; case CHECK_USEDDISKSPACE: - if (value_list == NULL) + if (value_list == NULL) { output_message = strdup(_("missing -l parameters")); - else if (strlen(value_list) != 1) + } else if (strlen(value_list) != 1) { output_message = strdup(_("wrong -l argument")); - else { + } else { xasprintf(&send_buffer, "%s&4&%s", req_password, value_list); fetch_data(server_address, server_port, send_buffer); fds = strtok(recv_buffer, "&"); tds = strtok(NULL, "&"); - if (fds != NULL) + if (fds != NULL) { free_disk_space = atof(fds); - if (tds != NULL) + } + if (tds != NULL) { total_disk_space = atof(tds); + } if (total_disk_space > 0 && free_disk_space >= 0) { percent_used_space = ((total_disk_space - free_disk_space) / total_disk_space) * 100; @@ -256,12 +263,13 @@ int main(int argc, char **argv) { (total_disk_space - free_disk_space) / 1073741824, warning_used_space / 1073741824, critical_used_space / 1073741824, total_disk_space / 1073741824); - if (check_critical_value && percent_used_space >= critical_value) + if (check_critical_value && percent_used_space >= critical_value) { return_code = STATE_CRITICAL; - else if (check_warning_value && percent_used_space >= warning_value) + } else if (check_warning_value && percent_used_space >= warning_value) { return_code = STATE_WARNING; - else + } else { return_code = STATE_OK; + } output_message = strdup(temp_string); perfdata = temp_string_perf; @@ -275,16 +283,17 @@ int main(int argc, char **argv) { case CHECK_SERVICESTATE: case CHECK_PROCSTATE: - if (value_list == NULL) + if (value_list == NULL) { output_message = strdup(_("No service/process specified")); - else { + } else { preparelist(value_list); /* replace , between services with & to send the request */ xasprintf(&send_buffer, "%s&%u&%s&%s", req_password, (vars_to_check == CHECK_SERVICESTATE) ? 5 : 6, (show_all) ? "ShowAll" : "ShowFail", value_list); fetch_data(server_address, server_port, send_buffer); numstr = strtok(recv_buffer, "&"); - if (numstr == NULL) + if (numstr == NULL) { die(STATE_UNKNOWN, _("could not fetch information from server\n")); + } return_code = atoi(numstr); temp_string = strtok(NULL, "&"); output_message = strdup(temp_string); @@ -296,12 +305,14 @@ int main(int argc, char **argv) { xasprintf(&send_buffer, "%s&7", req_password); fetch_data(server_address, server_port, send_buffer); numstr = strtok(recv_buffer, "&"); - if (numstr == NULL) + if (numstr == NULL) { die(STATE_UNKNOWN, _("could not fetch information from server\n")); + } mem_commitLimit = atof(numstr); numstr = strtok(NULL, "&"); - if (numstr == NULL) + if (numstr == NULL) { die(STATE_UNKNOWN, _("could not fetch information from server\n")); + } mem_commitByte = atof(numstr); percent_used_space = (mem_commitByte / mem_commitLimit) * 100; warning_used_space = ((float)warning_value / 100) * mem_commitLimit; @@ -316,10 +327,11 @@ int main(int argc, char **argv) { critical_used_space / 1048567, mem_commitLimit / 1048567); return_code = STATE_OK; - if (check_critical_value && percent_used_space >= critical_value) + if (check_critical_value && percent_used_space >= critical_value) { return_code = STATE_CRITICAL; - else if (check_warning_value && percent_used_space >= warning_value) + } else if (check_warning_value && percent_used_space >= warning_value) { return_code = STATE_WARNING; + } break; @@ -346,9 +358,9 @@ int main(int argc, char **argv) { strange things will happen when you make graphs of your data. */ - if (value_list == NULL) + if (value_list == NULL) { output_message = strdup(_("No counter specified")); - else { + } else { preparelist(value_list); /* replace , between services with & to send the request */ isPercent = (strchr(value_list, '%') != NULL); @@ -359,9 +371,9 @@ int main(int argc, char **argv) { fetch_data(server_address, server_port, send_buffer); counter_value = atof(recv_buffer); - if (description == NULL) + if (description == NULL) { xasprintf(&output_message, "%.f", counter_value); - else if (isPercent) { + } else if (isPercent) { counter_unit = strdup("%"); allRight = true; } @@ -375,16 +387,18 @@ int main(int argc, char **argv) { fminval = (minval != NULL) ? strtod(minval, &errcvt) : -1; fmaxval = (minval != NULL) ? strtod(maxval, &errcvt) : -1; - if ((fminval == 0) && (minval == errcvt)) + if ((fminval == 0) && (minval == errcvt)) { output_message = strdup(_("Minimum value contains non-numbers")); - else { - if ((fmaxval == 0) && (maxval == errcvt)) + } else { + if ((fmaxval == 0) && (maxval == errcvt)) { output_message = strdup(_("Maximum value contains non-numbers")); - else + } else { allRight = true; /* Everything is OK. */ + } } - } else if ((counter_unit == NULL) && (description != NULL)) + } else if ((counter_unit == NULL) && (description != NULL)) { output_message = strdup(_("No unit counter specified")); + } if (allRight) { /* Let's format the output string, finally... */ @@ -402,26 +416,28 @@ int main(int argc, char **argv) { } if (critical_value > warning_value) { /* Normal thresholds */ - if (check_critical_value && counter_value >= critical_value) + if (check_critical_value && counter_value >= critical_value) { return_code = STATE_CRITICAL; - else if (check_warning_value && counter_value >= warning_value) + } else if (check_warning_value && counter_value >= warning_value) { return_code = STATE_WARNING; - else + } else { return_code = STATE_OK; + } } else { /* inverse thresholds */ return_code = STATE_OK; - if (check_critical_value && counter_value <= critical_value) + if (check_critical_value && counter_value <= critical_value) { return_code = STATE_CRITICAL; - else if (check_warning_value && counter_value <= warning_value) + } else if (check_warning_value && counter_value <= warning_value) { return_code = STATE_WARNING; + } } break; case CHECK_FILEAGE: - if (value_list == NULL) + if (value_list == NULL) { output_message = strdup(_("No counter specified")); - else { + } else { preparelist(value_list); /* replace , between services with & to send the request */ xasprintf(&send_buffer, "%s&9&%s", req_password, value_list); fetch_data(server_address, server_port, send_buffer); @@ -430,27 +446,29 @@ int main(int argc, char **argv) { output_message = strdup(description); if (critical_value > warning_value) { /* Normal thresholds */ - if (check_critical_value && age_in_minutes >= critical_value) + if (check_critical_value && age_in_minutes >= critical_value) { return_code = STATE_CRITICAL; - else if (check_warning_value && age_in_minutes >= warning_value) + } else if (check_warning_value && age_in_minutes >= warning_value) { return_code = STATE_WARNING; - else + } else { return_code = STATE_OK; + } } else { /* inverse thresholds */ - if (check_critical_value && age_in_minutes <= critical_value) + if (check_critical_value && age_in_minutes <= critical_value) { return_code = STATE_CRITICAL; - else if (check_warning_value && age_in_minutes <= warning_value) + } else if (check_warning_value && age_in_minutes <= warning_value) { return_code = STATE_WARNING; - else + } else { return_code = STATE_OK; + } } } break; case CHECK_INSTANCES: - if (value_list == NULL) + if (value_list == NULL) { output_message = strdup(_("No counter specified")); - else { + } else { xasprintf(&send_buffer, "%s&10&%s", req_password, value_list); fetch_data(server_address, server_port, send_buffer); if (!strncmp(recv_buffer, "ERROR", 5)) { @@ -471,10 +489,11 @@ int main(int argc, char **argv) { /* reset timeout */ alarm(0); - if (perfdata == NULL) + if (perfdata == NULL) { printf("%s\n", output_message); - else + } else { printf("%s | %s\n", output_message, perfdata); + } return return_code; } @@ -498,8 +517,9 @@ int process_arguments(int argc, char **argv) { {0, 0, 0, 0}}; /* no options were supplied */ - if (argc < 2) + if (argc < 2) { return ERROR; + } /* backwards compatibility */ if (!is_option(argv[1])) { @@ -510,19 +530,21 @@ int process_arguments(int argc, char **argv) { } for (c = 1; c < argc; c++) { - if (strcmp("-to", argv[c]) == 0) + if (strcmp("-to", argv[c]) == 0) { strcpy(argv[c], "-t"); - else if (strcmp("-wv", argv[c]) == 0) + } else if (strcmp("-wv", argv[c]) == 0) { strcpy(argv[c], "-w"); - else if (strcmp("-cv", argv[c]) == 0) + } else if (strcmp("-cv", argv[c]) == 0) { strcpy(argv[c], "-c"); + } } while (1) { c = getopt_long(argc, argv, "+hVH:t:c:w:p:v:l:s:d:u", longopts, &option); - if (c == -1 || c == EOF || c == 1) + if (c == -1 || c == EOF || c == 1) { break; + } switch (c) { case '?': /* print short usage statement if args not parsable */ @@ -540,36 +562,39 @@ int process_arguments(int argc, char **argv) { req_password = optarg; break; case 'p': /* port */ - if (is_intnonneg(optarg)) + if (is_intnonneg(optarg)) { server_port = atoi(optarg); - else + } else { die(STATE_UNKNOWN, _("Server port must be an integer\n")); + } break; case 'v': - if (strlen(optarg) < 4) + if (strlen(optarg) < 4) { return ERROR; - if (!strcmp(optarg, "CLIENTVERSION")) + } + if (!strcmp(optarg, "CLIENTVERSION")) { vars_to_check = CHECK_CLIENTVERSION; - else if (!strcmp(optarg, "CPULOAD")) + } else if (!strcmp(optarg, "CPULOAD")) { vars_to_check = CHECK_CPULOAD; - else if (!strcmp(optarg, "UPTIME")) + } else if (!strcmp(optarg, "UPTIME")) { vars_to_check = CHECK_UPTIME; - else if (!strcmp(optarg, "USEDDISKSPACE")) + } else if (!strcmp(optarg, "USEDDISKSPACE")) { vars_to_check = CHECK_USEDDISKSPACE; - else if (!strcmp(optarg, "SERVICESTATE")) + } else if (!strcmp(optarg, "SERVICESTATE")) { vars_to_check = CHECK_SERVICESTATE; - else if (!strcmp(optarg, "PROCSTATE")) + } else if (!strcmp(optarg, "PROCSTATE")) { vars_to_check = CHECK_PROCSTATE; - else if (!strcmp(optarg, "MEMUSE")) + } else if (!strcmp(optarg, "MEMUSE")) { vars_to_check = CHECK_MEMUSE; - else if (!strcmp(optarg, "COUNTER")) + } else if (!strcmp(optarg, "COUNTER")) { vars_to_check = CHECK_COUNTER; - else if (!strcmp(optarg, "FILEAGE")) + } else if (!strcmp(optarg, "FILEAGE")) { vars_to_check = CHECK_FILEAGE; - else if (!strcmp(optarg, "INSTANCES")) + } else if (!strcmp(optarg, "INSTANCES")) { vars_to_check = CHECK_INSTANCES; - else + } else { return ERROR; + } break; case 'l': /* value list */ value_list = optarg; @@ -583,26 +608,31 @@ int process_arguments(int argc, char **argv) { check_critical_value = true; break; case 'd': /* Display select for services */ - if (!strcmp(optarg, "SHOWALL")) + if (!strcmp(optarg, "SHOWALL")) { show_all = true; + } break; case 'u': socket_timeout_state = STATE_UNKNOWN; break; case 't': /* timeout */ socket_timeout = atoi(optarg); - if (socket_timeout <= 0) + if (socket_timeout <= 0) { return ERROR; + } } } - if (server_address == NULL) + if (server_address == NULL) { usage4(_("You must provide a server address or host name")); + } - if (vars_to_check == CHECK_NONE) + if (vars_to_check == CHECK_NONE) { return ERROR; + } - if (req_password == NULL) + if (req_password == NULL) { req_password = strdup(_("None")); + } return OK; } @@ -612,11 +642,13 @@ void fetch_data(const char *address, int port, const char *sendb) { result = process_tcp_request(address, port, sendb, recv_buffer, sizeof(recv_buffer)); - if (result != STATE_OK) + if (result != STATE_OK) { die(result, _("could not fetch information from server\n")); + } - if (!strncmp(recv_buffer, "ERROR", 5)) + if (!strncmp(recv_buffer, "ERROR", 5)) { die(STATE_UNKNOWN, "NSClient - %s\n", recv_buffer); + } } bool strtoularray(unsigned long *array, char *string, const char *delim) { @@ -624,16 +656,18 @@ bool strtoularray(unsigned long *array, char *string, const char *delim) { int idx = 0; char *t1; - for (idx = 0; idx < MAX_VALUE_LIST; idx++) + for (idx = 0; idx < MAX_VALUE_LIST; idx++) { array[idx] = 0; + } idx = 0; for (t1 = strtok(string, delim); t1 != NULL; t1 = strtok(NULL, delim)) { if (is_numeric(t1) && idx < MAX_VALUE_LIST) { array[idx] = strtoul(t1, NULL, 10); idx++; - } else + } else { return false; + } } return true; } @@ -642,10 +676,11 @@ void preparelist(char *string) { /* Replace all , with & which is the delimiter for the request */ int i; - for (i = 0; (size_t)i < strlen(string); i++) + for (i = 0; (size_t)i < strlen(string); i++) { if (string[i] == ',') { string[i] = '&'; } + } } void print_help(void) { -- cgit v1.2.3-74-g34f1 From df871f924d213360fd6ee902584abbd31373e8ad Mon Sep 17 00:00:00 2001 From: Lorenz Kästle <12514511+RincewindsHat@users.noreply.github.com> Date: Tue, 11 Mar 2025 23:39:47 +0100 Subject: Update nsclient link --- plugins/check_nt.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/check_nt.c b/plugins/check_nt.c index fb9a7b94..4b9f8c48 100644 --- a/plugins/check_nt.c +++ b/plugins/check_nt.c @@ -13,7 +13,7 @@ * This plugin collects data from the NSClient service running on a * Windows NT/2000/XP/2003 server. * This plugin requires NSClient software to run on NT - * (http://nsclient.ready2run.nl/) + * (https://nsclient.org/) * * * This program is free software: you can redistribute it and/or modify -- cgit v1.2.3-74-g34f1 From deac7f99ef409cf1299ab8da25a930db200e1dba Mon Sep 17 00:00:00 2001 From: Lorenz Kästle <12514511+RincewindsHat@users.noreply.github.com> Date: Wed, 12 Mar 2025 00:01:50 +0100 Subject: check_nt: general refactoring --- plugins/check_nt.c | 148 +++++++++++++++++++---------------------------------- 1 file changed, 54 insertions(+), 94 deletions(-) diff --git a/plugins/check_nt.c b/plugins/check_nt.c index 4b9f8c48..7897558b 100644 --- a/plugins/check_nt.c +++ b/plugins/check_nt.c @@ -81,40 +81,6 @@ static void print_help(void); void print_usage(void); int main(int argc, char **argv) { - - /* should be int result = STATE_UNKNOWN; */ - - int return_code = STATE_UNKNOWN; - char *send_buffer = NULL; - char *output_message = NULL; - char *perfdata = NULL; - char *temp_string = NULL; - char *temp_string_perf = NULL; - char *description = NULL, *counter_unit = NULL; - char *minval = NULL, *maxval = NULL, *errcvt = NULL; - char *fds = NULL, *tds = NULL; - char *numstr; - - double total_disk_space = 0; - double free_disk_space = 0; - double percent_used_space = 0; - double warning_used_space = 0; - double critical_used_space = 0; - double mem_commitLimit = 0; - double mem_commitByte = 0; - double fminval = 0, fmaxval = 0; - unsigned long utilization; - unsigned long uptime; - unsigned long age_in_minutes; - double counter_value = 0.0; - int offset = 0; - int updays = 0; - int uphours = 0; - int upminutes = 0; - - bool isPercent = false; - bool allRight = false; - setlocale(LC_ALL, ""); bindtextdomain(PACKAGE, LOCALEDIR); textdomain(PACKAGE); @@ -132,10 +98,17 @@ int main(int argc, char **argv) { /* set socket timeout */ alarm(socket_timeout); + int return_code = STATE_UNKNOWN; + char *send_buffer = NULL; + char *output_message = NULL; + char *perfdata = NULL; + char *temp_string = NULL; + char *temp_string_perf = NULL; + char *description = NULL; + char *counter_unit = NULL; + char *errcvt = NULL; switch (vars_to_check) { - case CHECK_CLIENTVERSION: - xasprintf(&send_buffer, "%s&1", req_password); fetch_data(server_address, server_port, send_buffer); if (value_list != NULL && strcmp(recv_buffer, value_list) != 0) { @@ -146,9 +119,7 @@ int main(int argc, char **argv) { return_code = STATE_OK; } break; - case CHECK_CPULOAD: - if (value_list == NULL) { output_message = strdup(_("missing -l parameters")); } else if (!strtoularray(lvalue_list, value_list, ",")) { @@ -160,6 +131,7 @@ int main(int argc, char **argv) { temp_string_perf = strdup(" "); /* loop until one of the parameters is wrong or not present */ + int offset = 0; while (lvalue_list[0 + offset] > (unsigned long)0 && lvalue_list[0 + offset] <= (unsigned long)17280 && lvalue_list[1 + offset] > (unsigned long)0 && lvalue_list[1 + offset] <= (unsigned long)100 && lvalue_list[2 + offset] > (unsigned long)0 && lvalue_list[2 + offset] <= (unsigned long)100) { @@ -168,7 +140,7 @@ int main(int argc, char **argv) { xasprintf(&send_buffer, "%s&2&%lu", req_password, lvalue_list[0 + offset]); fetch_data(server_address, server_port, send_buffer); - utilization = strtoul(recv_buffer, NULL, 10); + unsigned long utilization = strtoul(recv_buffer, NULL, 10); /* Check if any of the request is in a warning or critical state */ if (utilization >= lvalue_list[2 + offset]) { @@ -193,9 +165,7 @@ int main(int argc, char **argv) { } } break; - case CHECK_UPTIME: - if (value_list == NULL) { value_list = "minutes"; } @@ -206,10 +176,10 @@ int main(int argc, char **argv) { } else { xasprintf(&send_buffer, "%s&3", req_password); fetch_data(server_address, server_port, send_buffer); - uptime = strtoul(recv_buffer, NULL, 10); - updays = uptime / 86400; - uphours = (uptime % 86400) / 3600; - upminutes = ((uptime % 86400) % 3600) / 60; + unsigned long uptime = strtoul(recv_buffer, NULL, 10); + int updays = uptime / 86400; + int uphours = (uptime % 86400) / 3600; + int upminutes = ((uptime % 86400) % 3600) / 60; if (!strncmp(value_list, "minutes", strlen("minutes"))) { uptime = uptime / 60; @@ -232,9 +202,7 @@ int main(int argc, char **argv) { } } break; - case CHECK_USEDDISKSPACE: - if (value_list == NULL) { output_message = strdup(_("missing -l parameters")); } else if (strlen(value_list) != 1) { @@ -242,8 +210,10 @@ int main(int argc, char **argv) { } else { xasprintf(&send_buffer, "%s&4&%s", req_password, value_list); fetch_data(server_address, server_port, send_buffer); - fds = strtok(recv_buffer, "&"); - tds = strtok(NULL, "&"); + char *fds = strtok(recv_buffer, "&"); + char *tds = strtok(NULL, "&"); + double total_disk_space = 0; + double free_disk_space = 0; if (fds != NULL) { free_disk_space = atof(fds); } @@ -252,9 +222,9 @@ int main(int argc, char **argv) { } if (total_disk_space > 0 && free_disk_space >= 0) { - percent_used_space = ((total_disk_space - free_disk_space) / total_disk_space) * 100; - warning_used_space = ((float)warning_value / 100) * total_disk_space; - critical_used_space = ((float)critical_value / 100) * total_disk_space; + double percent_used_space = ((total_disk_space - free_disk_space) / total_disk_space) * 100; + double warning_used_space = ((float)warning_value / 100) * total_disk_space; + double critical_used_space = ((float)critical_value / 100) * total_disk_space; xasprintf(&temp_string, _("%s:\\ - total: %.2f Gb - used: %.2f Gb (%.0f%%) - free %.2f Gb (%.0f%%)"), value_list, total_disk_space / 1073741824, (total_disk_space - free_disk_space) / 1073741824, percent_used_space, @@ -279,10 +249,8 @@ int main(int argc, char **argv) { } } break; - case CHECK_SERVICESTATE: case CHECK_PROCSTATE: - if (value_list == NULL) { output_message = strdup(_("No service/process specified")); } else { @@ -290,7 +258,7 @@ int main(int argc, char **argv) { xasprintf(&send_buffer, "%s&%u&%s&%s", req_password, (vars_to_check == CHECK_SERVICESTATE) ? 5 : 6, (show_all) ? "ShowAll" : "ShowFail", value_list); fetch_data(server_address, server_port, send_buffer); - numstr = strtok(recv_buffer, "&"); + char *numstr = strtok(recv_buffer, "&"); if (numstr == NULL) { die(STATE_UNKNOWN, _("could not fetch information from server\n")); } @@ -299,24 +267,22 @@ int main(int argc, char **argv) { output_message = strdup(temp_string); } break; - case CHECK_MEMUSE: - xasprintf(&send_buffer, "%s&7", req_password); fetch_data(server_address, server_port, send_buffer); - numstr = strtok(recv_buffer, "&"); + char *numstr = strtok(recv_buffer, "&"); if (numstr == NULL) { die(STATE_UNKNOWN, _("could not fetch information from server\n")); } - mem_commitLimit = atof(numstr); + double mem_commitLimit = atof(numstr); numstr = strtok(NULL, "&"); if (numstr == NULL) { die(STATE_UNKNOWN, _("could not fetch information from server\n")); } - mem_commitByte = atof(numstr); - percent_used_space = (mem_commitByte / mem_commitLimit) * 100; - warning_used_space = ((float)warning_value / 100) * mem_commitLimit; - critical_used_space = ((float)critical_value / 100) * mem_commitLimit; + double mem_commitByte = atof(numstr); + double percent_used_space = (mem_commitByte / mem_commitLimit) * 100; + double warning_used_space = ((float)warning_value / 100) * mem_commitLimit; + double critical_used_space = ((float)critical_value / 100) * mem_commitLimit; /* Divisor should be 1048567, not 3044515, as we are measuring "Commit Charge" here, which equals RAM + Pagefiles. */ @@ -334,9 +300,7 @@ int main(int argc, char **argv) { } break; - case CHECK_COUNTER: - /* CHECK_COUNTER has been modified to provide extensive perfdata information. In order to do this, some modifications have been done to the code @@ -358,11 +322,12 @@ int main(int argc, char **argv) { strange things will happen when you make graphs of your data. */ + double counter_value = 0.0; if (value_list == NULL) { output_message = strdup(_("No counter specified")); } else { preparelist(value_list); /* replace , between services with & to send the request */ - isPercent = (strchr(value_list, '%') != NULL); + bool isPercent = (strchr(value_list, '%') != NULL); strtok(value_list, "&"); /* burn the first parameters */ description = strtok(NULL, "&"); @@ -371,6 +336,7 @@ int main(int argc, char **argv) { fetch_data(server_address, server_port, send_buffer); counter_value = atof(recv_buffer); + bool allRight = false; if (description == NULL) { xasprintf(&output_message, "%.f", counter_value); } else if (isPercent) { @@ -378,6 +344,10 @@ int main(int argc, char **argv) { allRight = true; } + char *minval = NULL; + char *maxval = NULL; + double fminval = 0; + double fmaxval = 0; if ((counter_unit != NULL) && (!allRight)) { minval = strtok(NULL, "&"); maxval = strtok(NULL, "&"); @@ -434,14 +404,13 @@ int main(int argc, char **argv) { break; case CHECK_FILEAGE: - if (value_list == NULL) { output_message = strdup(_("No counter specified")); } else { preparelist(value_list); /* replace , between services with & to send the request */ xasprintf(&send_buffer, "%s&9&%s", req_password, value_list); fetch_data(server_address, server_port, send_buffer); - age_in_minutes = atoi(strtok(recv_buffer, "&")); + unsigned long age_in_minutes = atoi(strtok(recv_buffer, "&")); description = strtok(NULL, "&"); output_message = strdup(description); @@ -499,9 +468,6 @@ int main(int argc, char **argv) { /* process command-line arguments */ int process_arguments(int argc, char **argv) { - int c; - - int option = 0; static struct option longopts[] = {{"port", required_argument, 0, 'p'}, {"timeout", required_argument, 0, 't'}, {"critical", required_argument, 0, 'c'}, @@ -529,24 +495,25 @@ int process_arguments(int argc, char **argv) { argc--; } - for (c = 1; c < argc; c++) { - if (strcmp("-to", argv[c]) == 0) { - strcpy(argv[c], "-t"); - } else if (strcmp("-wv", argv[c]) == 0) { - strcpy(argv[c], "-w"); - } else if (strcmp("-cv", argv[c]) == 0) { - strcpy(argv[c], "-c"); + for (int index = 1; index < argc; index++) { + if (strcmp("-to", argv[index]) == 0) { + strcpy(argv[index], "-t"); + } else if (strcmp("-wv", argv[index]) == 0) { + strcpy(argv[index], "-w"); + } else if (strcmp("-cv", argv[index]) == 0) { + strcpy(argv[index], "-c"); } } - while (1) { - c = getopt_long(argc, argv, "+hVH:t:c:w:p:v:l:s:d:u", longopts, &option); + int option = 0; + while (true) { + int option_index = getopt_long(argc, argv, "+hVH:t:c:w:p:v:l:s:d:u", longopts, &option); - if (c == -1 || c == EOF || c == 1) { + if (option_index == -1 || option_index == EOF || option_index == 1) { break; } - switch (c) { + switch (option_index) { case '?': /* print short usage statement if args not parsable */ usage5(); case 'h': /* help */ @@ -638,9 +605,7 @@ int process_arguments(int argc, char **argv) { } void fetch_data(const char *address, int port, const char *sendb) { - int result; - - result = process_tcp_request(address, port, sendb, recv_buffer, sizeof(recv_buffer)); + int result = process_tcp_request(address, port, sendb, recv_buffer, sizeof(recv_buffer)); if (result != STATE_OK) { die(result, _("could not fetch information from server\n")); @@ -653,15 +618,12 @@ void fetch_data(const char *address, int port, const char *sendb) { bool strtoularray(unsigned long *array, char *string, const char *delim) { /* split a delimited string into a long array */ - int idx = 0; - char *t1; - - for (idx = 0; idx < MAX_VALUE_LIST; idx++) { + for (int idx = 0; idx < MAX_VALUE_LIST; idx++) { array[idx] = 0; } - idx = 0; - for (t1 = strtok(string, delim); t1 != NULL; t1 = strtok(NULL, delim)) { + int idx = 0; + for (char *t1 = strtok(string, delim); t1 != NULL; t1 = strtok(NULL, delim)) { if (is_numeric(t1) && idx < MAX_VALUE_LIST) { array[idx] = strtoul(t1, NULL, 10); idx++; @@ -674,9 +636,7 @@ bool strtoularray(unsigned long *array, char *string, const char *delim) { void preparelist(char *string) { /* Replace all , with & which is the delimiter for the request */ - int i; - - for (i = 0; (size_t)i < strlen(string); i++) { + for (int i = 0; (size_t)i < strlen(string); i++) { if (string[i] == ',') { string[i] = '&'; } -- cgit v1.2.3-74-g34f1 From 47b484eb454b0a487f7d32406ee93f85c94f5895 Mon Sep 17 00:00:00 2001 From: Lorenz Kästle <12514511+RincewindsHat@users.noreply.github.com> Date: Wed, 12 Mar 2025 00:36:53 +0100 Subject: Refactor check_nt --- plugins/Makefile.am | 1 + plugins/check_nt.c | 254 +++++++++++++++++++++----------------------- plugins/check_nt.d/config.h | 53 +++++++++ 3 files changed, 178 insertions(+), 130 deletions(-) create mode 100644 plugins/check_nt.d/config.h diff --git a/plugins/Makefile.am b/plugins/Makefile.am index 5d4449bf..097763fc 100644 --- a/plugins/Makefile.am +++ b/plugins/Makefile.am @@ -56,6 +56,7 @@ EXTRA_DIST = t \ check_nagios.d \ check_dbi.d \ check_ssh.d \ + check_nt.d \ check_dns.d \ check_mrtgtraf.d \ check_mysql_query.d \ diff --git a/plugins/check_nt.c b/plugins/check_nt.c index 7897558b..7dd23e5c 100644 --- a/plugins/check_nt.c +++ b/plugins/check_nt.c @@ -39,42 +39,22 @@ const char *email = "devel@monitoring-plugins.org"; #include "common.h" #include "netutils.h" #include "utils.h" - -enum checkvars { - CHECK_NONE, - CHECK_CLIENTVERSION, - CHECK_CPULOAD, - CHECK_UPTIME, - CHECK_USEDDISKSPACE, - CHECK_SERVICESTATE, - CHECK_PROCSTATE, - CHECK_MEMUSE, - CHECK_COUNTER, - CHECK_FILEAGE, - CHECK_INSTANCES -}; +#include "check_nt.d/config.h" enum { MAX_VALUE_LIST = 30, - PORT = 1248 }; -static char *server_address = NULL; -static int server_port = PORT; -static char *value_list = NULL; -static char *req_password = NULL; -static unsigned long lvalue_list[MAX_VALUE_LIST]; -static unsigned long warning_value = 0L; -static unsigned long critical_value = 0L; -static bool check_warning_value = false; -static bool check_critical_value = false; -static enum checkvars vars_to_check = CHECK_NONE; -static bool show_all = false; - static char recv_buffer[MAX_INPUT_BUFFER]; static void fetch_data(const char *address, int port, const char *sendb); -static int process_arguments(int /*argc*/, char ** /*argv*/); + +typedef struct { + int errorcode; + check_nt_config config; +} check_nt_config_wrapper; +static check_nt_config_wrapper process_arguments(int /*argc*/, char ** /*argv*/); + static void preparelist(char *string); static bool strtoularray(unsigned long *array, char *string, const char *delim); static void print_help(void); @@ -88,10 +68,13 @@ 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_nt_config_wrapper tmp_config = process_arguments(argc, argv); + if (tmp_config.errorcode == ERROR) { usage4(_("Could not parse arguments")); } + const check_nt_config config = tmp_config.config; + /* initialize alarm signal handling */ signal(SIGALRM, socket_timeout_alarm_handler); @@ -107,12 +90,13 @@ int main(int argc, char **argv) { char *description = NULL; char *counter_unit = NULL; char *errcvt = NULL; - switch (vars_to_check) { + unsigned long lvalue_list[MAX_VALUE_LIST]; + switch (config.vars_to_check) { case CHECK_CLIENTVERSION: - xasprintf(&send_buffer, "%s&1", req_password); - fetch_data(server_address, server_port, send_buffer); - if (value_list != NULL && strcmp(recv_buffer, value_list) != 0) { - xasprintf(&output_message, _("Wrong client version - running: %s, required: %s"), recv_buffer, value_list); + xasprintf(&send_buffer, "%s&1", config.req_password); + fetch_data(config.server_address, config.server_port, send_buffer); + if (config.value_list != NULL && strcmp(recv_buffer, config.value_list) != 0) { + xasprintf(&output_message, _("Wrong client version - running: %s, required: %s"), recv_buffer, config.value_list); return_code = STATE_WARNING; } else { xasprintf(&output_message, "%s", recv_buffer); @@ -120,9 +104,9 @@ int main(int argc, char **argv) { } break; case CHECK_CPULOAD: - if (value_list == NULL) { + if (config.value_list == NULL) { output_message = strdup(_("missing -l parameters")); - } else if (!strtoularray(lvalue_list, value_list, ",")) { + } else if (!strtoularray(lvalue_list, config.value_list, ",")) { output_message = strdup(_("wrong -l parameter.")); } else { /* -l parameters is present with only integers */ @@ -137,8 +121,8 @@ int main(int argc, char **argv) { lvalue_list[2 + offset] > (unsigned long)0 && lvalue_list[2 + offset] <= (unsigned long)100) { /* Send request and retrieve data */ - xasprintf(&send_buffer, "%s&2&%lu", req_password, lvalue_list[0 + offset]); - fetch_data(server_address, server_port, send_buffer); + xasprintf(&send_buffer, "%s&2&%lu", config.req_password, lvalue_list[0 + offset]); + fetch_data(config.server_address, config.server_port, send_buffer); unsigned long utilization = strtoul(recv_buffer, NULL, 10); @@ -165,27 +149,28 @@ int main(int argc, char **argv) { } } break; - case CHECK_UPTIME: - if (value_list == NULL) { - value_list = "minutes"; + case CHECK_UPTIME: { + char *tmp_value_list = config.value_list; + if (config.value_list == NULL) { + tmp_value_list = "minutes"; } - if (strncmp(value_list, "seconds", strlen("seconds") + 1) && strncmp(value_list, "minutes", strlen("minutes") + 1) && - strncmp(value_list, "hours", strlen("hours") + 1) && strncmp(value_list, "days", strlen("days") + 1)) { + if (strncmp(tmp_value_list, "seconds", strlen("seconds") + 1) && strncmp(tmp_value_list, "minutes", strlen("minutes") + 1) && + strncmp(config.value_list, "hours", strlen("hours") + 1) && strncmp(tmp_value_list, "days", strlen("days") + 1)) { output_message = strdup(_("wrong -l argument")); } else { - xasprintf(&send_buffer, "%s&3", req_password); - fetch_data(server_address, server_port, send_buffer); + xasprintf(&send_buffer, "%s&3", config.req_password); + fetch_data(config.server_address, config.server_port, send_buffer); unsigned long uptime = strtoul(recv_buffer, NULL, 10); int updays = uptime / 86400; int uphours = (uptime % 86400) / 3600; int upminutes = ((uptime % 86400) % 3600) / 60; - if (!strncmp(value_list, "minutes", strlen("minutes"))) { + if (!strncmp(tmp_value_list, "minutes", strlen("minutes"))) { uptime = uptime / 60; - } else if (!strncmp(value_list, "hours", strlen("hours"))) { + } else if (!strncmp(tmp_value_list, "hours", strlen("hours"))) { uptime = uptime / 3600; - } else if (!strncmp(value_list, "days", strlen("days"))) { + } else if (!strncmp(tmp_value_list, "days", strlen("days"))) { uptime = uptime / 86400; } /* else uptime in seconds, nothing to do */ @@ -193,23 +178,23 @@ int main(int argc, char **argv) { xasprintf(&output_message, _("System Uptime - %u day(s) %u hour(s) %u minute(s) |uptime=%lu"), updays, uphours, upminutes, uptime); - if (check_critical_value && uptime <= critical_value) { + if (config.check_critical_value && uptime <= config.critical_value) { return_code = STATE_CRITICAL; - } else if (check_warning_value && uptime <= warning_value) { + } else if (config.check_warning_value && uptime <= config.warning_value) { return_code = STATE_WARNING; } else { return_code = STATE_OK; } } - break; + } break; case CHECK_USEDDISKSPACE: - if (value_list == NULL) { + if (config.value_list == NULL) { output_message = strdup(_("missing -l parameters")); - } else if (strlen(value_list) != 1) { + } else if (strlen(config.value_list) != 1) { output_message = strdup(_("wrong -l argument")); } else { - xasprintf(&send_buffer, "%s&4&%s", req_password, value_list); - fetch_data(server_address, server_port, send_buffer); + xasprintf(&send_buffer, "%s&4&%s", config.req_password, config.value_list); + fetch_data(config.server_address, config.server_port, send_buffer); char *fds = strtok(recv_buffer, "&"); char *tds = strtok(NULL, "&"); double total_disk_space = 0; @@ -223,19 +208,19 @@ int main(int argc, char **argv) { if (total_disk_space > 0 && free_disk_space >= 0) { double percent_used_space = ((total_disk_space - free_disk_space) / total_disk_space) * 100; - double warning_used_space = ((float)warning_value / 100) * total_disk_space; - double critical_used_space = ((float)critical_value / 100) * total_disk_space; + double warning_used_space = ((float)config.warning_value / 100) * total_disk_space; + double critical_used_space = ((float)config.critical_value / 100) * total_disk_space; - xasprintf(&temp_string, _("%s:\\ - total: %.2f Gb - used: %.2f Gb (%.0f%%) - free %.2f Gb (%.0f%%)"), value_list, + xasprintf(&temp_string, _("%s:\\ - total: %.2f Gb - used: %.2f Gb (%.0f%%) - free %.2f Gb (%.0f%%)"), config.value_list, total_disk_space / 1073741824, (total_disk_space - free_disk_space) / 1073741824, percent_used_space, free_disk_space / 1073741824, (free_disk_space / total_disk_space) * 100); - xasprintf(&temp_string_perf, _("'%s:\\ Used Space'=%.2fGb;%.2f;%.2f;0.00;%.2f"), value_list, + xasprintf(&temp_string_perf, _("'%s:\\ Used Space'=%.2fGb;%.2f;%.2f;0.00;%.2f"), config.value_list, (total_disk_space - free_disk_space) / 1073741824, warning_used_space / 1073741824, critical_used_space / 1073741824, total_disk_space / 1073741824); - if (check_critical_value && percent_used_space >= critical_value) { + if (config.check_critical_value && percent_used_space >= config.critical_value) { return_code = STATE_CRITICAL; - } else if (check_warning_value && percent_used_space >= warning_value) { + } else if (config.check_warning_value && percent_used_space >= config.warning_value) { return_code = STATE_WARNING; } else { return_code = STATE_OK; @@ -251,13 +236,13 @@ int main(int argc, char **argv) { break; case CHECK_SERVICESTATE: case CHECK_PROCSTATE: - if (value_list == NULL) { + if (config.value_list == NULL) { output_message = strdup(_("No service/process specified")); } else { - preparelist(value_list); /* replace , between services with & to send the request */ - xasprintf(&send_buffer, "%s&%u&%s&%s", req_password, (vars_to_check == CHECK_SERVICESTATE) ? 5 : 6, - (show_all) ? "ShowAll" : "ShowFail", value_list); - fetch_data(server_address, server_port, send_buffer); + preparelist(config.value_list); /* replace , between services with & to send the request */ + xasprintf(&send_buffer, "%s&%u&%s&%s", config.req_password, (config.vars_to_check == CHECK_SERVICESTATE) ? 5 : 6, + (config.show_all) ? "ShowAll" : "ShowFail", config.value_list); + fetch_data(config.server_address, config.server_port, send_buffer); char *numstr = strtok(recv_buffer, "&"); if (numstr == NULL) { die(STATE_UNKNOWN, _("could not fetch information from server\n")); @@ -268,8 +253,8 @@ int main(int argc, char **argv) { } break; case CHECK_MEMUSE: - xasprintf(&send_buffer, "%s&7", req_password); - fetch_data(server_address, server_port, send_buffer); + xasprintf(&send_buffer, "%s&7", config.req_password); + fetch_data(config.server_address, config.server_port, send_buffer); char *numstr = strtok(recv_buffer, "&"); if (numstr == NULL) { die(STATE_UNKNOWN, _("could not fetch information from server\n")); @@ -281,8 +266,8 @@ int main(int argc, char **argv) { } double mem_commitByte = atof(numstr); double percent_used_space = (mem_commitByte / mem_commitLimit) * 100; - double warning_used_space = ((float)warning_value / 100) * mem_commitLimit; - double critical_used_space = ((float)critical_value / 100) * mem_commitLimit; + double warning_used_space = ((float)config.warning_value / 100) * mem_commitLimit; + double critical_used_space = ((float)config.critical_value / 100) * mem_commitLimit; /* Divisor should be 1048567, not 3044515, as we are measuring "Commit Charge" here, which equals RAM + Pagefiles. */ @@ -293,14 +278,14 @@ int main(int argc, char **argv) { critical_used_space / 1048567, mem_commitLimit / 1048567); return_code = STATE_OK; - if (check_critical_value && percent_used_space >= critical_value) { + if (config.check_critical_value && percent_used_space >= config.critical_value) { return_code = STATE_CRITICAL; - } else if (check_warning_value && percent_used_space >= warning_value) { + } else if (config.check_warning_value && percent_used_space >= config.warning_value) { return_code = STATE_WARNING; } break; - case CHECK_COUNTER: + case CHECK_COUNTER: { /* CHECK_COUNTER has been modified to provide extensive perfdata information. In order to do this, some modifications have been done to the code @@ -323,17 +308,17 @@ int main(int argc, char **argv) { */ double counter_value = 0.0; - if (value_list == NULL) { + if (config.value_list == NULL) { output_message = strdup(_("No counter specified")); } else { - preparelist(value_list); /* replace , between services with & to send the request */ - bool isPercent = (strchr(value_list, '%') != NULL); + preparelist(config.value_list); /* replace , between services with & to send the request */ + bool isPercent = (strchr(config.value_list, '%') != NULL); - strtok(value_list, "&"); /* burn the first parameters */ + strtok(config.value_list, "&"); /* burn the first parameters */ description = strtok(NULL, "&"); counter_unit = strtok(NULL, "&"); - xasprintf(&send_buffer, "%s&8&%s", req_password, value_list); - fetch_data(server_address, server_port, send_buffer); + xasprintf(&send_buffer, "%s&8&%s", config.req_password, config.value_list); + fetch_data(config.server_address, config.server_port, send_buffer); counter_value = atof(recv_buffer); bool allRight = false; @@ -380,52 +365,51 @@ int main(int argc, char **argv) { } xasprintf(&output_message, "%s |", output_message); xasprintf(&output_message, "%s %s", output_message, - fperfdata(description, counter_value, counter_unit, 1, warning_value, 1, critical_value, + fperfdata(description, counter_value, counter_unit, 1, config.warning_value, 1, config.critical_value, (!(isPercent) && (minval != NULL)), fminval, (!(isPercent) && (minval != NULL)), fmaxval)); } } - if (critical_value > warning_value) { /* Normal thresholds */ - if (check_critical_value && counter_value >= critical_value) { + if (config.critical_value > config.warning_value) { /* Normal thresholds */ + if (config.check_critical_value && counter_value >= config.critical_value) { return_code = STATE_CRITICAL; - } else if (check_warning_value && counter_value >= warning_value) { + } else if (config.check_warning_value && counter_value >= config.warning_value) { return_code = STATE_WARNING; } else { return_code = STATE_OK; } } else { /* inverse thresholds */ return_code = STATE_OK; - if (check_critical_value && counter_value <= critical_value) { + if (config.check_critical_value && counter_value <= config.critical_value) { return_code = STATE_CRITICAL; - } else if (check_warning_value && counter_value <= warning_value) { + } else if (config.check_warning_value && counter_value <= config.warning_value) { return_code = STATE_WARNING; } } - break; - + } break; case CHECK_FILEAGE: - if (value_list == NULL) { + if (config.value_list == NULL) { output_message = strdup(_("No counter specified")); } else { - preparelist(value_list); /* replace , between services with & to send the request */ - xasprintf(&send_buffer, "%s&9&%s", req_password, value_list); - fetch_data(server_address, server_port, send_buffer); + preparelist(config.value_list); /* replace , between services with & to send the request */ + xasprintf(&send_buffer, "%s&9&%s", config.req_password, config.value_list); + fetch_data(config.server_address, config.server_port, send_buffer); unsigned long age_in_minutes = atoi(strtok(recv_buffer, "&")); description = strtok(NULL, "&"); output_message = strdup(description); - if (critical_value > warning_value) { /* Normal thresholds */ - if (check_critical_value && age_in_minutes >= critical_value) { + if (config.critical_value > config.warning_value) { /* Normal thresholds */ + if (config.check_critical_value && age_in_minutes >= config.critical_value) { return_code = STATE_CRITICAL; - } else if (check_warning_value && age_in_minutes >= warning_value) { + } else if (config.check_warning_value && age_in_minutes >= config.warning_value) { return_code = STATE_WARNING; } else { return_code = STATE_OK; } } else { /* inverse thresholds */ - if (check_critical_value && age_in_minutes <= critical_value) { + if (config.check_critical_value && age_in_minutes <= config.critical_value) { return_code = STATE_CRITICAL; - } else if (check_warning_value && age_in_minutes <= warning_value) { + } else if (config.check_warning_value && age_in_minutes <= config.warning_value) { return_code = STATE_WARNING; } else { return_code = STATE_OK; @@ -435,11 +419,11 @@ int main(int argc, char **argv) { break; case CHECK_INSTANCES: - if (value_list == NULL) { + if (config.value_list == NULL) { output_message = strdup(_("No counter specified")); } else { - xasprintf(&send_buffer, "%s&10&%s", req_password, value_list); - fetch_data(server_address, server_port, send_buffer); + xasprintf(&send_buffer, "%s&10&%s", config.req_password, config.value_list); + fetch_data(config.server_address, config.server_port, send_buffer); if (!strncmp(recv_buffer, "ERROR", 5)) { printf("NSClient - %s\n", recv_buffer); exit(STATE_UNKNOWN); @@ -467,7 +451,7 @@ int main(int argc, char **argv) { } /* process command-line arguments */ -int process_arguments(int argc, char **argv) { +check_nt_config_wrapper process_arguments(int argc, char **argv) { static struct option longopts[] = {{"port", required_argument, 0, 'p'}, {"timeout", required_argument, 0, 't'}, {"critical", required_argument, 0, 'c'}, @@ -482,14 +466,20 @@ int process_arguments(int argc, char **argv) { {"help", no_argument, 0, 'h'}, {0, 0, 0, 0}}; + check_nt_config_wrapper result = { + .errorcode = OK, + .config = check_nt_config_init(), + }; + /* no options were supplied */ if (argc < 2) { - return ERROR; + result.errorcode = ERROR; + return result; } /* backwards compatibility */ if (!is_option(argv[1])) { - server_address = strdup(argv[1]); + result.config.server_address = strdup(argv[1]); argv[1] = argv[0]; argv = &argv[1]; argc--; @@ -523,60 +513,62 @@ int process_arguments(int argc, char **argv) { print_revision(progname, NP_VERSION); exit(STATE_UNKNOWN); case 'H': /* hostname */ - server_address = optarg; + result.config.server_address = optarg; break; case 's': /* password */ - req_password = optarg; + result.config.req_password = optarg; break; case 'p': /* port */ if (is_intnonneg(optarg)) { - server_port = atoi(optarg); + result.config.server_port = atoi(optarg); } else { die(STATE_UNKNOWN, _("Server port must be an integer\n")); } break; case 'v': if (strlen(optarg) < 4) { - return ERROR; + result.errorcode = ERROR; + return result; } if (!strcmp(optarg, "CLIENTVERSION")) { - vars_to_check = CHECK_CLIENTVERSION; + result.config.vars_to_check = CHECK_CLIENTVERSION; } else if (!strcmp(optarg, "CPULOAD")) { - vars_to_check = CHECK_CPULOAD; + result.config.vars_to_check = CHECK_CPULOAD; } else if (!strcmp(optarg, "UPTIME")) { - vars_to_check = CHECK_UPTIME; + result.config.vars_to_check = CHECK_UPTIME; } else if (!strcmp(optarg, "USEDDISKSPACE")) { - vars_to_check = CHECK_USEDDISKSPACE; + result.config.vars_to_check = CHECK_USEDDISKSPACE; } else if (!strcmp(optarg, "SERVICESTATE")) { - vars_to_check = CHECK_SERVICESTATE; + result.config.vars_to_check = CHECK_SERVICESTATE; } else if (!strcmp(optarg, "PROCSTATE")) { - vars_to_check = CHECK_PROCSTATE; + result.config.vars_to_check = CHECK_PROCSTATE; } else if (!strcmp(optarg, "MEMUSE")) { - vars_to_check = CHECK_MEMUSE; + result.config.vars_to_check = CHECK_MEMUSE; } else if (!strcmp(optarg, "COUNTER")) { - vars_to_check = CHECK_COUNTER; + result.config.vars_to_check = CHECK_COUNTER; } else if (!strcmp(optarg, "FILEAGE")) { - vars_to_check = CHECK_FILEAGE; + result.config.vars_to_check = CHECK_FILEAGE; } else if (!strcmp(optarg, "INSTANCES")) { - vars_to_check = CHECK_INSTANCES; + result.config.vars_to_check = CHECK_INSTANCES; } else { - return ERROR; + result.errorcode = ERROR; + return result; } break; case 'l': /* value list */ - value_list = optarg; + result.config.value_list = optarg; break; case 'w': /* warning threshold */ - warning_value = strtoul(optarg, NULL, 10); - check_warning_value = true; + result.config.warning_value = strtoul(optarg, NULL, 10); + result.config.check_warning_value = true; break; case 'c': /* critical threshold */ - critical_value = strtoul(optarg, NULL, 10); - check_critical_value = true; + result.config.critical_value = strtoul(optarg, NULL, 10); + result.config.check_critical_value = true; break; case 'd': /* Display select for services */ if (!strcmp(optarg, "SHOWALL")) { - show_all = true; + result.config.show_all = true; } break; case 'u': @@ -585,23 +577,25 @@ int process_arguments(int argc, char **argv) { case 't': /* timeout */ socket_timeout = atoi(optarg); if (socket_timeout <= 0) { - return ERROR; + result.errorcode = ERROR; + return result; } } } - if (server_address == NULL) { + if (result.config.server_address == NULL) { usage4(_("You must provide a server address or host name")); } - if (vars_to_check == CHECK_NONE) { - return ERROR; + if (result.config.vars_to_check == CHECK_NONE) { + result.errorcode = ERROR; + return result; } - if (req_password == NULL) { - req_password = strdup(_("None")); + if (result.config.req_password == NULL) { + result.config.req_password = strdup(_("None")); } - return OK; + return result; } void fetch_data(const char *address, int port, const char *sendb) { diff --git a/plugins/check_nt.d/config.h b/plugins/check_nt.d/config.h new file mode 100644 index 00000000..431889cb --- /dev/null +++ b/plugins/check_nt.d/config.h @@ -0,0 +1,53 @@ +#pragma once + +#include "../../config.h" +#include + +enum { + PORT = 1248, +}; + +enum checkvars { + CHECK_NONE, + CHECK_CLIENTVERSION, + CHECK_CPULOAD, + CHECK_UPTIME, + CHECK_USEDDISKSPACE, + CHECK_SERVICESTATE, + CHECK_PROCSTATE, + CHECK_MEMUSE, + CHECK_COUNTER, + CHECK_FILEAGE, + CHECK_INSTANCES +}; + +typedef struct { + char *server_address; + int server_port; + char *req_password; + enum checkvars vars_to_check; + bool show_all; + char *value_list; + bool check_warning_value; + unsigned long warning_value; + bool check_critical_value; + unsigned long critical_value; +} check_nt_config; + +check_nt_config check_nt_config_init() { + check_nt_config tmp = { + .server_address = NULL, + .server_port = PORT, + .req_password = NULL, + + .vars_to_check = CHECK_NONE, + .show_all = false, + .value_list = NULL, + + .check_warning_value = false, + .warning_value = 0, + .check_critical_value = false, + .critical_value = 0, + }; + return tmp; +} -- cgit v1.2.3-74-g34f1 From 9f6f32324e694d51e9e01e07fcd9694736f7846a Mon Sep 17 00:00:00 2001 From: Lorenz Kästle <12514511+RincewindsHat@users.noreply.github.com> Date: Wed, 12 Mar 2025 00:38:26 +0100 Subject: check_ntp_peer: clang-format --- plugins/check_ntp_peer.c | 94 +++++++++++++++++++++++++++++++----------------- 1 file changed, 62 insertions(+), 32 deletions(-) diff --git a/plugins/check_ntp_peer.c b/plugins/check_ntp_peer.c index f99e5032..35abdf10 100644 --- a/plugins/check_ntp_peer.c +++ b/plugins/check_ntp_peer.c @@ -255,22 +255,26 @@ int ntp_request(double *offset, int *offset_result, double *jitter, int *stratum /* Attempt to read the largest size packet possible */ req.count = htons(MAX_CM_SIZE); DBG(printf("receiving READSTAT response")) - if (read(conn, &req, SIZEOF_NTPCM(req)) == -1) + if (read(conn, &req, SIZEOF_NTPCM(req)) == -1) { die(STATE_CRITICAL, "NTP CRITICAL: No response from NTP server\n"); + } DBG(print_ntp_control_message(&req)); /* discard obviously invalid packets */ - if (ntohs(req.count) > MAX_CM_SIZE) + if (ntohs(req.count) > MAX_CM_SIZE) { die(STATE_CRITICAL, "NTP CRITICAL: Invalid packet received from NTP server\n"); + } } while (!(req.op & OP_READSTAT && ntohs(req.seq) == 1)); - if (LI(req.flags) == LI_ALARM) + if (LI(req.flags) == LI_ALARM) { li_alarm = true; + } /* Each peer identifier is 4 bytes in the data section, which * we represent as a ntp_assoc_status_pair datatype. */ peers_size += ntohs(req.count); - if ((tmp = realloc(peers, peers_size)) == NULL) + if ((tmp = realloc(peers, peers_size)) == NULL) { free(peers), die(STATE_UNKNOWN, "can not (re)allocate 'peers' buffer\n"); + } peers = tmp; memcpy((void *)((ptrdiff_t)peers + peer_offset), (void *)req.data, ntohs(req.count)); npeers = peers_size / sizeof(ntp_assoc_status_pair); @@ -293,21 +297,25 @@ int ntp_request(double *offset, int *offset_result, double *jitter, int *stratum } } - if (verbose) + if (verbose) { printf("%d candidate peers available\n", num_candidates); - if (verbose && syncsource_found) + } + if (verbose && syncsource_found) { printf("synchronization source found\n"); + } int status = STATE_OK; if (!syncsource_found) { status = STATE_WARNING; - if (verbose) + if (verbose) { printf("warning: no synchronization source found\n"); + } } if (li_alarm) { status = STATE_WARNING; - if (verbose) + if (verbose) { printf("warning: LI_ALARM bit is set\n"); + } } const char *getvar = "stratum,offset,jitter"; @@ -316,8 +324,9 @@ int ntp_request(double *offset, int *offset_result, double *jitter, int *stratum /* Only query this server if it is the current sync source */ /* If there's no sync.peer, query all candidates and use the best one */ if (PEER_SEL(peers[i].status) >= min_peer_sel) { - if (verbose) + if (verbose) { printf("Getting offset, jitter and stratum for peer %.2x\n", ntohs(peers[i].assoc)); + } xasprintf(&data, ""); do { setup_control_request(&req, OP_READVAR, 2); @@ -342,50 +351,58 @@ int ntp_request(double *offset, int *offset_result, double *jitter, int *stratum DBG(print_ntp_control_message(&req)); } while (!(req.op & OP_READVAR && ntohs(req.seq) == 2)); - if (!(req.op & REM_ERROR)) + if (!(req.op & REM_ERROR)) { xasprintf(&data, "%s%s", data, req.data); + } } while (req.op & REM_MORE); if (req.op & REM_ERROR) { if (strstr(getvar, "jitter")) { - if (verbose) + if (verbose) { printf("The command failed. This is usually caused by servers refusing the 'jitter'\nvariable. Restarting with " "'dispersion'...\n"); + } getvar = "stratum,offset,dispersion"; i--; continue; } if (strlen(getvar)) { - if (verbose) + if (verbose) { printf("Server didn't like dispersion either; will retrieve everything\n"); + } getvar = ""; i--; continue; } } - if (verbose > 1) + if (verbose > 1) { printf("Server responded: >>>%s<<<\n", data); + } double tmp_offset = 0; char *value; char *nptr; /* get the offset */ - if (verbose) + if (verbose) { printf("parsing offset from peer %.2x: ", ntohs(peers[i].assoc)); + } value = np_extract_ntpvar(data, "offset"); nptr = NULL; /* Convert the value if we have one */ - if (value != NULL) + if (value != NULL) { tmp_offset = strtod(value, &nptr) / 1000; + } /* If value is null or no conversion was performed */ if (value == NULL || value == nptr) { - if (verbose) + if (verbose) { printf("error: unable to read server offset response.\n"); + } } else { - if (verbose) + if (verbose) { printf("%.10g\n", tmp_offset); + } if (*offset_result == STATE_UNKNOWN || fabs(tmp_offset) < fabs(*offset)) { *offset = tmp_offset; *offset_result = STATE_OK; @@ -404,12 +421,14 @@ int ntp_request(double *offset, int *offset_result, double *jitter, int *stratum value = np_extract_ntpvar(data, strstr(getvar, "dispersion") != NULL ? "dispersion" : "jitter"); nptr = NULL; /* Convert the value if we have one */ - if (value != NULL) + if (value != NULL) { *jitter = strtod(value, &nptr); + } /* If value is null or no conversion was performed */ if (value == NULL || value == nptr) { - if (verbose) + if (verbose) { printf("error: unable to read server jitter/dispersion response.\n"); + } *jitter = -1; } else if (verbose) { printf("%.10g\n", *jitter); @@ -424,23 +443,27 @@ int ntp_request(double *offset, int *offset_result, double *jitter, int *stratum value = np_extract_ntpvar(data, "stratum"); nptr = NULL; /* Convert the value if we have one */ - if (value != NULL) + if (value != NULL) { *stratum = strtol(value, &nptr, 10); + } if (value == NULL || value == nptr) { - if (verbose) + if (verbose) { printf("error: unable to read server stratum response.\n"); + } *stratum = -1; } else { - if (verbose) + if (verbose) { printf("%i\n", *stratum); + } } } } /* if (PEER_SEL(peers[i].status) >= min_peer_sel) */ - } /* for (i = 0; i < npeers; i++) */ + } /* for (i = 0; i < npeers; i++) */ close(conn); - if (peers != NULL) + if (peers != NULL) { free(peers); + } return status; } @@ -454,14 +477,16 @@ int process_arguments(int argc, char **argv) { {"twarn", required_argument, 0, 'm'}, {"tcrit", required_argument, 0, 'n'}, {"timeout", required_argument, 0, 't'}, {"hostname", required_argument, 0, 'H'}, {"port", required_argument, 0, 'p'}, {0, 0, 0, 0}}; - if (argc < 2) + if (argc < 2) { usage("\n"); + } while (true) { int option = 0; int option_char = getopt_long(argc, argv, "Vhv46qw:c:W:C:j:k:m:n:t:H:p:", longopts, &option); - if (option_char == -1 || option_char == EOF || option_char == 1) + if (option_char == -1 || option_char == EOF || option_char == 1) { break; + } switch (option_char) { case 'h': @@ -509,8 +534,9 @@ int process_arguments(int argc, char **argv) { tcrit = optarg; break; case 'H': - if (!is_host(optarg)) + if (!is_host(optarg)) { usage2(_("Invalid hostname/address"), optarg); + } server_address = strdup(optarg); break; case 'p': @@ -571,8 +597,9 @@ int main(int argc, char *argv[]) { /* Parse extra opts if any */ argv = np_extra_opts(&argc, argv, progname); - if (process_arguments(argc, argv) == ERROR) + if (process_arguments(argc, argv) == ERROR) { usage4(_("Could not parse arguments")); + } set_thresholds(&offset_thresholds, owarn, ocrit); set_thresholds(&jitter_thresholds, jwarn, jcrit); @@ -598,8 +625,9 @@ int main(int argc, char *argv[]) { result = (quiet ? STATE_UNKNOWN : STATE_CRITICAL); } else { /* Be quiet if there's no candidates either */ - if (quiet && result == STATE_WARNING) + if (quiet && result == STATE_WARNING) { result = STATE_UNKNOWN; + } result = max_state_alt(result, get_status(fabs(offset), offset_thresholds)); } @@ -641,10 +669,11 @@ int main(int argc, char *argv[]) { xasprintf(&result_line, _("NTP UNKNOWN:")); break; } - if (!syncsource_found) + if (!syncsource_found) { xasprintf(&result_line, "%s %s,", result_line, _("Server not synchronized")); - else if (li_alarm) + } else if (li_alarm) { xasprintf(&result_line, "%s %s,", result_line, _("Server has the LI_ALARM bit set")); + } char *perfdata_line; if (offset_result == STATE_UNKNOWN) { @@ -691,8 +720,9 @@ int main(int argc, char *argv[]) { } printf("%s|%s\n", result_line, perfdata_line); - if (server_address != NULL) + if (server_address != NULL) { free(server_address); + } return result; } -- cgit v1.2.3-74-g34f1 From 8b2222e8b704fc451093996e906c07a6a8e3538a Mon Sep 17 00:00:00 2001 From: Lorenz Kästle <12514511+RincewindsHat@users.noreply.github.com> Date: Wed, 12 Mar 2025 01:00:48 +0100 Subject: Refactor check_ntp_peer --- plugins/Makefile.am | 1 + plugins/check_ntp_peer.c | 139 ++++++++++++++++++++------------------ plugins/check_ntp_peer.d/config.h | 54 +++++++++++++++ 3 files changed, 127 insertions(+), 67 deletions(-) create mode 100644 plugins/check_ntp_peer.d/config.h diff --git a/plugins/Makefile.am b/plugins/Makefile.am index 5d4449bf..a294cfef 100644 --- a/plugins/Makefile.am +++ b/plugins/Makefile.am @@ -60,6 +60,7 @@ EXTRA_DIST = t \ check_mrtgtraf.d \ check_mysql_query.d \ check_mrtg.d \ + check_ntp_peer.d \ check_apt.d \ check_by_ssh.d \ check_smtp.d \ diff --git a/plugins/check_ntp_peer.c b/plugins/check_ntp_peer.c index 35abdf10..6979d275 100644 --- a/plugins/check_ntp_peer.c +++ b/plugins/check_ntp_peer.c @@ -35,6 +35,7 @@ * *****************************************************************************/ +#include "states.h" const char *progname = "check_ntp_peer"; const char *copyright = "2006-2024"; const char *email = "devel@monitoring-plugins.org"; @@ -42,26 +43,17 @@ const char *email = "devel@monitoring-plugins.org"; #include "common.h" #include "netutils.h" #include "utils.h" +#include "check_ntp_peer.d/config.h" -static char *server_address = NULL; -static int port = 123; static int verbose = 0; -static bool quiet = false; -static char *owarn = "60"; -static char *ocrit = "120"; -static bool do_stratum = false; -static char *swarn = "-1:16"; -static char *scrit = "-1:16"; -static bool do_jitter = false; -static char *jwarn = "-1:5000"; -static char *jcrit = "-1:10000"; -static bool do_truechimers = false; -static char *twarn = "0:"; -static char *tcrit = "0:"; static bool syncsource_found = false; static bool li_alarm = false; -static int process_arguments(int /*argc*/, char ** /*argv*/); +typedef struct { + int errorcode; + check_ntp_peer_config config; +} check_ntp_peer_config_wrapper; +static check_ntp_peer_config_wrapper process_arguments(int /*argc*/, char ** /*argv*/); static thresholds *offset_thresholds = NULL; static thresholds *jitter_thresholds = NULL; static thresholds *stratum_thresholds = NULL; @@ -211,7 +203,8 @@ void setup_control_request(ntp_control_message *p, uint8_t opcode, uint16_t seq) * status is pretty much useless as syncsource_found is a global variable * used later in main to check is the server was synchronized. It works * so I left it alone */ -int ntp_request(double *offset, int *offset_result, double *jitter, int *stratum, int *num_truechimers) { +mp_state_enum ntp_request(double *offset, int *offset_result, double *jitter, int *stratum, int *num_truechimers, + const check_ntp_peer_config config) { *offset_result = STATE_UNKNOWN; *jitter = *stratum = -1; *num_truechimers = 0; @@ -240,7 +233,7 @@ int ntp_request(double *offset, int *offset_result, double *jitter, int *stratum int peers_size = 0; int npeers = 0; int conn = -1; - my_udp_connect(server_address, port, &conn); + my_udp_connect(config.server_address, config.port, &conn); /* keep sending requests until the server stops setting the * REM_MORE bit, though usually this is only 1 packet. */ @@ -412,7 +405,7 @@ int ntp_request(double *offset, int *offset_result, double *jitter, int *stratum } } - if (do_jitter) { + if (config.do_jitter) { /* get the jitter */ if (verbose) { printf("parsing %s from peer %.2x: ", strstr(getvar, "dispersion") != NULL ? "dispersion" : "jitter", @@ -435,7 +428,7 @@ int ntp_request(double *offset, int *offset_result, double *jitter, int *stratum } } - if (do_stratum) { + if (config.do_stratum) { /* get the stratum */ if (verbose) { printf("parsing stratum from peer %.2x: ", ntohs(peers[i].assoc)); @@ -468,7 +461,7 @@ int ntp_request(double *offset, int *offset_result, double *jitter, int *stratum return status; } -int process_arguments(int argc, char **argv) { +check_ntp_peer_config_wrapper process_arguments(int argc, char **argv) { static struct option longopts[] = { {"version", no_argument, 0, 'V'}, {"help", no_argument, 0, 'h'}, {"verbose", no_argument, 0, 'v'}, {"use-ipv4", no_argument, 0, '4'}, {"use-ipv6", no_argument, 0, '6'}, {"quiet", no_argument, 0, 'q'}, @@ -481,6 +474,11 @@ int process_arguments(int argc, char **argv) { usage("\n"); } + check_ntp_peer_config_wrapper result = { + .errorcode = OK, + .config = check_ntp_peer_config_init(), + }; + while (true) { int option = 0; int option_char = getopt_long(argc, argv, "Vhv46qw:c:W:C:j:k:m:n:t:H:p:", longopts, &option); @@ -501,46 +499,46 @@ int process_arguments(int argc, char **argv) { verbose++; break; case 'q': - quiet = true; + result.config.quiet = true; break; case 'w': - owarn = optarg; + result.config.owarn = optarg; break; case 'c': - ocrit = optarg; + result.config.ocrit = optarg; break; case 'W': - do_stratum = true; - swarn = optarg; + result.config.do_stratum = true; + result.config.swarn = optarg; break; case 'C': - do_stratum = true; - scrit = optarg; + result.config.do_stratum = true; + result.config.scrit = optarg; break; case 'j': - do_jitter = true; - jwarn = optarg; + result.config.do_jitter = true; + result.config.jwarn = optarg; break; case 'k': - do_jitter = true; - jcrit = optarg; + result.config.do_jitter = true; + result.config.jcrit = optarg; break; case 'm': - do_truechimers = true; - twarn = optarg; + result.config.do_truechimers = true; + result.config.twarn = optarg; break; case 'n': - do_truechimers = true; - tcrit = optarg; + result.config.do_truechimers = true; + result.config.tcrit = optarg; break; case 'H': if (!is_host(optarg)) { usage2(_("Invalid hostname/address"), optarg); } - server_address = strdup(optarg); + result.config.server_address = strdup(optarg); break; case 'p': - port = atoi(optarg); + result.config.port = atoi(optarg); break; case 't': socket_timeout = atoi(optarg); @@ -562,11 +560,11 @@ int process_arguments(int argc, char **argv) { } } - if (server_address == NULL) { + if (result.config.server_address == NULL) { usage4(_("Hostname was not supplied")); } - return 0; + return result; } char *perfd_offset(double offset) { @@ -574,17 +572,17 @@ char *perfd_offset(double offset) { 0); } -char *perfd_jitter(double jitter) { +char *perfd_jitter(double jitter, bool do_jitter) { return fperfdata("jitter", jitter, "", do_jitter, jitter_thresholds->warning->end, do_jitter, jitter_thresholds->critical->end, true, 0, false, 0); } -char *perfd_stratum(int stratum) { +char *perfd_stratum(int stratum, bool do_stratum) { return perfdata("stratum", stratum, "", do_stratum, (int)stratum_thresholds->warning->end, do_stratum, (int)stratum_thresholds->critical->end, true, 0, true, 16); } -char *perfd_truechimers(int num_truechimers) { +char *perfd_truechimers(int num_truechimers, const bool do_truechimers) { return perfdata("truechimers", num_truechimers, "", do_truechimers, (int)truechimer_thresholds->warning->end, do_truechimers, (int)truechimer_thresholds->critical->end, true, 0, false, 0); } @@ -597,14 +595,18 @@ 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_ntp_peer_config_wrapper tmp_config = process_arguments(argc, argv); + + if (tmp_config.errorcode == ERROR) { usage4(_("Could not parse arguments")); } - set_thresholds(&offset_thresholds, owarn, ocrit); - set_thresholds(&jitter_thresholds, jwarn, jcrit); - set_thresholds(&stratum_thresholds, swarn, scrit); - set_thresholds(&truechimer_thresholds, twarn, tcrit); + const check_ntp_peer_config config = tmp_config.config; + + set_thresholds(&offset_thresholds, config.owarn, config.ocrit); + set_thresholds(&jitter_thresholds, config.jwarn, config.jcrit); + set_thresholds(&stratum_thresholds, config.swarn, config.scrit); + set_thresholds(&truechimer_thresholds, config.twarn, config.tcrit); /* initialize alarm signal handling */ signal(SIGALRM, socket_timeout_alarm_handler); @@ -618,38 +620,37 @@ int main(int argc, char *argv[]) { double offset = 0; double jitter = 0; /* This returns either OK or WARNING (See comment preceding ntp_request) */ - int result = ntp_request(&offset, &offset_result, &jitter, &stratum, &num_truechimers); + mp_state_enum result = ntp_request(&offset, &offset_result, &jitter, &stratum, &num_truechimers, config); if (offset_result == STATE_UNKNOWN) { /* if there's no sync peer (this overrides ntp_request output): */ - result = (quiet ? STATE_UNKNOWN : STATE_CRITICAL); + result = (config.quiet ? STATE_UNKNOWN : STATE_CRITICAL); } else { /* Be quiet if there's no candidates either */ - if (quiet && result == STATE_WARNING) { + if (config.quiet && result == STATE_WARNING) { result = STATE_UNKNOWN; } result = max_state_alt(result, get_status(fabs(offset), offset_thresholds)); } - int oresult = result; - - int tresult = STATE_UNKNOWN; + mp_state_enum oresult = result; + mp_state_enum tresult = STATE_UNKNOWN; - if (do_truechimers) { + if (config.do_truechimers) { tresult = get_status(num_truechimers, truechimer_thresholds); result = max_state_alt(result, tresult); } - int sresult = STATE_UNKNOWN; + mp_state_enum sresult = STATE_UNKNOWN; - if (do_stratum) { + if (config.do_stratum) { sresult = get_status(stratum, stratum_thresholds); result = max_state_alt(result, sresult); } - int jresult = STATE_UNKNOWN; + mp_state_enum jresult = STATE_UNKNOWN; - if (do_jitter) { + if (config.do_jitter) { jresult = get_status(jitter, jitter_thresholds); result = max_state_alt(result, jresult); } @@ -669,6 +670,7 @@ int main(int argc, char *argv[]) { xasprintf(&result_line, _("NTP UNKNOWN:")); break; } + if (!syncsource_found) { xasprintf(&result_line, "%s %s,", result_line, _("Server not synchronized")); } else if (li_alarm) { @@ -688,7 +690,7 @@ int main(int argc, char *argv[]) { } xasprintf(&perfdata_line, "%s", perfd_offset(offset)); - if (do_jitter) { + if (config.do_jitter) { if (jresult == STATE_WARNING) { xasprintf(&result_line, "%s, jitter=%f (WARNING)", result_line, jitter); } else if (jresult == STATE_CRITICAL) { @@ -696,9 +698,10 @@ int main(int argc, char *argv[]) { } else { xasprintf(&result_line, "%s, jitter=%f", result_line, jitter); } - xasprintf(&perfdata_line, "%s %s", perfdata_line, perfd_jitter(jitter)); + xasprintf(&perfdata_line, "%s %s", perfdata_line, perfd_jitter(jitter, config.do_jitter)); } - if (do_stratum) { + + if (config.do_stratum) { if (sresult == STATE_WARNING) { xasprintf(&result_line, "%s, stratum=%i (WARNING)", result_line, stratum); } else if (sresult == STATE_CRITICAL) { @@ -706,9 +709,10 @@ int main(int argc, char *argv[]) { } else { xasprintf(&result_line, "%s, stratum=%i", result_line, stratum); } - xasprintf(&perfdata_line, "%s %s", perfdata_line, perfd_stratum(stratum)); + xasprintf(&perfdata_line, "%s %s", perfdata_line, perfd_stratum(stratum, config.do_stratum)); } - if (do_truechimers) { + + if (config.do_truechimers) { if (tresult == STATE_WARNING) { xasprintf(&result_line, "%s, truechimers=%i (WARNING)", result_line, num_truechimers); } else if (tresult == STATE_CRITICAL) { @@ -716,14 +720,15 @@ int main(int argc, char *argv[]) { } else { xasprintf(&result_line, "%s, truechimers=%i", result_line, num_truechimers); } - xasprintf(&perfdata_line, "%s %s", perfdata_line, perfd_truechimers(num_truechimers)); + xasprintf(&perfdata_line, "%s %s", perfdata_line, perfd_truechimers(num_truechimers, config.do_truechimers)); } printf("%s|%s\n", result_line, perfdata_line); - if (server_address != NULL) { - free(server_address); + if (config.server_address != NULL) { + free(config.server_address); } - return result; + + exit(result); } void print_help(void) { diff --git a/plugins/check_ntp_peer.d/config.h b/plugins/check_ntp_peer.d/config.h new file mode 100644 index 00000000..1907af7c --- /dev/null +++ b/plugins/check_ntp_peer.d/config.h @@ -0,0 +1,54 @@ +#pragma once + +#include "../../config.h" +#include + +enum { + DEFAULT_NTP_PORT = 123, +}; + +typedef struct { + char *server_address; + int port; + + bool quiet; + + // truechimer stuff + bool do_truechimers; + char *twarn; + char *tcrit; + + char *owarn; + char *ocrit; + + // stratum stuff + bool do_stratum; + char *swarn; + char *scrit; + + // jitter stuff + bool do_jitter; + char *jwarn; + char *jcrit; +} check_ntp_peer_config; + +check_ntp_peer_config check_ntp_peer_config_init() { + check_ntp_peer_config tmp = { + .server_address = NULL, + .port = DEFAULT_NTP_PORT, + + .quiet = false, + .do_truechimers = false, + .twarn = "0:", + .tcrit = "0:", + .owarn = "60", + .ocrit = "120", + .do_stratum = false, + .swarn = "-1:16", + .scrit = "-1:16", + .do_jitter = false, + .jwarn = "-1:5000", + .jcrit = "-1:10000", + }; + return tmp; +} -- cgit v1.2.3-74-g34f1 From 59156e79c97c1f425142e6ddc7983d4364534cef Mon Sep 17 00:00:00 2001 From: Lorenz Kästle <12514511+RincewindsHat@users.noreply.github.com> Date: Wed, 12 Mar 2025 01:08:18 +0100 Subject: check_ntp_time: clang-format --- plugins/check_ntp_time.c | 45 ++++++++++++++++++++++++++++++--------------- 1 file changed, 30 insertions(+), 15 deletions(-) diff --git a/plugins/check_ntp_time.c b/plugins/check_ntp_time.c index 703b69df..05c3d1e4 100644 --- a/plugins/check_ntp_time.c +++ b/plugins/check_ntp_time.c @@ -273,14 +273,16 @@ int best_offset_server(const ntp_server_results *slist, int nservers) { * stratum 0 is for reference clocks so no NTP server should ever report * a stratum 0 */ if (slist[cserver].stratum == 0) { - if (verbose) + if (verbose) { printf("discarding peer %d: stratum=%d\n", cserver, slist[cserver].stratum); + } continue; } /* Sort out servers with error flags */ if (LI(slist[cserver].flags) == LI_ALARM) { - if (verbose) + if (verbose) { printf("discarding peer %d: flags=%d\n", cserver, LI(slist[cserver].flags)); + } continue; } @@ -345,20 +347,24 @@ double offset_request(const char *host, int *status) { ntp_message *req = (ntp_message *)malloc(sizeof(ntp_message) * num_hosts); - if (req == NULL) + if (req == NULL) { die(STATE_UNKNOWN, "can not allocate ntp message array"); + } int *socklist = (int *)malloc(sizeof(int) * num_hosts); - if (socklist == NULL) + if (socklist == NULL) { die(STATE_UNKNOWN, "can not allocate socket array"); + } struct pollfd *ufds = (struct pollfd *)malloc(sizeof(struct pollfd) * num_hosts); - if (ufds == NULL) + if (ufds == NULL) { die(STATE_UNKNOWN, "can not allocate socket array"); + } ntp_server_results *servers = (ntp_server_results *)malloc(sizeof(ntp_server_results) * num_hosts); - if (servers == NULL) + if (servers == NULL) { die(STATE_UNKNOWN, "can not allocate server array"); + } memset(servers, 0, sizeof(ntp_server_results) * num_hosts); DBG(printf("Found %d peers to check\n", num_hosts)); @@ -400,10 +406,12 @@ double offset_request(const char *host, int *status) { for (int i = 0; i < num_hosts; i++) { if (servers[i].waiting < now_time && servers[i].num_responses < AVG_NUM) { - if (verbose && servers[i].waiting != 0) + if (verbose && servers[i].waiting != 0) { printf("re-"); - if (verbose) + } + if (verbose) { printf("sending request to peer %d\n", i); + } setup_request(&req[i]); write(socklist[i], &req[i], sizeof(ntp_message)); servers[i].waiting = now_time; @@ -442,8 +450,9 @@ double offset_request(const char *host, int *status) { servers[i].flags = req[i].flags; servers_readable--; one_read = true; - if (servers[i].num_responses == AVG_NUM) + if (servers[i].num_responses == AVG_NUM) { servers_completed++; + } } } /* lather, rinse, repeat. */ @@ -476,8 +485,9 @@ double offset_request(const char *host, int *status) { free(req); freeaddrinfo(ai); - if (verbose) + if (verbose) { printf("overall average offset: %.10g\n", avg_offset); + } return avg_offset; } @@ -496,14 +506,16 @@ int process_arguments(int argc, char **argv) { {"port", required_argument, 0, 'p'}, {0, 0, 0, 0}}; - if (argc < 2) + if (argc < 2) { usage("\n"); + } while (true) { int option = 0; int option_char = getopt_long(argc, argv, "Vhv46qw:c:t:H:p:o:", longopts, &option); - if (option_char == -1 || option_char == EOF || option_char == 1) + if (option_char == -1 || option_char == EOF || option_char == 1) { break; + } switch (option_char) { case 'h': @@ -527,8 +539,9 @@ int process_arguments(int argc, char **argv) { ocrit = optarg; break; case 'H': - if (!is_host(optarg)) + if (!is_host(optarg)) { usage2(_("Invalid hostname/address"), optarg); + } server_address = strdup(optarg); break; case 'p': @@ -577,8 +590,9 @@ int main(int argc, char *argv[]) { /* Parse extra opts if any */ argv = np_extra_opts(&argc, argv, progname); - if (process_arguments(argc, argv) == ERROR) + if (process_arguments(argc, argv) == ERROR) { usage4(_("Could not parse arguments")); + } set_thresholds(&offset_thresholds, owarn, ocrit); @@ -623,8 +637,9 @@ int main(int argc, char *argv[]) { } printf("%s|%s\n", result_line, perfdata_line); - if (server_address != NULL) + if (server_address != NULL) { free(server_address); + } return result; } -- cgit v1.2.3-74-g34f1 From b770cc0f42a78a5bb934b7cf757a04f132b1e2de Mon Sep 17 00:00:00 2001 From: Lorenz Kästle <12514511+RincewindsHat@users.noreply.github.com> Date: Wed, 12 Mar 2025 01:23:50 +0100 Subject: check_ntp_time: general refactoring --- plugins/check_ntp_time.c | 105 +++++++++++++++++++++++------------------------ 1 file changed, 51 insertions(+), 54 deletions(-) diff --git a/plugins/check_ntp_time.c b/plugins/check_ntp_time.c index 05c3d1e4..c757bc08 100644 --- a/plugins/check_ntp_time.c +++ b/plugins/check_ntp_time.c @@ -41,6 +41,7 @@ const char *email = "devel@monitoring-plugins.org"; #include "common.h" #include "netutils.h" #include "utils.h" +#include "states.h" static char *server_address = NULL; static char *port = "123"; @@ -50,7 +51,7 @@ static char *owarn = "60"; static char *ocrit = "120"; static int time_offset = 0; -static int process_arguments(int, char **); +static int process_arguments(int /*argc*/, char ** /*argv*/); static thresholds *offset_thresholds = NULL; static void print_help(void); void print_usage(void); @@ -159,7 +160,7 @@ typedef struct { #define EPOCHDIFF 0x83aa7e80UL /* extract a 32-bit ntp fixed point number into a double */ -#define NTP32asDOUBLE(x) (ntohs(L16(x)) + (double)ntohs(R16(x)) / 65536.0) +#define NTP32asDOUBLE(x) (ntohs(L16(x)) + ((double)ntohs(R16(x)) / 65536.0)) /* likewise for a 64-bit ntp fp number */ #define NTP64asDOUBLE(n) \ @@ -208,56 +209,52 @@ typedef struct { } while (0); /* calculate the offset of the local clock */ -static inline double calc_offset(const ntp_message *m, const struct timeval *t) { - double client_tx = NTP64asDOUBLE(m->origts); - double peer_rx = NTP64asDOUBLE(m->rxts); - double peer_tx = NTP64asDOUBLE(m->txts); - double client_rx = TVasDOUBLE((*t)); - return (.5 * ((peer_tx - client_rx) + (peer_rx - client_tx))); +static inline double calc_offset(const ntp_message *message, const struct timeval *time_value) { + double client_tx = NTP64asDOUBLE(message->origts); + double peer_rx = NTP64asDOUBLE(message->rxts); + double peer_tx = NTP64asDOUBLE(message->txts); + double client_rx = TVasDOUBLE((*time_value)); + return (((peer_tx - client_rx) + (peer_rx - client_tx)) / 2); } /* print out a ntp packet in human readable/debuggable format */ -void print_ntp_message(const ntp_message *p) { +void print_ntp_message(const ntp_message *message) { struct timeval ref; struct timeval orig; - struct timeval rx; - struct timeval tx; - NTP64toTV(p->refts, ref); - NTP64toTV(p->origts, orig); - NTP64toTV(p->rxts, rx); - NTP64toTV(p->txts, tx); + NTP64toTV(message->refts, ref); + NTP64toTV(message->origts, orig); printf("packet contents:\n"); - printf("\tflags: 0x%.2x\n", p->flags); - printf("\t li=%d (0x%.2x)\n", LI(p->flags), p->flags & LI_MASK); - printf("\t vn=%d (0x%.2x)\n", VN(p->flags), p->flags & VN_MASK); - printf("\t mode=%d (0x%.2x)\n", MODE(p->flags), p->flags & MODE_MASK); - printf("\tstratum = %d\n", p->stratum); - printf("\tpoll = %g\n", pow(2, p->poll)); - printf("\tprecision = %g\n", pow(2, p->precision)); - printf("\trtdelay = %-.16g\n", NTP32asDOUBLE(p->rtdelay)); - printf("\trtdisp = %-.16g\n", NTP32asDOUBLE(p->rtdisp)); - printf("\trefid = %x\n", p->refid); - printf("\trefts = %-.16g\n", NTP64asDOUBLE(p->refts)); - printf("\torigts = %-.16g\n", NTP64asDOUBLE(p->origts)); - printf("\trxts = %-.16g\n", NTP64asDOUBLE(p->rxts)); - printf("\ttxts = %-.16g\n", NTP64asDOUBLE(p->txts)); + printf("\tflags: 0x%.2x\n", message->flags); + printf("\t li=%d (0x%.2x)\n", LI(message->flags), message->flags & LI_MASK); + printf("\t vn=%d (0x%.2x)\n", VN(message->flags), message->flags & VN_MASK); + printf("\t mode=%d (0x%.2x)\n", MODE(message->flags), message->flags & MODE_MASK); + printf("\tstratum = %d\n", message->stratum); + printf("\tpoll = %g\n", pow(2, message->poll)); + printf("\tprecision = %g\n", pow(2, message->precision)); + printf("\trtdelay = %-.16g\n", NTP32asDOUBLE(message->rtdelay)); + printf("\trtdisp = %-.16g\n", NTP32asDOUBLE(message->rtdisp)); + printf("\trefid = %x\n", message->refid); + printf("\trefts = %-.16g\n", NTP64asDOUBLE(message->refts)); + printf("\torigts = %-.16g\n", NTP64asDOUBLE(message->origts)); + printf("\trxts = %-.16g\n", NTP64asDOUBLE(message->rxts)); + printf("\ttxts = %-.16g\n", NTP64asDOUBLE(message->txts)); } -void setup_request(ntp_message *p) { - memset(p, 0, sizeof(ntp_message)); - LI_SET(p->flags, LI_ALARM); - VN_SET(p->flags, 4); - MODE_SET(p->flags, MODE_CLIENT); - p->poll = 4; - p->precision = (int8_t)0xfa; - L16(p->rtdelay) = htons(1); - L16(p->rtdisp) = htons(1); +void setup_request(ntp_message *message) { + memset(message, 0, sizeof(ntp_message)); + LI_SET(message->flags, LI_ALARM); + VN_SET(message->flags, 4); + MODE_SET(message->flags, MODE_CLIENT); + message->poll = 4; + message->precision = (int8_t)0xfa; + L16(message->rtdelay) = htons(1); + L16(message->rtdisp) = htons(1); struct timeval t; gettimeofday(&t, NULL); - TVtoNTP64(t, p->txts); + TVtoNTP64(t, message->txts); } /* select the "best" server from a list of servers, and return its index. @@ -324,7 +321,7 @@ int best_offset_server(const ntp_server_results *slist, int nservers) { * we don't waste time sitting around waiting for single packets. * - we also "manually" handle resolving host names and connecting, because * we have to do it in a way that our lazy macros don't handle currently :( */ -double offset_request(const char *host, int *status) { +double offset_request(const char *host, mp_state_enum *status) { /* setup hints to only return results from getaddrinfo that we'd like */ struct addrinfo hints; memset(&hints, 0, sizeof(struct addrinfo)); @@ -333,15 +330,15 @@ double offset_request(const char *host, int *status) { hints.ai_socktype = SOCK_DGRAM; /* fill in ai with the list of hosts resolved by the host name */ - struct addrinfo *ai = NULL; - int ga_result = getaddrinfo(host, port, &hints, &ai); + struct addrinfo *addresses = NULL; + int ga_result = getaddrinfo(host, port, &hints, &addresses); if (ga_result != 0) { die(STATE_UNKNOWN, "error getting address for %s: %s\n", host, gai_strerror(ga_result)); } /* count the number of returned hosts, and allocate stuff accordingly */ - int num_hosts = 0; - for (struct addrinfo *ai_tmp = ai; ai_tmp != NULL; ai_tmp = ai_tmp->ai_next) { + size_t num_hosts = 0; + for (struct addrinfo *ai_tmp = addresses; ai_tmp != NULL; ai_tmp = ai_tmp->ai_next) { num_hosts++; } @@ -366,10 +363,10 @@ double offset_request(const char *host, int *status) { die(STATE_UNKNOWN, "can not allocate server array"); } memset(servers, 0, sizeof(ntp_server_results) * num_hosts); - DBG(printf("Found %d peers to check\n", num_hosts)); + DBG(printf("Found %zu peers to check\n", num_hosts)); /* setup each socket for writing, and the corresponding struct pollfd */ - struct addrinfo *ai_tmp = ai; + struct addrinfo *ai_tmp = addresses; for (int i = 0; ai_tmp; i++) { socklist[i] = socket(ai_tmp->ai_family, SOCK_DGRAM, IPPROTO_UDP); if (socklist[i] == -1) { @@ -427,10 +424,10 @@ double offset_request(const char *host, int *status) { } /* read from any sockets with pending data */ - for (int i = 0; servers_readable && i < num_hosts; i++) { + for (size_t i = 0; servers_readable && i < num_hosts; i++) { if (ufds[i].revents & POLLIN && servers[i].num_responses < AVG_NUM) { if (verbose) { - printf("response from peer %d: ", i); + printf("response from peer %zu: ", i); } read(ufds[i].fd, &req[i], sizeof(ntp_message)); @@ -458,7 +455,7 @@ double offset_request(const char *host, int *status) { /* lather, rinse, repeat. */ } - if (one_read == false) { + if (!one_read) { die(STATE_CRITICAL, "NTP CRITICAL: No response from NTP server\n"); } @@ -476,14 +473,14 @@ double offset_request(const char *host, int *status) { } /* cleanup */ - for (int j = 0; j < num_hosts; j++) { + for (size_t j = 0; j < num_hosts; j++) { close(socklist[j]); } free(socklist); free(ufds); free(servers); free(req); - freeaddrinfo(ai); + freeaddrinfo(addresses); if (verbose) { printf("overall average offset: %.10g\n", avg_offset); @@ -602,8 +599,8 @@ int main(int argc, char *argv[]) { /* set socket timeout */ alarm(socket_timeout); - int offset_result = STATE_OK; - int result = STATE_OK; + mp_state_enum offset_result = STATE_OK; + mp_state_enum result = STATE_OK; double offset = offset_request(server_address, &offset_result); if (offset_result == STATE_UNKNOWN) { result = ((!quiet) ? STATE_UNKNOWN : STATE_CRITICAL); @@ -640,7 +637,7 @@ int main(int argc, char *argv[]) { if (server_address != NULL) { free(server_address); } - return result; + exit(result); } void print_help(void) { -- cgit v1.2.3-74-g34f1 From 9ea0bf23df484cdb223595e02211aa9145dffb34 Mon Sep 17 00:00:00 2001 From: Lorenz Kästle <12514511+RincewindsHat@users.noreply.github.com> Date: Wed, 12 Mar 2025 01:41:48 +0100 Subject: Refactor check_ntp_time --- plugins/Makefile.am | 1 + plugins/check_ntp_time.c | 68 +++++++++++++++++++++++---------------- plugins/check_ntp_time.d/config.h | 28 ++++++++++++++++ 3 files changed, 69 insertions(+), 28 deletions(-) create mode 100644 plugins/check_ntp_time.d/config.h diff --git a/plugins/Makefile.am b/plugins/Makefile.am index 5d4449bf..bb117881 100644 --- a/plugins/Makefile.am +++ b/plugins/Makefile.am @@ -64,6 +64,7 @@ EXTRA_DIST = t \ check_by_ssh.d \ check_smtp.d \ check_mysql.d \ + check_ntp_time.d \ check_dig.d \ check_cluster.d \ check_fping.d diff --git a/plugins/check_ntp_time.c b/plugins/check_ntp_time.c index c757bc08..31162883 100644 --- a/plugins/check_ntp_time.c +++ b/plugins/check_ntp_time.c @@ -42,17 +42,17 @@ const char *email = "devel@monitoring-plugins.org"; #include "netutils.h" #include "utils.h" #include "states.h" +#include "thresholds.h" +#include "check_ntp_time.d/config.h" -static char *server_address = NULL; -static char *port = "123"; static int verbose = 0; -static bool quiet = false; -static char *owarn = "60"; -static char *ocrit = "120"; -static int time_offset = 0; -static int process_arguments(int /*argc*/, char ** /*argv*/); -static thresholds *offset_thresholds = NULL; +typedef struct { + int errorcode; + check_ntp_time_config config; +} check_ntp_time_config_wrapper; +static check_ntp_time_config_wrapper process_arguments(int /*argc*/, char ** /*argv*/); + static void print_help(void); void print_usage(void); @@ -321,7 +321,7 @@ int best_offset_server(const ntp_server_results *slist, int nservers) { * we don't waste time sitting around waiting for single packets. * - we also "manually" handle resolving host names and connecting, because * we have to do it in a way that our lazy macros don't handle currently :( */ -double offset_request(const char *host, mp_state_enum *status) { +double offset_request(const char *host, const char *port, mp_state_enum *status, int time_offset) { /* setup hints to only return results from getaddrinfo that we'd like */ struct addrinfo hints; memset(&hints, 0, sizeof(struct addrinfo)); @@ -392,7 +392,7 @@ double offset_request(const char *host, mp_state_enum *status) { time_t start_ts = 0; time_t now_time = 0; now_time = start_ts = time(NULL); - int servers_completed = 0; + size_t servers_completed = 0; bool one_read = false; while (servers_completed < num_hosts && now_time - start_ts <= socket_timeout / 2) { /* loop through each server and find each one which hasn't @@ -401,13 +401,13 @@ double offset_request(const char *host, mp_state_enum *status) { * and update the "waiting" timestamp with the current time. */ now_time = time(NULL); - for (int i = 0; i < num_hosts; i++) { + for (size_t i = 0; i < num_hosts; i++) { if (servers[i].waiting < now_time && servers[i].num_responses < AVG_NUM) { if (verbose && servers[i].waiting != 0) { printf("re-"); } if (verbose) { - printf("sending request to peer %d\n", i); + printf("sending request to peer %zu\n", i); } setup_request(&req[i]); write(socklist[i], &req[i], sizeof(ntp_message)); @@ -488,7 +488,7 @@ double offset_request(const char *host, mp_state_enum *status) { return avg_offset; } -int process_arguments(int argc, char **argv) { +check_ntp_time_config_wrapper process_arguments(int argc, char **argv) { static struct option longopts[] = {{"version", no_argument, 0, 'V'}, {"help", no_argument, 0, 'h'}, {"verbose", no_argument, 0, 'v'}, @@ -507,6 +507,14 @@ int process_arguments(int argc, char **argv) { usage("\n"); } + check_ntp_time_config_wrapper result = { + .errorcode = OK, + .config = check_ntp_time_config_init(), + }; + + char *owarn = "60"; + char *ocrit = "120"; + while (true) { int option = 0; int option_char = getopt_long(argc, argv, "Vhv46qw:c:t:H:p:o:", longopts, &option); @@ -527,7 +535,7 @@ int process_arguments(int argc, char **argv) { verbose++; break; case 'q': - quiet = true; + result.config.quiet = true; break; case 'w': owarn = optarg; @@ -539,16 +547,16 @@ int process_arguments(int argc, char **argv) { if (!is_host(optarg)) { usage2(_("Invalid hostname/address"), optarg); } - server_address = strdup(optarg); + result.config.server_address = strdup(optarg); break; case 'p': - port = strdup(optarg); + result.config.port = strdup(optarg); break; case 't': socket_timeout = atoi(optarg); break; case 'o': - time_offset = atoi(optarg); + result.config.time_offset = atoi(optarg); break; case '4': address_family = AF_INET; @@ -567,14 +575,16 @@ int process_arguments(int argc, char **argv) { } } - if (server_address == NULL) { + if (result.config.server_address == NULL) { usage4(_("Hostname was not supplied")); } - return 0; + set_thresholds(&result.config.offset_thresholds, owarn, ocrit); + + return result; } -char *perfd_offset(double offset) { +char *perfd_offset(double offset, thresholds *offset_thresholds) { return fperfdata("offset", offset, "s", true, offset_thresholds->warning->end, true, offset_thresholds->critical->end, false, 0, false, 0); } @@ -587,11 +597,13 @@ 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_ntp_time_config_wrapper tmp_config = process_arguments(argc, argv); + + if (tmp_config.errorcode == ERROR) { usage4(_("Could not parse arguments")); } - set_thresholds(&offset_thresholds, owarn, ocrit); + const check_ntp_time_config config = tmp_config.config; /* initialize alarm signal handling */ signal(SIGALRM, socket_timeout_alarm_handler); @@ -601,11 +613,11 @@ int main(int argc, char *argv[]) { mp_state_enum offset_result = STATE_OK; mp_state_enum result = STATE_OK; - double offset = offset_request(server_address, &offset_result); + double offset = offset_request(config.server_address, config.port, &offset_result, config.time_offset); if (offset_result == STATE_UNKNOWN) { - result = ((!quiet) ? STATE_UNKNOWN : STATE_CRITICAL); + result = ((!config.quiet) ? STATE_UNKNOWN : STATE_CRITICAL); } else { - result = get_status(fabs(offset), offset_thresholds); + result = get_status(fabs(offset), config.offset_thresholds); } char *result_line; @@ -630,12 +642,12 @@ int main(int argc, char *argv[]) { xasprintf(&perfdata_line, ""); } else { xasprintf(&result_line, "%s %s %.10g secs", result_line, _("Offset"), offset); - xasprintf(&perfdata_line, "%s", perfd_offset(offset)); + xasprintf(&perfdata_line, "%s", perfd_offset(offset, config.offset_thresholds)); } printf("%s|%s\n", result_line, perfdata_line); - if (server_address != NULL) { - free(server_address); + if (config.server_address != NULL) { + free(config.server_address); } exit(result); } diff --git a/plugins/check_ntp_time.d/config.h b/plugins/check_ntp_time.d/config.h new file mode 100644 index 00000000..99dabbbd --- /dev/null +++ b/plugins/check_ntp_time.d/config.h @@ -0,0 +1,28 @@ +#pragma once + +#include "../../config.h" +#include "thresholds.h" +#include + +typedef struct { + char *server_address; + char *port; + + bool quiet; + int time_offset; + + thresholds *offset_thresholds; +} check_ntp_time_config; + +check_ntp_time_config check_ntp_time_config_init() { + check_ntp_time_config tmp = { + .server_address = NULL, + .port = "123", + + .quiet = false, + .time_offset = 0, + + .offset_thresholds = NULL, + }; + return tmp; +} -- cgit v1.2.3-74-g34f1 From 003b96741ddcfa9fa5746f918d8cb86e37b6fb9e Mon Sep 17 00:00:00 2001 From: Lorenz Kästle <12514511+RincewindsHat@users.noreply.github.com> Date: Wed, 12 Mar 2025 01:47:38 +0100 Subject: check_pgsql: clang-format --- plugins/check_pgsql.c | 89 +++++++++++++++++++++++++++++++++------------------ 1 file changed, 57 insertions(+), 32 deletions(-) diff --git a/plugins/check_pgsql.c b/plugins/check_pgsql.c index 6613634d..0c0ef415 100644 --- a/plugins/check_pgsql.c +++ b/plugins/check_pgsql.c @@ -150,10 +150,12 @@ int main(int argc, char **argv) { /* Parse extra opts if any */ argv = np_extra_opts(&argc, argv, progname); - if (process_arguments(argc, argv) == ERROR) + if (process_arguments(argc, argv) == ERROR) { usage4(_("Could not parse arguments")); - if (verbose > 2) + } + if (verbose > 2) { printf("Arguments initialized\n"); + } /* Set signal handling and alarm */ if (signal(SIGALRM, timeout_alarm_handler) == SIG_ERR) { @@ -162,25 +164,32 @@ int main(int argc, char **argv) { alarm(timeout_interval); char *conninfo = NULL; - if (pgparams) + if (pgparams) { asprintf(&conninfo, "%s ", pgparams); + } asprintf(&conninfo, "%sdbname = '%s'", conninfo ? conninfo : "", dbName); - if (pghost) + if (pghost) { asprintf(&conninfo, "%s host = '%s'", conninfo, pghost); - if (pgport) + } + if (pgport) { asprintf(&conninfo, "%s port = '%s'", conninfo, pgport); - if (pgoptions) + } + if (pgoptions) { asprintf(&conninfo, "%s options = '%s'", conninfo, pgoptions); + } /* if (pgtty) -- ignored by PQconnectdb */ - if (pguser) + if (pguser) { asprintf(&conninfo, "%s user = '%s'", conninfo, pguser); + } - if (verbose) /* do not include password (see right below) in output */ + if (verbose) { /* do not include password (see right below) in output */ printf("Connecting to PostgreSQL using conninfo: %s%s\n", conninfo, pgpasswd ? " password = " : ""); + } - if (pgpasswd) + if (pgpasswd) { asprintf(&conninfo, "%s password = '%s'", conninfo, pgpasswd); + } /* make a connection to the database */ struct timeval start_timeval; @@ -196,12 +205,14 @@ int main(int argc, char **argv) { double elapsed_time = (double)(end_timeval.tv_sec - start_timeval.tv_sec) + (double)(end_timeval.tv_usec - start_timeval.tv_usec) / 1000000.0; - if (verbose) + if (verbose) { printf("Time elapsed: %f\n", elapsed_time); + } /* check to see that the backend connection was successfully made */ - if (verbose) + if (verbose) { printf("Verifying connection\n"); + } if (PQstatus(conn) == CONNECTION_BAD) { printf(_("CRITICAL - no connection to '%s' (%s).\n"), dbName, PQerrorMessage(conn)); PQfinish(conn); @@ -232,11 +243,13 @@ int main(int argc, char **argv) { fperfdata("time", elapsed_time, "s", !!(twarn > 0.0), twarn, !!(tcrit > 0.0), tcrit, true, 0, false, 0)); int query_status = STATE_UNKNOWN; - if (pgquery) + if (pgquery) { query_status = do_query(conn, pgquery); + } - if (verbose) + if (verbose) { printf("Closing connection\n"); + } PQfinish(conn); return (pgquery && query_status > status) ? query_status : status; } @@ -266,8 +279,9 @@ int process_arguments(int argc, char **argv) { 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); - if (option_char == EOF) + if (option_char == EOF) { break; + } switch (option_char) { case '?': /* usage */ @@ -279,22 +293,25 @@ int process_arguments(int argc, char **argv) { print_revision(progname, NP_VERSION); exit(STATE_UNKNOWN); case 't': /* timeout period */ - if (!is_integer(optarg)) + if (!is_integer(optarg)) { usage2(_("Timeout interval must be a positive integer"), optarg); - else + } else { timeout_interval = atoi(optarg); + } break; case 'c': /* critical time threshold */ - if (!is_nonnegative(optarg)) + if (!is_nonnegative(optarg)) { usage2(_("Critical threshold must be a positive integer"), optarg); - else + } else { tcrit = strtod(optarg, NULL); + } break; case 'w': /* warning time threshold */ - if (!is_nonnegative(optarg)) + if (!is_nonnegative(optarg)) { usage2(_("Warning threshold must be a positive integer"), optarg); - else + } else { twarn = strtod(optarg, NULL); + } break; case 'C': /* critical query threshold */ query_critical = optarg; @@ -303,16 +320,18 @@ int process_arguments(int argc, char **argv) { query_warning = optarg; break; case 'H': /* host */ - if ((*optarg != '/') && (!is_host(optarg))) + if ((*optarg != '/') && (!is_host(optarg))) { usage2(_("Invalid hostname/address"), optarg); - else + } else { pghost = optarg; + } break; case 'P': /* port */ - if (!is_integer(optarg)) + if (!is_integer(optarg)) { usage2(_("Port must be a positive integer"), optarg); - else + } else { pgport = optarg; + } break; case 'd': /* database name */ if (strlen(optarg) >= NAMEDATALEN) { @@ -321,20 +340,22 @@ int process_arguments(int argc, char **argv) { snprintf(dbName, NAMEDATALEN, "%s", optarg); break; case 'l': /* login name */ - if (!is_pg_logname(optarg)) + if (!is_pg_logname(optarg)) { usage2(_("User name is not valid"), optarg); - else + } else { pguser = optarg; + } break; case 'p': /* authentication password */ case 'a': pgpasswd = optarg; break; case 'o': - if (pgparams) + if (pgparams) { asprintf(&pgparams, "%s %s", pgparams, optarg); - else + } else { asprintf(&pgparams, "%s", optarg); + } break; case 'q': pgquery = optarg; @@ -378,8 +399,9 @@ should be added. ******************************************************************************/ bool is_pg_logname(char *username) { - if (strlen(username) > NAMEDATALEN - 1) + if (strlen(username) > NAMEDATALEN - 1) { return (false); + } return (true); } @@ -483,8 +505,9 @@ void print_usage(void) { } int do_query(PGconn *conn, char *query) { - if (verbose) + if (verbose) { printf("Executing SQL query \"%s\".\n", query); + } PGresult *res = PQexec(conn, query); if (PGRES_TUPLES_OK != PQresultStatus(res)) { @@ -510,8 +533,9 @@ int do_query(PGconn *conn, char *query) { char *endptr = NULL; double value = strtod(val_str, &endptr); - if (verbose) + if (verbose) { printf("Query result: %f\n", value); + } if (endptr == val_str) { printf("QUERY %s - %s: %s\n", _("CRITICAL"), _("Is not a numeric"), val_str); @@ -519,8 +543,9 @@ int do_query(PGconn *conn, char *query) { } if ((endptr != NULL) && (*endptr != '\0')) { - if (verbose) + if (verbose) { printf("Garbage after value: %s.\n", endptr); + } } int my_status = get_status(value, qthresholds); -- cgit v1.2.3-74-g34f1 From de392a81ede00fef1c25e220ee253d487453f6cd Mon Sep 17 00:00:00 2001 From: Lorenz Kästle <12514511+RincewindsHat@users.noreply.github.com> Date: Wed, 12 Mar 2025 02:16:41 +0100 Subject: 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(-) create mode 100644 plugins/check_pgsql.d/config.h 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 #include -#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 = " : ""); + printf("Connecting to PostgreSQL using conninfo: %s%s\n", conninfo, config.pgpasswd ? " password = " : ""); } - 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 ] [-C ] [-W ]\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 +#include + +#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; +} -- cgit v1.2.3-74-g34f1 From dbfd6568658869c017feb518e50c574f0b928d6f Mon Sep 17 00:00:00 2001 From: Lorenz Kästle <12514511+RincewindsHat@users.noreply.github.com> Date: Wed, 12 Mar 2025 11:10:43 +0100 Subject: all includes in one place --- plugins/check_ntp_peer.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/check_ntp_peer.c b/plugins/check_ntp_peer.c index 6979d275..fcd06b8e 100644 --- a/plugins/check_ntp_peer.c +++ b/plugins/check_ntp_peer.c @@ -35,7 +35,6 @@ * *****************************************************************************/ -#include "states.h" const char *progname = "check_ntp_peer"; const char *copyright = "2006-2024"; const char *email = "devel@monitoring-plugins.org"; @@ -43,6 +42,7 @@ const char *email = "devel@monitoring-plugins.org"; #include "common.h" #include "netutils.h" #include "utils.h" +#include "../lib/states.h" #include "check_ntp_peer.d/config.h" static int verbose = 0; -- cgit v1.2.3-74-g34f1 From 56ad762bd3bd59e5dac1ecb0e87c0b69f4ebaffc Mon Sep 17 00:00:00 2001 From: Lorenz Kästle <12514511+RincewindsHat@users.noreply.github.com> Date: Wed, 12 Mar 2025 11:16:04 +0100 Subject: Remove check_overcr This commit removes the plugin check_overcr and all related files and parts of files. OverCR seems to be dead and I have never seen a mention of an active usage anywhere. The website still does exist, but the activity seems to be limited. Carrying check_overcr forward seems to be a burden without a purpose and more of an opportunity to remove some code. --- .github/monitoring-plugins.spec | 14 -- .gitignore | 1 - plugins/Makefile.am | 3 +- plugins/check_overcr.c | 417 ---------------------------------------- 4 files changed, 1 insertion(+), 434 deletions(-) delete mode 100644 plugins/check_overcr.c diff --git a/.github/monitoring-plugins.spec b/.github/monitoring-plugins.spec index 5cae3e59..64ee34f2 100644 --- a/.github/monitoring-plugins.spec +++ b/.github/monitoring-plugins.spec @@ -193,7 +193,6 @@ Requires: %{name}-ntp_peer Requires: %{name}-ntp_time Requires: %{name}-nwstat Requires: %{name}-oracle -Requires: %{name}-overcr Requires: %{name}-pgsql Requires: %{name}-ping Requires: %{name}-procs @@ -729,19 +728,6 @@ Provides check_oracle of the Monitoring Plugins. -# check_overcr -%package overcr -Summary: Monitoring Plugins - check_overcr -Requires: %{name} = %{version}-%{release} - -%description overcr -Provides check_overcr of the Monitoring Plugins. - -%files overcr -%{plugindir}/check_overcr - - - # check_pgsql %package pgsql Summary: Monitoring Plugins - check_pgsql diff --git a/.gitignore b/.gitignore index 0efc2b66..f9cb37e4 100644 --- a/.gitignore +++ b/.gitignore @@ -178,7 +178,6 @@ NP-VERSION-FILE /plugins/check_ntp_peer /plugins/check_ntp_time /plugins/check_nwstat -/plugins/check_overcr /plugins/check_pgsql /plugins/check_ping /plugins/check_pop diff --git a/plugins/Makefile.am b/plugins/Makefile.am index 9ea6e85e..6c582a15 100644 --- a/plugins/Makefile.am +++ b/plugins/Makefile.am @@ -27,7 +27,7 @@ MATHLIBS = @MATHLIBS@ #AM_CFLAGS = -Wall libexec_PROGRAMS = check_apt check_cluster check_disk check_dummy check_http check_load \ - check_mrtg check_mrtgtraf check_ntp check_ntp_peer check_nwstat check_overcr check_ping \ + check_mrtg check_mrtgtraf check_ntp check_ntp_peer check_nwstat check_ping \ check_real check_smtp check_ssh check_tcp check_time check_ntp_time \ check_ups check_users negate \ urlize @EXTRAS@ @@ -132,7 +132,6 @@ check_nt_LDADD = $(NETLIBS) check_ntp_LDADD = $(NETLIBS) $(MATHLIBS) check_ntp_peer_LDADD = $(NETLIBS) $(MATHLIBS) check_nwstat_LDADD = $(NETLIBS) -check_overcr_LDADD = $(NETLIBS) check_pgsql_LDADD = $(NETLIBS) $(PGLIBS) check_ping_LDADD = $(NETLIBS) check_procs_LDADD = $(BASEOBJS) diff --git a/plugins/check_overcr.c b/plugins/check_overcr.c deleted file mode 100644 index 599540b7..00000000 --- a/plugins/check_overcr.c +++ /dev/null @@ -1,417 +0,0 @@ -/***************************************************************************** - * - * Monitoring check_overcr plugin - * - * License: GPL - * Copyright (c) 2000-2024 Monitoring Plugins Development Team - * - * Description: - * - * This file contains the check_overcr plugin - * - * This plugin attempts to contact the Over-CR collector daemon running on the - * remote UNIX server in order to gather the requested system information. - * - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - * - *****************************************************************************/ - -const char *progname = "check_overcr"; -const char *copyright = "2000-2024"; -const char *email = "devel@monitoring-plugins.org"; - -#include "common.h" -#include "netutils.h" -#include "utils.h" - -enum checkvar { - NONE, - LOAD1, - LOAD5, - LOAD15, - DPU, - PROCS, - NETSTAT, - UPTIME -}; - -enum { - PORT = 2000 -}; - -static char *server_address = NULL; -static int server_port = PORT; -static double warning_value = 0L; -static double critical_value = 0L; -static bool check_warning_value = false; -static bool check_critical_value = false; -static enum checkvar vars_to_check = NONE; - -static int netstat_port = 0; -static char *disk_name = NULL; -static char *process_name = NULL; -static char send_buffer[MAX_INPUT_BUFFER]; - -static int process_arguments(int, char **); -void print_usage(void); -static void print_help(void); - -int main(int argc, char **argv) { - int result = STATE_UNKNOWN; - char recv_buffer[MAX_INPUT_BUFFER]; - char temp_buffer[MAX_INPUT_BUFFER]; - char *temp_ptr = NULL; - bool found_disk = false; - unsigned long percent_used_disk_space = 100; - double load; - double load_1min; - double load_5min; - double load_15min; - int port_connections = 0; - int processes = 0; - double uptime_raw_hours; - int uptime_raw_minutes = 0; - int uptime_days = 0; - int uptime_hours = 0; - int uptime_minutes = 0; - - setlocale(LC_ALL, ""); - bindtextdomain(PACKAGE, LOCALEDIR); - textdomain(PACKAGE); - - /* Parse extra opts if any */ - argv = np_extra_opts(&argc, argv, progname); - - if (process_arguments(argc, argv) == ERROR) - usage4(_("Could not parse arguments")); - - /* initialize alarm signal handling */ - signal(SIGALRM, socket_timeout_alarm_handler); - - /* set socket timeout */ - alarm(socket_timeout); - - result = process_tcp_request2(server_address, server_port, send_buffer, recv_buffer, sizeof(recv_buffer)); - - switch (vars_to_check) { - - case LOAD1: - case LOAD5: - case LOAD15: - - if (result != STATE_OK) - die(result, _("Unknown error fetching load data\n")); - - temp_ptr = (char *)strtok(recv_buffer, "\r\n"); - if (temp_ptr == NULL) - die(STATE_CRITICAL, _("Invalid response from server - no load information\n")); - else - load_1min = strtod(temp_ptr, NULL); - - temp_ptr = (char *)strtok(NULL, "\r\n"); - if (temp_ptr == NULL) - die(STATE_CRITICAL, _("Invalid response from server after load 1\n")); - else - load_5min = strtod(temp_ptr, NULL); - - temp_ptr = (char *)strtok(NULL, "\r\n"); - if (temp_ptr == NULL) - die(STATE_CRITICAL, _("Invalid response from server after load 5\n")); - else - load_15min = strtod(temp_ptr, NULL); - - switch (vars_to_check) { - case LOAD1: - strcpy(temp_buffer, "1"); - load = load_1min; - break; - case LOAD5: - strcpy(temp_buffer, "5"); - load = load_5min; - break; - default: - strcpy(temp_buffer, "15"); - load = load_15min; - break; - } - - if (check_critical_value && (load >= critical_value)) - result = STATE_CRITICAL; - else if (check_warning_value && (load >= warning_value)) - result = STATE_WARNING; - - die(result, _("Load %s - %s-min load average = %0.2f"), state_text(result), temp_buffer, load); - - break; - - case DPU: - - if (result != STATE_OK) - die(result, _("Unknown error fetching disk data\n")); - - for (temp_ptr = (char *)strtok(recv_buffer, " "); temp_ptr != NULL; temp_ptr = (char *)strtok(NULL, " ")) { - - if (!strcmp(temp_ptr, disk_name)) { - found_disk = true; - temp_ptr = (char *)strtok(NULL, "%"); - if (temp_ptr == NULL) - die(STATE_CRITICAL, _("Invalid response from server\n")); - else - percent_used_disk_space = strtoul(temp_ptr, NULL, 10); - break; - } - - temp_ptr = (char *)strtok(NULL, "\r\n"); - } - - /* error if we couldn't find the info for the disk */ - if (!found_disk) - die(STATE_CRITICAL, "CRITICAL - Disk '%s' non-existent or not mounted", disk_name); - - if (check_critical_value && (percent_used_disk_space >= critical_value)) - result = STATE_CRITICAL; - else if (check_warning_value && (percent_used_disk_space >= warning_value)) - result = STATE_WARNING; - - die(result, "Disk %s - %lu%% used on %s", state_text(result), percent_used_disk_space, disk_name); - - break; - - case NETSTAT: - - if (result != STATE_OK) - die(result, _("Unknown error fetching network status\n")); - else - port_connections = strtod(recv_buffer, NULL); - - if (check_critical_value && (port_connections >= critical_value)) - result = STATE_CRITICAL; - else if (check_warning_value && (port_connections >= warning_value)) - result = STATE_WARNING; - - die(result, _("Net %s - %d connection%s on port %d"), state_text(result), port_connections, (port_connections == 1) ? "" : "s", - netstat_port); - - break; - - case PROCS: - - if (result != STATE_OK) - die(result, _("Unknown error fetching process status\n")); - - temp_ptr = (char *)strtok(recv_buffer, "("); - if (temp_ptr == NULL) - die(STATE_CRITICAL, _("Invalid response from server\n")); - - temp_ptr = (char *)strtok(NULL, ")"); - if (temp_ptr == NULL) - die(STATE_CRITICAL, _("Invalid response from server\n")); - else - processes = strtod(temp_ptr, NULL); - - if (check_critical_value && (processes >= critical_value)) - result = STATE_CRITICAL; - else if (check_warning_value && (processes >= warning_value)) - result = STATE_WARNING; - - die(result, _("Process %s - %d instance%s of %s running"), state_text(result), processes, (processes == 1) ? "" : "s", - process_name); - break; - - case UPTIME: - - if (result != STATE_OK) - return result; - - uptime_raw_hours = strtod(recv_buffer, NULL); - uptime_raw_minutes = (unsigned long)(uptime_raw_hours * 60.0); - - if (check_critical_value && (uptime_raw_minutes <= critical_value)) - result = STATE_CRITICAL; - else if (check_warning_value && (uptime_raw_minutes <= warning_value)) - result = STATE_WARNING; - - uptime_days = uptime_raw_minutes / 1440; - uptime_raw_minutes %= 1440; - uptime_hours = uptime_raw_minutes / 60; - uptime_raw_minutes %= 60; - uptime_minutes = uptime_raw_minutes; - - die(result, _("Uptime %s - Up %d days %d hours %d minutes"), state_text(result), uptime_days, uptime_hours, uptime_minutes); - break; - - default: - die(STATE_UNKNOWN, _("Nothing to check!\n")); - break; - } -} - -/* process command-line arguments */ -int process_arguments(int argc, char **argv) { - int c; - - int option = 0; - static struct option longopts[] = { - {"port", required_argument, 0, 'p'}, {"timeout", required_argument, 0, 't'}, {"critical", required_argument, 0, 'c'}, - {"warning", required_argument, 0, 'w'}, {"variable", required_argument, 0, 'v'}, {"hostname", required_argument, 0, 'H'}, - {"version", no_argument, 0, 'V'}, {"help", no_argument, 0, 'h'}, {0, 0, 0, 0}}; - - /* no options were supplied */ - if (argc < 2) - return ERROR; - - /* backwards compatibility */ - if (!is_option(argv[1])) { - server_address = argv[1]; - argv[1] = argv[0]; - argv = &argv[1]; - argc--; - } - - for (c = 1; c < argc; c++) { - if (strcmp("-to", argv[c]) == 0) - strcpy(argv[c], "-t"); - else if (strcmp("-wv", argv[c]) == 0) - strcpy(argv[c], "-w"); - else if (strcmp("-cv", argv[c]) == 0) - strcpy(argv[c], "-c"); - } - - while (1) { - c = getopt_long(argc, argv, "+hVH:t:c:w:p:v:", longopts, &option); - - if (c == -1 || c == EOF || c == 1) - break; - - switch (c) { - case '?': /* print short usage statement if args not parsable */ - usage5(); - case 'h': /* help */ - print_help(); - exit(STATE_UNKNOWN); - case 'V': /* version */ - print_revision(progname, NP_VERSION); - exit(STATE_UNKNOWN); - case 'H': /* hostname */ - server_address = optarg; - break; - case 'p': /* port */ - if (is_intnonneg(optarg)) - server_port = atoi(optarg); - else - die(STATE_UNKNOWN, _("Server port an integer\n")); - break; - case 'v': /* variable */ - if (strcmp(optarg, "LOAD") == 0) { - strcpy(send_buffer, "LOAD\r\nQUIT\r\n"); - if (strcmp(optarg, "LOAD1") == 0) - vars_to_check = LOAD1; - else if (strcmp(optarg, "LOAD5") == 0) - vars_to_check = LOAD5; - else if (strcmp(optarg, "LOAD15") == 0) - vars_to_check = LOAD15; - } else if (strcmp(optarg, "UPTIME") == 0) { - vars_to_check = UPTIME; - strcpy(send_buffer, "UPTIME\r\n"); - } else if (strstr(optarg, "PROC") == optarg) { - vars_to_check = PROCS; - process_name = strscpy(process_name, optarg + 4); - sprintf(send_buffer, "PROCESS %s\r\n", process_name); - } else if (strstr(optarg, "NET") == optarg) { - vars_to_check = NETSTAT; - netstat_port = atoi(optarg + 3); - sprintf(send_buffer, "NETSTAT %d\r\n", netstat_port); - } else if (strstr(optarg, "DPU") == optarg) { - vars_to_check = DPU; - strcpy(send_buffer, "DISKSPACE\r\n"); - disk_name = strscpy(disk_name, optarg + 3); - } else - return ERROR; - break; - case 'w': /* warning threshold */ - warning_value = strtoul(optarg, NULL, 10); - check_warning_value = true; - break; - case 'c': /* critical threshold */ - critical_value = strtoul(optarg, NULL, 10); - check_critical_value = true; - break; - case 't': /* timeout */ - socket_timeout = atoi(optarg); - if (socket_timeout <= 0) - return ERROR; - } - } - return OK; -} - -void print_help(void) { - char *myport; - xasprintf(&myport, "%d", PORT); - - print_revision(progname, NP_VERSION); - - printf("Copyright (c) 1999 Ethan Galstad \n"); - printf(COPYRIGHT, copyright, email); - - printf("%s\n", _("This plugin attempts to contact the Over-CR collector daemon running on the")); - printf("%s\n", _("remote UNIX server in order to gather the requested system information.")); - - printf("\n\n"); - - print_usage(); - - printf(UT_HELP_VRSN); - printf(UT_EXTRA_OPTS); - - printf(UT_HOST_PORT, 'p', myport); - - printf(" %s\n", "-w, --warning=INTEGER"); - printf(" %s\n", _("Threshold which will result in a warning status")); - printf(" %s\n", "-c, --critical=INTEGER"); - printf(" %s\n", _("Threshold which will result in a critical status")); - printf(" %s\n", "-v, --variable=STRING"); - printf(" %s\n", _("Variable to check. Valid variables include:")); - printf(" %s\n", _("LOAD1 = 1 minute average CPU load")); - printf(" %s\n", _("LOAD5 = 5 minute average CPU load")); - printf(" %s\n", _("LOAD15 = 15 minute average CPU load")); - printf(" %s\n", _("DPU = percent used disk space on filesystem ")); - printf(" %s\n", _("PROC = number of running processes with name ")); - printf(" %s\n", _("NET = number of active connections on TCP port ")); - printf(" %s\n", _("UPTIME = system uptime in seconds")); - - printf(UT_CONN_TIMEOUT, DEFAULT_SOCKET_TIMEOUT); - - printf(UT_VERBOSE); - - printf("\n"); - printf("%s\n", _("This plugin requires that Eric Molitors' Over-CR collector daemon be")); - printf("%s\n", _("running on the remote server.")); - printf("%s\n", _("Over-CR can be downloaded from http://www.molitor.org/overcr")); - printf("%s\n", _("This plugin was tested with version 0.99.53 of the Over-CR collector")); - - printf("\n"); - printf("%s\n", _("Notes:")); - printf(" %s\n", _("For the available options, the critical threshold value should always be")); - printf(" %s\n", _("higher than the warning threshold value, EXCEPT with the uptime variable")); - - printf(UT_SUPPORT); -} - -void print_usage(void) { - printf("%s\n", _("Usage:")); - printf("%s -H host [-p port] [-v variable] [-w warning] [-c critical] [-t timeout]\n", progname); -} -- cgit v1.2.3-74-g34f1 From 19514d21b90f3ed5e1925fa2a96b3bb9cfc40f02 Mon Sep 17 00:00:00 2001 From: Lorenz Kästle <12514511+RincewindsHat@users.noreply.github.com> Date: Wed, 12 Mar 2025 11:24:53 +0100 Subject: check_ping: clang-format --- plugins/check_ping.c | 138 ++++++++++++++++++++++++++++++++------------------- 1 file changed, 86 insertions(+), 52 deletions(-) diff --git a/plugins/check_ping.c b/plugins/check_ping.c index 4aafaf41..526b8618 100644 --- a/plugins/check_ping.c +++ b/plugins/check_ping.c @@ -89,8 +89,9 @@ int main(int argc, char **argv) { /* Parse extra opts if any */ argv = np_extra_opts(&argc, argv, progname); - if (process_arguments(argc, argv) == ERROR) + if (process_arguments(argc, argv) == ERROR) { usage4(_("Could not parse arguments")); + } /* Set signal handling and alarm */ if (signal(SIGALRM, popen_timeout_alarm_handler) == SIG_ERR) { @@ -108,15 +109,16 @@ int main(int argc, char **argv) { for (i = 0; i < n_addresses; i++) { #ifdef PING6_COMMAND - if (address_family != AF_INET && is_inet6_addr(addresses[i])) + if (address_family != AF_INET && is_inet6_addr(addresses[i])) { rawcmd = strdup(PING6_COMMAND); - else + } else { rawcmd = strdup(PING_COMMAND); + } #else rawcmd = strdup(PING_COMMAND); #endif - /* does the host address of number of packets argument come first? */ + /* does the host address of number of packets argument come first? */ #ifdef PING_PACKETS_FIRST # ifdef PING_HAS_TIMEOUT xasprintf(&cmd, rawcmd, timeout_interval, max_packets, addresses[i]); @@ -127,8 +129,9 @@ int main(int argc, char **argv) { xasprintf(&cmd, rawcmd, addresses[i], max_packets); #endif - if (verbose >= 2) + if (verbose >= 2) { printf("CMD: %s\n", cmd); + } /* run the command */ this_result = run_ping(cmd, addresses[i]); @@ -138,24 +141,29 @@ int main(int argc, char **argv) { die(STATE_UNKNOWN, _("CRITICAL - Could not interpret output from ping command\n")); } - if (pl >= cpl || rta >= crta || rta < 0) + if (pl >= cpl || rta >= crta || rta < 0) { this_result = STATE_CRITICAL; - else if (pl >= wpl || rta >= wrta) + } else if (pl >= wpl || rta >= wrta) { this_result = STATE_WARNING; - else if (pl >= 0 && rta >= 0) + } else if (pl >= 0 && rta >= 0) { this_result = max_state(STATE_OK, this_result); + } - if (n_addresses > 1 && this_result != STATE_UNKNOWN) + if (n_addresses > 1 && this_result != STATE_UNKNOWN) { die(STATE_OK, "%s is alive\n", addresses[i]); + } - if (display_html == true) + if (display_html == true) { printf("", CGIURL, addresses[i]); - if (pl == 100) + } + if (pl == 100) { printf(_("PING %s - %sPacket loss = %d%%"), state_text(this_result), warn_text, pl); - else + } else { printf(_("PING %s - %sPacket loss = %d%%, RTA = %2.2f ms"), state_text(this_result), warn_text, pl, rta); - if (display_html == true) + } + if (display_html == true) { printf(""); + } /* Print performance data */ if (pl != 100) { @@ -166,8 +174,9 @@ int main(int argc, char **argv) { } printf(" %s\n", perfdata("pl", (long)pl, "%", wpl > 0 ? true : false, wpl, cpl > 0 ? true : false, cpl, true, 0, false, 0)); - if (verbose >= 2) + if (verbose >= 2) { printf("%f:%d%% %f:%d%%\n", wrta, wpl, crta, cpl); + } result = max_state(result, this_result); free(rawcmd); @@ -191,21 +200,25 @@ int process_arguments(int argc, char **argv) { {"use-ipv6", no_argument, 0, '6'}, {0, 0, 0, 0}}; - if (argc < 2) + if (argc < 2) { return ERROR; + } for (c = 1; c < argc; c++) { - if (strcmp("-to", argv[c]) == 0) + if (strcmp("-to", argv[c]) == 0) { strcpy(argv[c], "-t"); - if (strcmp("-nohtml", argv[c]) == 0) + } + if (strcmp("-nohtml", argv[c]) == 0) { strcpy(argv[c], "-n"); + } } while (1) { c = getopt_long(argc, argv, "VvhnL46t:c:w:H:p:", longopts, &option); - if (c == -1 || c == EOF) + if (c == -1 || c == EOF) { break; + } switch (c) { case '?': /* usage */ @@ -241,8 +254,9 @@ int process_arguments(int argc, char **argv) { if (n_addresses > max_addr) { max_addr *= 2; addresses = realloc(addresses, sizeof(char *) * max_addr); - if (addresses == NULL) + if (addresses == NULL) { die(STATE_UNKNOWN, _("Could not realloc() addresses\n")); + } } addresses[n_addresses - 1] = ptr; if ((ptr = index(ptr, ','))) { @@ -254,10 +268,11 @@ int process_arguments(int argc, char **argv) { } break; case 'p': /* number of packets to send */ - if (is_intnonneg(optarg)) + if (is_intnonneg(optarg)) { max_packets = atoi(optarg); - else + } else { usage2(_(" (%s) must be a non-negative number\n"), optarg); + } break; case 'n': /* no HTML */ display_html = false; @@ -275,8 +290,9 @@ int process_arguments(int argc, char **argv) { } c = optind; - if (c == argc) + if (c == argc) { return validate_arguments(); + } if (addresses[0] == NULL) { if (!is_host(argv[c])) { @@ -284,8 +300,9 @@ int process_arguments(int argc, char **argv) { } else { addresses[0] = argv[c++]; n_addresses++; - if (c == argc) + if (c == argc) { return validate_arguments(); + } } } @@ -295,8 +312,9 @@ int process_arguments(int argc, char **argv) { return ERROR; } else { wpl = atoi(argv[c++]); - if (c == argc) + if (c == argc) { return validate_arguments(); + } } } @@ -306,8 +324,9 @@ int process_arguments(int argc, char **argv) { return ERROR; } else { cpl = atoi(argv[c++]); - if (c == argc) + if (c == argc) { return validate_arguments(); + } } } @@ -317,8 +336,9 @@ int process_arguments(int argc, char **argv) { return ERROR; } else { wrta = atof(argv[c++]); - if (c == argc) + if (c == argc) { return validate_arguments(); + } } } @@ -328,8 +348,9 @@ int process_arguments(int argc, char **argv) { return ERROR; } else { crta = atof(argv[c++]); - if (c == argc) + if (c == argc) { return validate_arguments(); + } } } @@ -346,12 +367,13 @@ int process_arguments(int argc, char **argv) { } int get_threshold(char *arg, float *trta, int *tpl) { - if (is_intnonneg(arg) && sscanf(arg, "%f", trta) == 1) + if (is_intnonneg(arg) && sscanf(arg, "%f", trta) == 1) { return OK; - else if (strpbrk(arg, ",:") && strstr(arg, "%") && sscanf(arg, "%f%*[:,]%d%%", trta, tpl) == 2) + } else if (strpbrk(arg, ",:") && strstr(arg, "%") && sscanf(arg, "%f%*[:,]%d%%", trta, tpl) == 2) { return OK; - else if (strstr(arg, "%") && sscanf(arg, "%d%%", tpl) == 1) + } else if (strstr(arg, "%") && sscanf(arg, "%d%%", tpl) == 1) { return OK; + } usage2(_("%s: Warning threshold must be integer or percentage!\n\n"), arg); return STATE_UNKNOWN; @@ -381,16 +403,19 @@ int validate_arguments() { return ERROR; } - if (max_packets == -1) + if (max_packets == -1) { max_packets = DEFAULT_MAX_PACKETS; + } max_seconds = crta / 1000.0 * max_packets + max_packets; - if (max_seconds > timeout_interval) + if (max_seconds > timeout_interval) { timeout_interval = (int)max_seconds; + } for (i = 0; i < n_addresses; i++) { - if (!is_host(addresses[i])) + if (!is_host(addresses[i])) { usage2(_("Invalid hostname/address"), addresses[i]); + } } if (n_addresses == 0) { @@ -405,17 +430,20 @@ int run_ping(const char *cmd, const char *addr) { int result = STATE_UNKNOWN; int match; - if ((child_process = spopen(cmd)) == NULL) + if ((child_process = spopen(cmd)) == NULL) { die(STATE_UNKNOWN, _("Could not open pipe: %s\n"), cmd); + } child_stderr = fdopen(child_stderr_array[fileno(child_process)], "r"); - if (child_stderr == NULL) + if (child_stderr == NULL) { printf(_("Cannot open stderr for %s\n"), cmd); + } while (fgets(buf, MAX_INPUT_BUFFER - 1, child_process)) { - if (verbose >= 3) + if (verbose >= 3) { printf("Output: %s", buf); + } result = max_state(result, error_scan(buf, addr)); @@ -430,8 +458,9 @@ int run_ping(const char *cmd, const char *addr) { (sscanf(buf, "%*d packets transmitted, %*d received, %d%% packet loss, time%n", &pl, &match) && match) || (sscanf(buf, "%*d packets transmitted, %*d received, +%*d errors, %d%% packet loss%n", &pl, &match) && match) || (sscanf(buf, "%*d packets transmitted %*d received, +%*d errors, %d%% packet loss%n", &pl, &match) && match) || - (sscanf(buf, "%*[^(](%d%% %*[^)])%n", &pl, &match) && match)) + (sscanf(buf, "%*[^(](%d%% %*[^)])%n", &pl, &match) && match)) { continue; + } /* get the round trip average */ else if ((sscanf(buf, "round-trip min/avg/max = %*f/%f/%*f%n", &rta, &match) && match) || @@ -442,13 +471,15 @@ int run_ping(const char *cmd, const char *addr) { (sscanf(buf, "round-trip (ms) min/avg/max = %*f/%f/%*f%n", &rta, &match) && match) || (sscanf(buf, "round-trip (ms) min/avg/max/stddev = %*f/%f/%*f/%*f%n", &rta, &match) && match) || (sscanf(buf, "rtt min/avg/max/mdev = %*f/%f/%*f/%*f ms%n", &rta, &match) && match) || - (sscanf(buf, "%*[^=] = %*fms, %*[^=] = %*fms, %*[^=] = %fms%n", &rta, &match) && match)) + (sscanf(buf, "%*[^=] = %*fms, %*[^=] = %*fms, %*[^=] = %fms%n", &rta, &match) && match)) { continue; + } } /* this is needed because there is no rta if all packets are lost */ - if (pl == 100) + if (pl == 100) { rta = crta; + } /* check stderr, setting at least WARNING if there is output here */ /* Add warning into warn_text */ @@ -474,39 +505,42 @@ int run_ping(const char *cmd, const char *addr) { spclose(child_process); - if (warn_text == NULL) + if (warn_text == NULL) { warn_text = strdup(""); + } return result; } int error_scan(char buf[MAX_INPUT_BUFFER], const char *addr) { - if (strstr(buf, "Network is unreachable") || strstr(buf, "Destination Net Unreachable") || strstr(buf, "No route")) + if (strstr(buf, "Network is unreachable") || strstr(buf, "Destination Net Unreachable") || strstr(buf, "No route")) { die(STATE_CRITICAL, _("CRITICAL - Network Unreachable (%s)\n"), addr); - else if (strstr(buf, "Destination Host Unreachable") || strstr(buf, "Address unreachable")) + } else if (strstr(buf, "Destination Host Unreachable") || strstr(buf, "Address unreachable")) { die(STATE_CRITICAL, _("CRITICAL - Host Unreachable (%s)\n"), addr); - else if (strstr(buf, "Destination Port Unreachable") || strstr(buf, "Port unreachable")) + } else if (strstr(buf, "Destination Port Unreachable") || strstr(buf, "Port unreachable")) { die(STATE_CRITICAL, _("CRITICAL - Bogus ICMP: Port Unreachable (%s)\n"), addr); - else if (strstr(buf, "Destination Protocol Unreachable")) + } else if (strstr(buf, "Destination Protocol Unreachable")) { die(STATE_CRITICAL, _("CRITICAL - Bogus ICMP: Protocol Unreachable (%s)\n"), addr); - else if (strstr(buf, "Destination Net Prohibited")) + } else if (strstr(buf, "Destination Net Prohibited")) { die(STATE_CRITICAL, _("CRITICAL - Network Prohibited (%s)\n"), addr); - else if (strstr(buf, "Destination Host Prohibited")) + } else if (strstr(buf, "Destination Host Prohibited")) { die(STATE_CRITICAL, _("CRITICAL - Host Prohibited (%s)\n"), addr); - else if (strstr(buf, "Packet filtered") || strstr(buf, "Administratively prohibited")) + } else if (strstr(buf, "Packet filtered") || strstr(buf, "Administratively prohibited")) { die(STATE_CRITICAL, _("CRITICAL - Packet Filtered (%s)\n"), addr); - else if (strstr(buf, "unknown host")) + } else if (strstr(buf, "unknown host")) { die(STATE_CRITICAL, _("CRITICAL - Host not found (%s)\n"), addr); - else if (strstr(buf, "Time to live exceeded") || strstr(buf, "Time exceeded")) + } else if (strstr(buf, "Time to live exceeded") || strstr(buf, "Time exceeded")) { die(STATE_CRITICAL, _("CRITICAL - Time to live exceeded (%s)\n"), addr); - else if (strstr(buf, "Destination unreachable: ")) + } else if (strstr(buf, "Destination unreachable: ")) { die(STATE_CRITICAL, _("CRITICAL - Destination Unreachable (%s)\n"), addr); + } if (strstr(buf, "(DUP!)") || strstr(buf, "DUPLICATES FOUND")) { - if (warn_text == NULL) + if (warn_text == NULL) { warn_text = strdup(_(WARN_DUPLICATES)); - else if (!strstr(warn_text, _(WARN_DUPLICATES)) && xasprintf(&warn_text, "%s %s", warn_text, _(WARN_DUPLICATES)) == -1) + } else if (!strstr(warn_text, _(WARN_DUPLICATES)) && xasprintf(&warn_text, "%s %s", warn_text, _(WARN_DUPLICATES)) == -1) { die(STATE_UNKNOWN, _("Unable to realloc warn_text\n")); + } return (STATE_WARNING); } -- cgit v1.2.3-74-g34f1 From 29c0998cdf0fdb00685df305c0d9e6fcd90eadd6 Mon Sep 17 00:00:00 2001 From: Lorenz Kästle <12514511+RincewindsHat@users.noreply.github.com> Date: Wed, 12 Mar 2025 11:57:34 +0100 Subject: check_ping: general refactoring --- plugins/check_ping.c | 236 ++++++++++++++++++++++++++------------------------- 1 file changed, 119 insertions(+), 117 deletions(-) diff --git a/plugins/check_ping.c b/plugins/check_ping.c index 526b8618..d79a4a61 100644 --- a/plugins/check_ping.c +++ b/plugins/check_ping.c @@ -66,18 +66,12 @@ static int max_addr = 1; static int max_packets = -1; static int verbose = 0; -static float rta = UNKNOWN_TRIP_TIME; -static int pl = UNKNOWN_PACKET_LOSS; +static float round_trip_average = UNKNOWN_TRIP_TIME; +static int packet_loss = UNKNOWN_PACKET_LOSS; static char *warn_text; int main(int argc, char **argv) { - char *cmd = NULL; - char *rawcmd = NULL; - int result = STATE_UNKNOWN; - int this_result = STATE_UNKNOWN; - int i; - setlocale(LC_ALL, ""); setlocale(LC_NUMERIC, "C"); bindtextdomain(PACKAGE, LOCALEDIR); @@ -106,8 +100,9 @@ int main(int argc, char **argv) { alarm(timeout_interval); #endif - for (i = 0; i < n_addresses; i++) { - + int result = STATE_UNKNOWN; + char *rawcmd = NULL; + for (int i = 0; i < n_addresses; i++) { #ifdef PING6_COMMAND if (address_family != AF_INET && is_inet6_addr(addresses[i])) { rawcmd = strdup(PING6_COMMAND); @@ -118,6 +113,8 @@ int main(int argc, char **argv) { rawcmd = strdup(PING_COMMAND); #endif + char *cmd = NULL; + /* does the host address of number of packets argument come first? */ #ifdef PING_PACKETS_FIRST # ifdef PING_HAS_TIMEOUT @@ -134,18 +131,18 @@ int main(int argc, char **argv) { } /* run the command */ - this_result = run_ping(cmd, addresses[i]); + int this_result = run_ping(cmd, addresses[i]); - if (pl == UNKNOWN_PACKET_LOSS || rta < 0.0) { + if (packet_loss == UNKNOWN_PACKET_LOSS || round_trip_average < 0.0) { printf("%s\n", cmd); die(STATE_UNKNOWN, _("CRITICAL - Could not interpret output from ping command\n")); } - if (pl >= cpl || rta >= crta || rta < 0) { + if (packet_loss >= cpl || round_trip_average >= crta || round_trip_average < 0) { this_result = STATE_CRITICAL; - } else if (pl >= wpl || rta >= wrta) { + } else if (packet_loss >= wpl || round_trip_average >= wrta) { this_result = STATE_WARNING; - } else if (pl >= 0 && rta >= 0) { + } else if (packet_loss >= 0 && round_trip_average >= 0) { this_result = max_state(STATE_OK, this_result); } @@ -153,26 +150,28 @@ int main(int argc, char **argv) { die(STATE_OK, "%s is alive\n", addresses[i]); } - if (display_html == true) { + if (display_html) { printf("", CGIURL, addresses[i]); } - if (pl == 100) { - printf(_("PING %s - %sPacket loss = %d%%"), state_text(this_result), warn_text, pl); + if (packet_loss == 100) { + printf(_("PING %s - %sPacket loss = %d%%"), state_text(this_result), warn_text, packet_loss); } else { - printf(_("PING %s - %sPacket loss = %d%%, RTA = %2.2f ms"), state_text(this_result), warn_text, pl, rta); + printf(_("PING %s - %sPacket loss = %d%%, RTA = %2.2f ms"), state_text(this_result), warn_text, packet_loss, + round_trip_average); } - if (display_html == true) { + if (display_html) { printf(""); } /* Print performance data */ - if (pl != 100) { + if (packet_loss != 100) { printf("|%s", - fperfdata("rta", (double)rta, "ms", wrta > 0 ? true : false, wrta, crta > 0 ? true : false, crta, true, 0, false, 0)); + fperfdata("rta", (double)round_trip_average, "ms", (bool)(wrta > 0), wrta, (bool)(crta > 0), crta, true, 0, false, 0)); } else { printf("| rta=U;%f;%f;;", wrta, crta); } - printf(" %s\n", perfdata("pl", (long)pl, "%", wpl > 0 ? true : false, wpl, cpl > 0 ? true : false, cpl, true, 0, false, 0)); + + printf(" %s\n", perfdata("pl", (long)packet_loss, "%", (bool)(wpl > 0), wpl, (bool)(cpl > 0), cpl, true, 0, false, 0)); if (verbose >= 2) { printf("%f:%d%% %f:%d%%\n", wrta, wpl, crta, cpl); @@ -188,10 +187,6 @@ int main(int argc, char **argv) { /* process command-line arguments */ int process_arguments(int argc, char **argv) { - int c = 1; - char *ptr; - - int option = 0; static struct option longopts[] = {STD_LONG_OPTS, {"packets", required_argument, 0, 'p'}, {"nohtml", no_argument, 0, 'n'}, @@ -204,23 +199,24 @@ int process_arguments(int argc, char **argv) { return ERROR; } - for (c = 1; c < argc; c++) { - if (strcmp("-to", argv[c]) == 0) { - strcpy(argv[c], "-t"); + for (int index = 1; index < argc; index++) { + if (strcmp("-to", argv[index]) == 0) { + strcpy(argv[index], "-t"); } - if (strcmp("-nohtml", argv[c]) == 0) { - strcpy(argv[c], "-n"); + if (strcmp("-nohtml", argv[index]) == 0) { + strcpy(argv[index], "-n"); } } - while (1) { - c = getopt_long(argc, argv, "VvhnL46t:c:w:H:p:", longopts, &option); + int option = 0; + while (true) { + int option_index = getopt_long(argc, argv, "VvhnL46t:c:w:H:p:", longopts, &option); - if (c == -1 || c == EOF) { + if (option_index == -1 || option_index == EOF) { break; } - switch (c) { + switch (option_index) { case '?': /* usage */ usage5(); case 'h': /* help */ @@ -247,9 +243,9 @@ int process_arguments(int argc, char **argv) { usage(_("IPv6 support not available\n")); #endif break; - case 'H': /* hostname */ - ptr = optarg; - while (1) { + case 'H': /* hostname */ { + char *ptr = optarg; + while (true) { n_addresses++; if (n_addresses > max_addr) { max_addr *= 2; @@ -266,7 +262,7 @@ int process_arguments(int argc, char **argv) { break; } } - break; + } break; case 'p': /* number of packets to send */ if (is_intnonneg(optarg)) { max_packets = atoi(optarg); @@ -289,76 +285,72 @@ int process_arguments(int argc, char **argv) { } } - c = optind; - if (c == argc) { + int arg_counter = optind; + if (arg_counter == argc) { return validate_arguments(); } if (addresses[0] == NULL) { - if (!is_host(argv[c])) { - usage2(_("Invalid hostname/address"), argv[c]); + if (!is_host(argv[arg_counter])) { + usage2(_("Invalid hostname/address"), argv[arg_counter]); } else { - addresses[0] = argv[c++]; + addresses[0] = argv[arg_counter++]; n_addresses++; - if (c == argc) { + if (arg_counter == argc) { return validate_arguments(); } } } if (wpl == UNKNOWN_PACKET_LOSS) { - if (!is_intpercent(argv[c])) { - printf(_(" (%s) must be an integer percentage\n"), argv[c]); + if (!is_intpercent(argv[arg_counter])) { + printf(_(" (%s) must be an integer percentage\n"), argv[arg_counter]); return ERROR; - } else { - wpl = atoi(argv[c++]); - if (c == argc) { - return validate_arguments(); - } + } + wpl = atoi(argv[arg_counter++]); + if (arg_counter == argc) { + return validate_arguments(); } } if (cpl == UNKNOWN_PACKET_LOSS) { - if (!is_intpercent(argv[c])) { - printf(_(" (%s) must be an integer percentage\n"), argv[c]); + if (!is_intpercent(argv[arg_counter])) { + printf(_(" (%s) must be an integer percentage\n"), argv[arg_counter]); return ERROR; - } else { - cpl = atoi(argv[c++]); - if (c == argc) { - return validate_arguments(); - } + } + cpl = atoi(argv[arg_counter++]); + if (arg_counter == argc) { + return validate_arguments(); } } if (wrta < 0.0) { - if (is_negative(argv[c])) { - printf(_(" (%s) must be a non-negative number\n"), argv[c]); + if (is_negative(argv[arg_counter])) { + printf(_(" (%s) must be a non-negative number\n"), argv[arg_counter]); return ERROR; - } else { - wrta = atof(argv[c++]); - if (c == argc) { - return validate_arguments(); - } + } + wrta = atof(argv[arg_counter++]); + if (arg_counter == argc) { + return validate_arguments(); } } if (crta < 0.0) { - if (is_negative(argv[c])) { - printf(_(" (%s) must be a non-negative number\n"), argv[c]); + if (is_negative(argv[arg_counter])) { + printf(_(" (%s) must be a non-negative number\n"), argv[arg_counter]); return ERROR; - } else { - crta = atof(argv[c++]); - if (c == argc) { - return validate_arguments(); - } + } + crta = atof(argv[arg_counter++]); + if (arg_counter == argc) { + return validate_arguments(); } } if (max_packets == -1) { - if (is_intnonneg(argv[c])) { - max_packets = atoi(argv[c++]); + if (is_intnonneg(argv[arg_counter])) { + max_packets = atoi(argv[arg_counter++]); } else { - printf(_(" (%s) must be a non-negative number\n"), argv[c]); + printf(_(" (%s) must be a non-negative number\n"), argv[arg_counter]); return ERROR; } } @@ -369,9 +361,13 @@ int process_arguments(int argc, char **argv) { int get_threshold(char *arg, float *trta, int *tpl) { if (is_intnonneg(arg) && sscanf(arg, "%f", trta) == 1) { return OK; - } else if (strpbrk(arg, ",:") && strstr(arg, "%") && sscanf(arg, "%f%*[:,]%d%%", trta, tpl) == 2) { + } + + if (strpbrk(arg, ",:") && strstr(arg, "%") && sscanf(arg, "%f%*[:,]%d%%", trta, tpl) == 2) { return OK; - } else if (strstr(arg, "%") && sscanf(arg, "%d%%", tpl) == 1) { + } + + if (strstr(arg, "%") && sscanf(arg, "%d%%", tpl) == 1) { return OK; } @@ -380,25 +376,32 @@ int get_threshold(char *arg, float *trta, int *tpl) { } int validate_arguments() { - float max_seconds; - int i; - if (wrta < 0.0) { printf(_(" was not set\n")); return ERROR; - } else if (crta < 0.0) { + } + + if (crta < 0.0) { printf(_(" was not set\n")); return ERROR; - } else if (wpl == UNKNOWN_PACKET_LOSS) { + } + + if (wpl == UNKNOWN_PACKET_LOSS) { printf(_(" was not set\n")); return ERROR; - } else if (cpl == UNKNOWN_PACKET_LOSS) { + } + + if (cpl == UNKNOWN_PACKET_LOSS) { printf(_(" was not set\n")); return ERROR; - } else if (wrta > crta) { + } + + if (wrta > crta) { printf(_(" (%f) cannot be larger than (%f)\n"), wrta, crta); return ERROR; - } else if (wpl > cpl) { + } + + if (wpl > cpl) { printf(_(" (%d) cannot be larger than (%d)\n"), wpl, cpl); return ERROR; } @@ -407,12 +410,12 @@ int validate_arguments() { max_packets = DEFAULT_MAX_PACKETS; } - max_seconds = crta / 1000.0 * max_packets + max_packets; + float max_seconds = (crta / 1000.0 * max_packets) + max_packets; if (max_seconds > timeout_interval) { - timeout_interval = (int)max_seconds; + timeout_interval = (unsigned int)max_seconds; } - for (i = 0; i < n_addresses; i++) { + for (int i = 0; i < n_addresses; i++) { if (!is_host(addresses[i])) { usage2(_("Invalid hostname/address"), addresses[i]); } @@ -426,10 +429,6 @@ int validate_arguments() { } int run_ping(const char *cmd, const char *addr) { - char buf[MAX_INPUT_BUFFER]; - int result = STATE_UNKNOWN; - int match; - if ((child_process = spopen(cmd)) == NULL) { die(STATE_UNKNOWN, _("Could not open pipe: %s\n"), cmd); } @@ -439,8 +438,9 @@ int run_ping(const char *cmd, const char *addr) { printf(_("Cannot open stderr for %s\n"), cmd); } + char buf[MAX_INPUT_BUFFER]; + int result = STATE_UNKNOWN; while (fgets(buf, MAX_INPUT_BUFFER - 1, child_process)) { - if (verbose >= 3) { printf("Output: %s", buf); } @@ -448,37 +448,39 @@ int run_ping(const char *cmd, const char *addr) { result = max_state(result, error_scan(buf, addr)); /* get the percent loss statistics */ - match = 0; - if ((sscanf(buf, "%*d packets transmitted, %*d packets received, +%*d errors, %d%% packet loss%n", &pl, &match) && match) || - (sscanf(buf, "%*d packets transmitted, %*d packets received, +%*d duplicates, %d%% packet loss%n", &pl, &match) && match) || - (sscanf(buf, "%*d packets transmitted, %*d received, +%*d duplicates, %d%% packet loss%n", &pl, &match) && match) || - (sscanf(buf, "%*d packets transmitted, %*d packets received, %d%% packet loss%n", &pl, &match) && match) || - (sscanf(buf, "%*d packets transmitted, %*d packets received, %d%% loss, time%n", &pl, &match) && match) || - (sscanf(buf, "%*d packets transmitted, %*d received, %d%% loss, time%n", &pl, &match) && match) || - (sscanf(buf, "%*d packets transmitted, %*d received, %d%% packet loss, time%n", &pl, &match) && match) || - (sscanf(buf, "%*d packets transmitted, %*d received, +%*d errors, %d%% packet loss%n", &pl, &match) && match) || - (sscanf(buf, "%*d packets transmitted %*d received, +%*d errors, %d%% packet loss%n", &pl, &match) && match) || - (sscanf(buf, "%*[^(](%d%% %*[^)])%n", &pl, &match) && match)) { + int match = 0; + if ((sscanf(buf, "%*d packets transmitted, %*d packets received, +%*d errors, %d%% packet loss%n", &packet_loss, &match) && + match) || + (sscanf(buf, "%*d packets transmitted, %*d packets received, +%*d duplicates, %d%% packet loss%n", &packet_loss, &match) && + match) || + (sscanf(buf, "%*d packets transmitted, %*d received, +%*d duplicates, %d%% packet loss%n", &packet_loss, &match) && match) || + (sscanf(buf, "%*d packets transmitted, %*d packets received, %d%% packet loss%n", &packet_loss, &match) && match) || + (sscanf(buf, "%*d packets transmitted, %*d packets received, %d%% loss, time%n", &packet_loss, &match) && match) || + (sscanf(buf, "%*d packets transmitted, %*d received, %d%% loss, time%n", &packet_loss, &match) && match) || + (sscanf(buf, "%*d packets transmitted, %*d received, %d%% packet loss, time%n", &packet_loss, &match) && match) || + (sscanf(buf, "%*d packets transmitted, %*d received, +%*d errors, %d%% packet loss%n", &packet_loss, &match) && match) || + (sscanf(buf, "%*d packets transmitted %*d received, +%*d errors, %d%% packet loss%n", &packet_loss, &match) && match) || + (sscanf(buf, "%*[^(](%d%% %*[^)])%n", &packet_loss, &match) && match)) { continue; } /* get the round trip average */ - else if ((sscanf(buf, "round-trip min/avg/max = %*f/%f/%*f%n", &rta, &match) && match) || - (sscanf(buf, "round-trip min/avg/max/mdev = %*f/%f/%*f/%*f%n", &rta, &match) && match) || - (sscanf(buf, "round-trip min/avg/max/sdev = %*f/%f/%*f/%*f%n", &rta, &match) && match) || - (sscanf(buf, "round-trip min/avg/max/stddev = %*f/%f/%*f/%*f%n", &rta, &match) && match) || - (sscanf(buf, "round-trip min/avg/max/std-dev = %*f/%f/%*f/%*f%n", &rta, &match) && match) || - (sscanf(buf, "round-trip (ms) min/avg/max = %*f/%f/%*f%n", &rta, &match) && match) || - (sscanf(buf, "round-trip (ms) min/avg/max/stddev = %*f/%f/%*f/%*f%n", &rta, &match) && match) || - (sscanf(buf, "rtt min/avg/max/mdev = %*f/%f/%*f/%*f ms%n", &rta, &match) && match) || - (sscanf(buf, "%*[^=] = %*fms, %*[^=] = %*fms, %*[^=] = %fms%n", &rta, &match) && match)) { + if ((sscanf(buf, "round-trip min/avg/max = %*f/%f/%*f%n", &round_trip_average, &match) && match) || + (sscanf(buf, "round-trip min/avg/max/mdev = %*f/%f/%*f/%*f%n", &round_trip_average, &match) && match) || + (sscanf(buf, "round-trip min/avg/max/sdev = %*f/%f/%*f/%*f%n", &round_trip_average, &match) && match) || + (sscanf(buf, "round-trip min/avg/max/stddev = %*f/%f/%*f/%*f%n", &round_trip_average, &match) && match) || + (sscanf(buf, "round-trip min/avg/max/std-dev = %*f/%f/%*f/%*f%n", &round_trip_average, &match) && match) || + (sscanf(buf, "round-trip (ms) min/avg/max = %*f/%f/%*f%n", &round_trip_average, &match) && match) || + (sscanf(buf, "round-trip (ms) min/avg/max/stddev = %*f/%f/%*f/%*f%n", &round_trip_average, &match) && match) || + (sscanf(buf, "rtt min/avg/max/mdev = %*f/%f/%*f/%*f ms%n", &round_trip_average, &match) && match) || + (sscanf(buf, "%*[^=] = %*fms, %*[^=] = %*fms, %*[^=] = %fms%n", &round_trip_average, &match) && match)) { continue; } } /* this is needed because there is no rta if all packets are lost */ - if (pl == 100) { - rta = crta; + if (packet_loss == 100) { + round_trip_average = crta; } /* check stderr, setting at least WARNING if there is output here */ -- cgit v1.2.3-74-g34f1 From ae60d6d8d818191afba08819c5a62673b98ef29a Mon Sep 17 00:00:00 2001 From: Lorenz Kästle <12514511+RincewindsHat@users.noreply.github.com> Date: Wed, 12 Mar 2025 13:03:17 +0100 Subject: Refactor check_ping --- plugins/Makefile.am | 1 + plugins/check_ping.c | 319 ++++++++++++++++++++++-------------------- plugins/check_ping.d/config.h | 46 ++++++ 3 files changed, 218 insertions(+), 148 deletions(-) create mode 100644 plugins/check_ping.d/config.h diff --git a/plugins/Makefile.am b/plugins/Makefile.am index 9ea6e85e..10a12168 100644 --- a/plugins/Makefile.am +++ b/plugins/Makefile.am @@ -63,6 +63,7 @@ EXTRA_DIST = t \ check_mrtg.d \ check_apt.d \ check_pgsql.d \ + check_ping.d \ check_by_ssh.d \ check_smtp.d \ check_mysql.d \ diff --git a/plugins/check_ping.c b/plugins/check_ping.c index d79a4a61..fcf68f81 100644 --- a/plugins/check_ping.c +++ b/plugins/check_ping.c @@ -36,39 +36,35 @@ const char *email = "devel@monitoring-plugins.org"; #include "netutils.h" #include "popen.h" #include "utils.h" +#include "check_ping.d/config.h" +#include "../lib/states.h" #include -#define WARN_DUPLICATES "DUPLICATES FOUND! " -#define UNKNOWN_TRIP_TIME -1.0 /* -1 seconds */ +#define WARN_DUPLICATES "DUPLICATES FOUND! " -enum { - UNKNOWN_PACKET_LOSS = 200, /* 200% */ - DEFAULT_MAX_PACKETS = 5 /* default no. of ICMP ECHO packets */ -}; +typedef struct { + int errorcode; + check_ping_config config; +} check_ping_config_wrapper; +static check_ping_config_wrapper process_arguments(int /*argc*/, char ** /*argv*/); +static check_ping_config_wrapper validate_arguments(check_ping_config_wrapper /*config_wrapper*/); -static int process_arguments(int /*argc*/, char ** /*argv*/); -static int get_threshold(char * /*arg*/, float * /*trta*/, int * /*tpl*/); -static int validate_arguments(void); -static int run_ping(const char *cmd, const char *addr); -static int error_scan(char buf[MAX_INPUT_BUFFER], const char *addr); +static int get_threshold(char * /*arg*/, double * /*trta*/, int * /*tpl*/); + +typedef struct { + mp_state_enum state; + double round_trip_average; + int packet_loss; +} ping_result; +static ping_result run_ping(const char *cmd, const char *addr, double /*crta*/); + +static mp_state_enum error_scan(char buf[MAX_INPUT_BUFFER], const char *addr); static void print_help(void); void print_usage(void); -static bool display_html = false; -static int wpl = UNKNOWN_PACKET_LOSS; -static int cpl = UNKNOWN_PACKET_LOSS; -static float wrta = UNKNOWN_TRIP_TIME; -static float crta = UNKNOWN_TRIP_TIME; -static char **addresses = NULL; -static int n_addresses = 0; -static int max_addr = 1; -static int max_packets = -1; static int verbose = 0; -static float round_trip_average = UNKNOWN_TRIP_TIME; -static int packet_loss = UNKNOWN_PACKET_LOSS; - static char *warn_text; int main(int argc, char **argv) { @@ -77,16 +73,16 @@ int main(int argc, char **argv) { bindtextdomain(PACKAGE, LOCALEDIR); textdomain(PACKAGE); - addresses = malloc(sizeof(char *) * max_addr); - addresses[0] = NULL; - /* Parse extra opts if any */ argv = np_extra_opts(&argc, argv, progname); - if (process_arguments(argc, argv) == ERROR) { + check_ping_config_wrapper tmp_config = process_arguments(argc, argv); + if (tmp_config.errorcode == ERROR) { usage4(_("Could not parse arguments")); } + const check_ping_config config = tmp_config.config; + /* Set signal handling and alarm */ if (signal(SIGALRM, popen_timeout_alarm_handler) == SIG_ERR) { usage4(_("Cannot catch SIGALRM")); @@ -102,9 +98,9 @@ int main(int argc, char **argv) { int result = STATE_UNKNOWN; char *rawcmd = NULL; - for (int i = 0; i < n_addresses; i++) { + for (size_t i = 0; i < config.n_addresses; i++) { #ifdef PING6_COMMAND - if (address_family != AF_INET && is_inet6_addr(addresses[i])) { + if (address_family != AF_INET && is_inet6_addr(config.addresses[i])) { rawcmd = strdup(PING6_COMMAND); } else { rawcmd = strdup(PING_COMMAND); @@ -118,12 +114,12 @@ int main(int argc, char **argv) { /* does the host address of number of packets argument come first? */ #ifdef PING_PACKETS_FIRST # ifdef PING_HAS_TIMEOUT - xasprintf(&cmd, rawcmd, timeout_interval, max_packets, addresses[i]); + xasprintf(&cmd, rawcmd, timeout_interval, config.max_packets, config.addresses[i]); # else - xasprintf(&cmd, rawcmd, max_packets, addresses[i]); + xasprintf(&cmd, rawcmd, config.max_packets, addresses[i]); # endif #else - xasprintf(&cmd, rawcmd, addresses[i], max_packets); + xasprintf(&cmd, rawcmd, addresses[i], config.max_packets); #endif if (verbose >= 2) { @@ -131,53 +127,55 @@ int main(int argc, char **argv) { } /* run the command */ - int this_result = run_ping(cmd, addresses[i]); - if (packet_loss == UNKNOWN_PACKET_LOSS || round_trip_average < 0.0) { + ping_result pinged = run_ping(cmd, config.addresses[i], config.crta); + + if (pinged.packet_loss == UNKNOWN_PACKET_LOSS || pinged.round_trip_average < 0.0) { printf("%s\n", cmd); die(STATE_UNKNOWN, _("CRITICAL - Could not interpret output from ping command\n")); } - if (packet_loss >= cpl || round_trip_average >= crta || round_trip_average < 0) { - this_result = STATE_CRITICAL; - } else if (packet_loss >= wpl || round_trip_average >= wrta) { - this_result = STATE_WARNING; - } else if (packet_loss >= 0 && round_trip_average >= 0) { - this_result = max_state(STATE_OK, this_result); + if (pinged.packet_loss >= config.cpl || pinged.round_trip_average >= config.crta || pinged.round_trip_average < 0) { + pinged.state = STATE_CRITICAL; + } else if (pinged.packet_loss >= config.wpl || pinged.round_trip_average >= config.wrta) { + pinged.state = STATE_WARNING; + } else if (pinged.packet_loss >= 0 && pinged.round_trip_average >= 0) { + pinged.state = max_state(STATE_OK, pinged.state); } - if (n_addresses > 1 && this_result != STATE_UNKNOWN) { - die(STATE_OK, "%s is alive\n", addresses[i]); + if (config.n_addresses > 1 && pinged.state != STATE_UNKNOWN) { + die(STATE_OK, "%s is alive\n", config.addresses[i]); } - if (display_html) { - printf("", CGIURL, addresses[i]); + if (config.display_html) { + printf("", CGIURL, config.addresses[i]); } - if (packet_loss == 100) { - printf(_("PING %s - %sPacket loss = %d%%"), state_text(this_result), warn_text, packet_loss); + if (pinged.packet_loss == 100) { + printf(_("PING %s - %sPacket loss = %d%%"), state_text(pinged.state), warn_text, pinged.packet_loss); } else { - printf(_("PING %s - %sPacket loss = %d%%, RTA = %2.2f ms"), state_text(this_result), warn_text, packet_loss, - round_trip_average); + printf(_("PING %s - %sPacket loss = %d%%, RTA = %2.2f ms"), state_text(pinged.state), warn_text, pinged.packet_loss, + pinged.round_trip_average); } - if (display_html) { + if (config.display_html) { printf(""); } /* Print performance data */ - if (packet_loss != 100) { - printf("|%s", - fperfdata("rta", (double)round_trip_average, "ms", (bool)(wrta > 0), wrta, (bool)(crta > 0), crta, true, 0, false, 0)); + if (pinged.packet_loss != 100) { + printf("|%s", fperfdata("rta", pinged.round_trip_average, "ms", (bool)(config.wrta > 0), config.wrta, + (bool)(config.crta > 0), config.crta, true, 0, false, 0)); } else { - printf("| rta=U;%f;%f;;", wrta, crta); + printf("| rta=U;%f;%f;;", config.wrta, config.crta); } - printf(" %s\n", perfdata("pl", (long)packet_loss, "%", (bool)(wpl > 0), wpl, (bool)(cpl > 0), cpl, true, 0, false, 0)); + printf(" %s\n", perfdata("pl", (long)pinged.packet_loss, "%", (bool)(config.wpl > 0), config.wpl, (bool)(config.cpl > 0), + config.cpl, true, 0, false, 0)); if (verbose >= 2) { - printf("%f:%d%% %f:%d%%\n", wrta, wpl, crta, cpl); + printf("%f:%d%% %f:%d%%\n", config.wrta, config.wpl, config.crta, config.cpl); } - result = max_state(result, this_result); + result = max_state(result, pinged.state); free(rawcmd); free(cmd); } @@ -186,7 +184,7 @@ int main(int argc, char **argv) { } /* process command-line arguments */ -int process_arguments(int argc, char **argv) { +check_ping_config_wrapper process_arguments(int argc, char **argv) { static struct option longopts[] = {STD_LONG_OPTS, {"packets", required_argument, 0, 'p'}, {"nohtml", no_argument, 0, 'n'}, @@ -195,8 +193,14 @@ int process_arguments(int argc, char **argv) { {"use-ipv6", no_argument, 0, '6'}, {0, 0, 0, 0}}; + check_ping_config_wrapper result = { + .errorcode = OK, + .config = check_ping_config_init(), + }; + if (argc < 2) { - return ERROR; + result.errorcode = ERROR; + return result; } for (int index = 1; index < argc; index++) { @@ -209,6 +213,7 @@ int process_arguments(int argc, char **argv) { } int option = 0; + size_t max_addr = MAX_ADDR_START; while (true) { int option_index = getopt_long(argc, argv, "VvhnL46t:c:w:H:p:", longopts, &option); @@ -246,15 +251,15 @@ int process_arguments(int argc, char **argv) { case 'H': /* hostname */ { char *ptr = optarg; while (true) { - n_addresses++; - if (n_addresses > max_addr) { + result.config.n_addresses++; + if (result.config.n_addresses > max_addr) { max_addr *= 2; - addresses = realloc(addresses, sizeof(char *) * max_addr); - if (addresses == NULL) { + result.config.addresses = realloc(result.config.addresses, sizeof(char *) * max_addr); + if (result.config.addresses == NULL) { die(STATE_UNKNOWN, _("Could not realloc() addresses\n")); } } - addresses[n_addresses - 1] = ptr; + result.config.addresses[result.config.n_addresses - 1] = ptr; if ((ptr = index(ptr, ','))) { strcpy(ptr, ""); ptr += sizeof(char); @@ -265,105 +270,110 @@ int process_arguments(int argc, char **argv) { } break; case 'p': /* number of packets to send */ if (is_intnonneg(optarg)) { - max_packets = atoi(optarg); + result.config.max_packets = atoi(optarg); } else { usage2(_(" (%s) must be a non-negative number\n"), optarg); } break; case 'n': /* no HTML */ - display_html = false; + result.config.display_html = false; break; case 'L': /* show HTML */ - display_html = true; + result.config.display_html = true; break; case 'c': - get_threshold(optarg, &crta, &cpl); + get_threshold(optarg, &result.config.crta, &result.config.cpl); break; case 'w': - get_threshold(optarg, &wrta, &wpl); + get_threshold(optarg, &result.config.wrta, &result.config.wpl); break; } } int arg_counter = optind; if (arg_counter == argc) { - return validate_arguments(); + return validate_arguments(result); } - if (addresses[0] == NULL) { + if (result.config.addresses[0] == NULL) { if (!is_host(argv[arg_counter])) { usage2(_("Invalid hostname/address"), argv[arg_counter]); } else { - addresses[0] = argv[arg_counter++]; - n_addresses++; + result.config.addresses[0] = argv[arg_counter++]; + result.config.n_addresses++; if (arg_counter == argc) { - return validate_arguments(); + return validate_arguments(result); } } } - if (wpl == UNKNOWN_PACKET_LOSS) { + if (result.config.wpl == UNKNOWN_PACKET_LOSS) { if (!is_intpercent(argv[arg_counter])) { printf(_(" (%s) must be an integer percentage\n"), argv[arg_counter]); - return ERROR; + result.errorcode = ERROR; + return result; } - wpl = atoi(argv[arg_counter++]); + result.config.wpl = atoi(argv[arg_counter++]); if (arg_counter == argc) { - return validate_arguments(); + return validate_arguments(result); } } - if (cpl == UNKNOWN_PACKET_LOSS) { + if (result.config.cpl == UNKNOWN_PACKET_LOSS) { if (!is_intpercent(argv[arg_counter])) { printf(_(" (%s) must be an integer percentage\n"), argv[arg_counter]); - return ERROR; + result.errorcode = ERROR; + return result; } - cpl = atoi(argv[arg_counter++]); + result.config.cpl = atoi(argv[arg_counter++]); if (arg_counter == argc) { - return validate_arguments(); + return validate_arguments(result); } } - if (wrta < 0.0) { + if (result.config.wrta < 0.0) { if (is_negative(argv[arg_counter])) { printf(_(" (%s) must be a non-negative number\n"), argv[arg_counter]); - return ERROR; + result.errorcode = ERROR; + return result; } - wrta = atof(argv[arg_counter++]); + result.config.wrta = atof(argv[arg_counter++]); if (arg_counter == argc) { - return validate_arguments(); + return validate_arguments(result); } } - if (crta < 0.0) { + if (result.config.crta < 0.0) { if (is_negative(argv[arg_counter])) { printf(_(" (%s) must be a non-negative number\n"), argv[arg_counter]); - return ERROR; + result.errorcode = ERROR; + return result; } - crta = atof(argv[arg_counter++]); + result.config.crta = atof(argv[arg_counter++]); if (arg_counter == argc) { - return validate_arguments(); + return validate_arguments(result); } } - if (max_packets == -1) { + if (result.config.max_packets == -1) { if (is_intnonneg(argv[arg_counter])) { - max_packets = atoi(argv[arg_counter++]); + result.config.max_packets = atoi(argv[arg_counter++]); } else { printf(_(" (%s) must be a non-negative number\n"), argv[arg_counter]); - return ERROR; + result.errorcode = ERROR; + return result; } } - return validate_arguments(); + return validate_arguments(result); } -int get_threshold(char *arg, float *trta, int *tpl) { - if (is_intnonneg(arg) && sscanf(arg, "%f", trta) == 1) { +int get_threshold(char *arg, double *trta, int *tpl) { + if (is_intnonneg(arg) && sscanf(arg, "%lf", trta) == 1) { return OK; } - if (strpbrk(arg, ",:") && strstr(arg, "%") && sscanf(arg, "%f%*[:,]%d%%", trta, tpl) == 2) { + if (strpbrk(arg, ",:") && strstr(arg, "%") && sscanf(arg, "%lf%*[:,]%d%%", trta, tpl) == 2) { return OK; } @@ -375,60 +385,66 @@ int get_threshold(char *arg, float *trta, int *tpl) { return STATE_UNKNOWN; } -int validate_arguments() { - if (wrta < 0.0) { +check_ping_config_wrapper validate_arguments(check_ping_config_wrapper config_wrapper) { + if (config_wrapper.config.wrta < 0.0) { printf(_(" was not set\n")); - return ERROR; + config_wrapper.errorcode = ERROR; + return config_wrapper; } - if (crta < 0.0) { + if (config_wrapper.config.crta < 0.0) { printf(_(" was not set\n")); - return ERROR; + config_wrapper.errorcode = ERROR; + return config_wrapper; } - if (wpl == UNKNOWN_PACKET_LOSS) { + if (config_wrapper.config.wpl == UNKNOWN_PACKET_LOSS) { printf(_(" was not set\n")); - return ERROR; + config_wrapper.errorcode = ERROR; + return config_wrapper; } - if (cpl == UNKNOWN_PACKET_LOSS) { + if (config_wrapper.config.cpl == UNKNOWN_PACKET_LOSS) { printf(_(" was not set\n")); - return ERROR; + config_wrapper.errorcode = ERROR; + return config_wrapper; } - if (wrta > crta) { - printf(_(" (%f) cannot be larger than (%f)\n"), wrta, crta); - return ERROR; + if (config_wrapper.config.wrta > config_wrapper.config.crta) { + printf(_(" (%f) cannot be larger than (%f)\n"), config_wrapper.config.wrta, config_wrapper.config.crta); + config_wrapper.errorcode = ERROR; + return config_wrapper; } - if (wpl > cpl) { - printf(_(" (%d) cannot be larger than (%d)\n"), wpl, cpl); - return ERROR; + if (config_wrapper.config.wpl > config_wrapper.config.cpl) { + printf(_(" (%d) cannot be larger than (%d)\n"), config_wrapper.config.wpl, config_wrapper.config.cpl); + config_wrapper.errorcode = ERROR; + return config_wrapper; } - if (max_packets == -1) { - max_packets = DEFAULT_MAX_PACKETS; + if (config_wrapper.config.max_packets == -1) { + config_wrapper.config.max_packets = DEFAULT_MAX_PACKETS; } - float max_seconds = (crta / 1000.0 * max_packets) + max_packets; + double max_seconds = (config_wrapper.config.crta / 1000.0 * config_wrapper.config.max_packets) + config_wrapper.config.max_packets; if (max_seconds > timeout_interval) { timeout_interval = (unsigned int)max_seconds; } - for (int i = 0; i < n_addresses; i++) { - if (!is_host(addresses[i])) { - usage2(_("Invalid hostname/address"), addresses[i]); + for (size_t i = 0; i < config_wrapper.config.n_addresses; i++) { + if (!is_host(config_wrapper.config.addresses[i])) { + usage2(_("Invalid hostname/address"), config_wrapper.config.addresses[i]); } } - if (n_addresses == 0) { + if (config_wrapper.config.n_addresses == 0) { usage(_("You must specify a server address or host name")); } - return OK; + return config_wrapper; } -int run_ping(const char *cmd, const char *addr) { +ping_result run_ping(const char *cmd, const char *addr, double crta) { if ((child_process = spopen(cmd)) == NULL) { die(STATE_UNKNOWN, _("Could not open pipe: %s\n"), cmd); } @@ -439,48 +455,55 @@ int run_ping(const char *cmd, const char *addr) { } char buf[MAX_INPUT_BUFFER]; - int result = STATE_UNKNOWN; + ping_result result = { + .state = STATE_UNKNOWN, + .packet_loss = UNKNOWN_PACKET_LOSS, + .round_trip_average = UNKNOWN_TRIP_TIME, + }; + while (fgets(buf, MAX_INPUT_BUFFER - 1, child_process)) { if (verbose >= 3) { printf("Output: %s", buf); } - result = max_state(result, error_scan(buf, addr)); + result.state = max_state(result.state, error_scan(buf, addr)); /* get the percent loss statistics */ int match = 0; - if ((sscanf(buf, "%*d packets transmitted, %*d packets received, +%*d errors, %d%% packet loss%n", &packet_loss, &match) && + if ((sscanf(buf, "%*d packets transmitted, %*d packets received, +%*d errors, %d%% packet loss%n", &result.packet_loss, &match) && + match) || + (sscanf(buf, "%*d packets transmitted, %*d packets received, +%*d duplicates, %d%% packet loss%n", &result.packet_loss, + &match) && match) || - (sscanf(buf, "%*d packets transmitted, %*d packets received, +%*d duplicates, %d%% packet loss%n", &packet_loss, &match) && + (sscanf(buf, "%*d packets transmitted, %*d received, +%*d duplicates, %d%% packet loss%n", &result.packet_loss, &match) && match) || - (sscanf(buf, "%*d packets transmitted, %*d received, +%*d duplicates, %d%% packet loss%n", &packet_loss, &match) && match) || - (sscanf(buf, "%*d packets transmitted, %*d packets received, %d%% packet loss%n", &packet_loss, &match) && match) || - (sscanf(buf, "%*d packets transmitted, %*d packets received, %d%% loss, time%n", &packet_loss, &match) && match) || - (sscanf(buf, "%*d packets transmitted, %*d received, %d%% loss, time%n", &packet_loss, &match) && match) || - (sscanf(buf, "%*d packets transmitted, %*d received, %d%% packet loss, time%n", &packet_loss, &match) && match) || - (sscanf(buf, "%*d packets transmitted, %*d received, +%*d errors, %d%% packet loss%n", &packet_loss, &match) && match) || - (sscanf(buf, "%*d packets transmitted %*d received, +%*d errors, %d%% packet loss%n", &packet_loss, &match) && match) || - (sscanf(buf, "%*[^(](%d%% %*[^)])%n", &packet_loss, &match) && match)) { + (sscanf(buf, "%*d packets transmitted, %*d packets received, %d%% packet loss%n", &result.packet_loss, &match) && match) || + (sscanf(buf, "%*d packets transmitted, %*d packets received, %d%% loss, time%n", &result.packet_loss, &match) && match) || + (sscanf(buf, "%*d packets transmitted, %*d received, %d%% loss, time%n", &result.packet_loss, &match) && match) || + (sscanf(buf, "%*d packets transmitted, %*d received, %d%% packet loss, time%n", &result.packet_loss, &match) && match) || + (sscanf(buf, "%*d packets transmitted, %*d received, +%*d errors, %d%% packet loss%n", &result.packet_loss, &match) && match) || + (sscanf(buf, "%*d packets transmitted %*d received, +%*d errors, %d%% packet loss%n", &result.packet_loss, &match) && match) || + (sscanf(buf, "%*[^(](%d%% %*[^)])%n", &result.packet_loss, &match) && match)) { continue; } /* get the round trip average */ - if ((sscanf(buf, "round-trip min/avg/max = %*f/%f/%*f%n", &round_trip_average, &match) && match) || - (sscanf(buf, "round-trip min/avg/max/mdev = %*f/%f/%*f/%*f%n", &round_trip_average, &match) && match) || - (sscanf(buf, "round-trip min/avg/max/sdev = %*f/%f/%*f/%*f%n", &round_trip_average, &match) && match) || - (sscanf(buf, "round-trip min/avg/max/stddev = %*f/%f/%*f/%*f%n", &round_trip_average, &match) && match) || - (sscanf(buf, "round-trip min/avg/max/std-dev = %*f/%f/%*f/%*f%n", &round_trip_average, &match) && match) || - (sscanf(buf, "round-trip (ms) min/avg/max = %*f/%f/%*f%n", &round_trip_average, &match) && match) || - (sscanf(buf, "round-trip (ms) min/avg/max/stddev = %*f/%f/%*f/%*f%n", &round_trip_average, &match) && match) || - (sscanf(buf, "rtt min/avg/max/mdev = %*f/%f/%*f/%*f ms%n", &round_trip_average, &match) && match) || - (sscanf(buf, "%*[^=] = %*fms, %*[^=] = %*fms, %*[^=] = %fms%n", &round_trip_average, &match) && match)) { + if ((sscanf(buf, "round-trip min/avg/max = %*f/%lf/%*f%n", &result.round_trip_average, &match) && match) || + (sscanf(buf, "round-trip min/avg/max/mdev = %*f/%lf/%*f/%*f%n", &result.round_trip_average, &match) && match) || + (sscanf(buf, "round-trip min/avg/max/sdev = %*f/%lf/%*f/%*f%n", &result.round_trip_average, &match) && match) || + (sscanf(buf, "round-trip min/avg/max/stddev = %*f/%lf/%*f/%*f%n", &result.round_trip_average, &match) && match) || + (sscanf(buf, "round-trip min/avg/max/std-dev = %*f/%lf/%*f/%*f%n", &result.round_trip_average, &match) && match) || + (sscanf(buf, "round-trip (ms) min/avg/max = %*f/%lf/%*f%n", &result.round_trip_average, &match) && match) || + (sscanf(buf, "round-trip (ms) min/avg/max/stddev = %*f/%lf/%*f/%*f%n", &result.round_trip_average, &match) && match) || + (sscanf(buf, "rtt min/avg/max/mdev = %*f/%lf/%*f/%*f ms%n", &result.round_trip_average, &match) && match) || + (sscanf(buf, "%*[^=] = %*fms, %*[^=] = %*fms, %*[^=] = %lfms%n", &result.round_trip_average, &match) && match)) { continue; } } /* this is needed because there is no rta if all packets are lost */ - if (packet_loss == 100) { - round_trip_average = crta; + if (result.packet_loss == 100) { + result.round_trip_average = crta; } /* check stderr, setting at least WARNING if there is output here */ @@ -492,8 +515,8 @@ int run_ping(const char *cmd, const char *addr) { if (verbose >= 3) { printf("Got stderr: %s", buf); } - if ((result = error_scan(buf, addr)) == STATE_OK) { - result = STATE_WARNING; + if ((result.state = error_scan(buf, addr)) == STATE_OK) { + result.state = STATE_WARNING; if (warn_text == NULL) { warn_text = strdup(_("System call sent warnings to stderr ")); } else { @@ -514,7 +537,7 @@ int run_ping(const char *cmd, const char *addr) { return result; } -int error_scan(char buf[MAX_INPUT_BUFFER], const char *addr) { +mp_state_enum error_scan(char buf[MAX_INPUT_BUFFER], const char *addr) { if (strstr(buf, "Network is unreachable") || strstr(buf, "Destination Net Unreachable") || strstr(buf, "No route")) { die(STATE_CRITICAL, _("CRITICAL - Network Unreachable (%s)\n"), addr); } else if (strstr(buf, "Destination Host Unreachable") || strstr(buf, "Address unreachable")) { @@ -543,10 +566,10 @@ int error_scan(char buf[MAX_INPUT_BUFFER], const char *addr) { } else if (!strstr(warn_text, _(WARN_DUPLICATES)) && xasprintf(&warn_text, "%s %s", warn_text, _(WARN_DUPLICATES)) == -1) { die(STATE_UNKNOWN, _("Unable to realloc warn_text\n")); } - return (STATE_WARNING); + return STATE_WARNING; } - return (STATE_OK); + return STATE_OK; } void print_help(void) { diff --git a/plugins/check_ping.d/config.h b/plugins/check_ping.d/config.h new file mode 100644 index 00000000..eb2735a7 --- /dev/null +++ b/plugins/check_ping.d/config.h @@ -0,0 +1,46 @@ +#pragma once + +#include "../../config.h" +#include +#include + +enum { + UNKNOWN_PACKET_LOSS = 200, /* 200% */ + DEFAULT_MAX_PACKETS = 5 /* default no. of ICMP ECHO packets */ +}; + +#define UNKNOWN_TRIP_TIME -1.0 /* -1 seconds */ + +#define MAX_ADDR_START 1 + +typedef struct { + bool display_html; + int max_packets; + + char **addresses; + size_t n_addresses; + + int wpl; + int cpl; + double wrta; + double crta; +} check_ping_config; + +check_ping_config check_ping_config_init() { + check_ping_config tmp = { + .display_html = false, + .max_packets = -1, + + .addresses = NULL, + .n_addresses = 0, + + .wpl = UNKNOWN_PACKET_LOSS, + .cpl = UNKNOWN_PACKET_LOSS, + .wrta = UNKNOWN_TRIP_TIME, + .crta = UNKNOWN_TRIP_TIME, + }; + + tmp.addresses = calloc(MAX_ADDR_START, sizeof(char *)); + tmp.addresses[0] = NULL; + return tmp; +} -- cgit v1.2.3-74-g34f1 From ab2c2f525987dba8d314644d9eeeb48f9ae4d70c Mon Sep 17 00:00:00 2001 From: Lorenz Kästle <12514511+RincewindsHat@users.noreply.github.com> Date: Wed, 12 Mar 2025 13:36:04 +0100 Subject: More refactoring --- plugins/check_ntp_peer.c | 186 ++++++++++++++++++++------------------ plugins/check_ntp_peer.d/config.h | 13 +++ 2 files changed, 109 insertions(+), 90 deletions(-) diff --git a/plugins/check_ntp_peer.c b/plugins/check_ntp_peer.c index fcd06b8e..19e8a11f 100644 --- a/plugins/check_ntp_peer.c +++ b/plugins/check_ntp_peer.c @@ -35,6 +35,7 @@ * *****************************************************************************/ +#include "thresholds.h" const char *progname = "check_ntp_peer"; const char *copyright = "2006-2024"; const char *email = "devel@monitoring-plugins.org"; @@ -54,10 +55,6 @@ typedef struct { check_ntp_peer_config config; } check_ntp_peer_config_wrapper; static check_ntp_peer_config_wrapper process_arguments(int /*argc*/, char ** /*argv*/); -static thresholds *offset_thresholds = NULL; -static thresholds *jitter_thresholds = NULL; -static thresholds *stratum_thresholds = NULL; -static thresholds *truechimer_thresholds = NULL; static void print_help(void); void print_usage(void); @@ -149,25 +146,25 @@ typedef struct { printf("%u.%u.%u.%u", (x >> 24) & 0xff, (x >> 16) & 0xff, (x >> 8) & 0xff, x & 0xff); \ } while (0); -void print_ntp_control_message(const ntp_control_message *p) { +void print_ntp_control_message(const ntp_control_message *message) { printf("control packet contents:\n"); - printf("\tflags: 0x%.2x , 0x%.2x\n", p->flags, p->op); - printf("\t li=%d (0x%.2x)\n", LI(p->flags), p->flags & LI_MASK); - printf("\t vn=%d (0x%.2x)\n", VN(p->flags), p->flags & VN_MASK); - printf("\t mode=%d (0x%.2x)\n", MODE(p->flags), p->flags & MODE_MASK); - printf("\t response=%d (0x%.2x)\n", (p->op & REM_RESP) > 0, p->op & REM_RESP); - printf("\t more=%d (0x%.2x)\n", (p->op & REM_MORE) > 0, p->op & REM_MORE); - printf("\t error=%d (0x%.2x)\n", (p->op & REM_ERROR) > 0, p->op & REM_ERROR); - printf("\t op=%d (0x%.2x)\n", p->op & OP_MASK, p->op & OP_MASK); - printf("\tsequence: %d (0x%.2x)\n", ntohs(p->seq), ntohs(p->seq)); - printf("\tstatus: %d (0x%.2x)\n", ntohs(p->status), ntohs(p->status)); - printf("\tassoc: %d (0x%.2x)\n", ntohs(p->assoc), ntohs(p->assoc)); - printf("\toffset: %d (0x%.2x)\n", ntohs(p->offset), ntohs(p->offset)); - printf("\tcount: %d (0x%.2x)\n", ntohs(p->count), ntohs(p->count)); - - int numpeers = ntohs(p->count) / (sizeof(ntp_assoc_status_pair)); - if (p->op & REM_RESP && p->op & OP_READSTAT) { - const ntp_assoc_status_pair *peer = (ntp_assoc_status_pair *)p->data; + printf("\tflags: 0x%.2x , 0x%.2x\n", message->flags, message->op); + printf("\t li=%d (0x%.2x)\n", LI(message->flags), message->flags & LI_MASK); + printf("\t vn=%d (0x%.2x)\n", VN(message->flags), message->flags & VN_MASK); + printf("\t mode=%d (0x%.2x)\n", MODE(message->flags), message->flags & MODE_MASK); + printf("\t response=%d (0x%.2x)\n", (message->op & REM_RESP) > 0, message->op & REM_RESP); + printf("\t more=%d (0x%.2x)\n", (message->op & REM_MORE) > 0, message->op & REM_MORE); + printf("\t error=%d (0x%.2x)\n", (message->op & REM_ERROR) > 0, message->op & REM_ERROR); + printf("\t op=%d (0x%.2x)\n", message->op & OP_MASK, message->op & OP_MASK); + printf("\tsequence: %d (0x%.2x)\n", ntohs(message->seq), ntohs(message->seq)); + printf("\tstatus: %d (0x%.2x)\n", ntohs(message->status), ntohs(message->status)); + printf("\tassoc: %d (0x%.2x)\n", ntohs(message->assoc), ntohs(message->assoc)); + printf("\toffset: %d (0x%.2x)\n", ntohs(message->offset), ntohs(message->offset)); + printf("\tcount: %d (0x%.2x)\n", ntohs(message->count), ntohs(message->count)); + + int numpeers = ntohs(message->count) / (sizeof(ntp_assoc_status_pair)); + if (message->op & REM_RESP && message->op & OP_READSTAT) { + const ntp_assoc_status_pair *peer = (ntp_assoc_status_pair *)message->data; for (int i = 0; i < numpeers; i++) { printf("\tpeer id %.2x status %.2x", ntohs(peer[i].assoc), ntohs(peer[i].status)); if (PEER_SEL(peer[i].status) >= PEER_SYNCSOURCE) { @@ -182,13 +179,13 @@ void print_ntp_control_message(const ntp_control_message *p) { } } -void setup_control_request(ntp_control_message *p, uint8_t opcode, uint16_t seq) { - memset(p, 0, sizeof(ntp_control_message)); - LI_SET(p->flags, LI_NOWARNING); - VN_SET(p->flags, VN_RESERVED); - MODE_SET(p->flags, MODE_CONTROLMSG); - OP_SET(p->op, opcode); - p->seq = htons(seq); +void setup_control_request(ntp_control_message *message, uint8_t opcode, uint16_t seq) { + memset(message, 0, sizeof(ntp_control_message)); + LI_SET(message->flags, LI_NOWARNING); + VN_SET(message->flags, VN_RESERVED); + MODE_SET(message->flags, MODE_CONTROLMSG); + OP_SET(message->op, opcode); + message->seq = htons(seq); /* Remaining fields are zero for requests */ } @@ -203,11 +200,23 @@ void setup_control_request(ntp_control_message *p, uint8_t opcode, uint16_t seq) * status is pretty much useless as syncsource_found is a global variable * used later in main to check is the server was synchronized. It works * so I left it alone */ -mp_state_enum ntp_request(double *offset, int *offset_result, double *jitter, int *stratum, int *num_truechimers, - const check_ntp_peer_config config) { - *offset_result = STATE_UNKNOWN; - *jitter = *stratum = -1; - *num_truechimers = 0; +typedef struct { + mp_state_enum state; + mp_state_enum offset_result; + double offset; + double jitter; + long stratum; + int num_truechimers; +} ntp_request_result; +ntp_request_result ntp_request(const check_ntp_peer_config config) { + + ntp_request_result result = { + .state = STATE_OK, + .offset_result = STATE_UNKNOWN, + .jitter = -1, + .stratum = -1, + .num_truechimers = 0, + }; /* Long-winded explanation: * Getting the sync peer offset, jitter and stratum requires a number of @@ -230,8 +239,8 @@ mp_state_enum ntp_request(double *offset, int *offset_result, double *jitter, in void *tmp; ntp_assoc_status_pair *peers = NULL; int peer_offset = 0; - int peers_size = 0; - int npeers = 0; + size_t peers_size = 0; + size_t npeers = 0; int conn = -1; my_udp_connect(config.server_address, config.port, &conn); @@ -269,7 +278,7 @@ mp_state_enum ntp_request(double *offset, int *offset_result, double *jitter, in free(peers), die(STATE_UNKNOWN, "can not (re)allocate 'peers' buffer\n"); } peers = tmp; - memcpy((void *)((ptrdiff_t)peers + peer_offset), (void *)req.data, ntohs(req.count)); + memcpy((peers + peer_offset), (void *)req.data, ntohs(req.count)); npeers = peers_size / sizeof(ntp_assoc_status_pair); peer_offset += ntohs(req.count); } while (req.op & REM_MORE); @@ -277,9 +286,9 @@ mp_state_enum ntp_request(double *offset, int *offset_result, double *jitter, in /* first, let's find out if we have a sync source, or if there are * at least some candidates. In the latter case we'll issue * a warning but go ahead with the check on them. */ - for (int i = 0; i < npeers; i++) { + for (size_t i = 0; i < npeers; i++) { if (PEER_SEL(peers[i].status) >= PEER_TRUECHIMER) { - (*num_truechimers)++; + result.num_truechimers++; if (PEER_SEL(peers[i].status) >= PEER_INCLUDED) { num_candidates++; if (PEER_SEL(peers[i].status) >= PEER_SYNCSOURCE) { @@ -297,15 +306,14 @@ mp_state_enum ntp_request(double *offset, int *offset_result, double *jitter, in printf("synchronization source found\n"); } - int status = STATE_OK; if (!syncsource_found) { - status = STATE_WARNING; + result.state = STATE_WARNING; if (verbose) { printf("warning: no synchronization source found\n"); } } if (li_alarm) { - status = STATE_WARNING; + result.state = STATE_WARNING; if (verbose) { printf("warning: LI_ALARM bit is set\n"); } @@ -313,7 +321,7 @@ mp_state_enum ntp_request(double *offset, int *offset_result, double *jitter, in const char *getvar = "stratum,offset,jitter"; char *data; - for (int i = 0; i < npeers; i++) { + for (size_t i = 0; i < npeers; i++) { /* Only query this server if it is the current sync source */ /* If there's no sync.peer, query all candidates and use the best one */ if (PEER_SEL(peers[i].status) >= min_peer_sel) { @@ -396,9 +404,9 @@ mp_state_enum ntp_request(double *offset, int *offset_result, double *jitter, in if (verbose) { printf("%.10g\n", tmp_offset); } - if (*offset_result == STATE_UNKNOWN || fabs(tmp_offset) < fabs(*offset)) { - *offset = tmp_offset; - *offset_result = STATE_OK; + if (result.offset_result == STATE_UNKNOWN || fabs(tmp_offset) < fabs(result.offset)) { + result.offset = tmp_offset; + result.offset_result = STATE_OK; } else { /* Skip this one; move to the next */ continue; @@ -415,16 +423,16 @@ mp_state_enum ntp_request(double *offset, int *offset_result, double *jitter, in nptr = NULL; /* Convert the value if we have one */ if (value != NULL) { - *jitter = strtod(value, &nptr); + result.jitter = strtod(value, &nptr); } /* If value is null or no conversion was performed */ if (value == NULL || value == nptr) { if (verbose) { printf("error: unable to read server jitter/dispersion response.\n"); } - *jitter = -1; + result.jitter = -1; } else if (verbose) { - printf("%.10g\n", *jitter); + printf("%.10g\n", result.jitter); } } @@ -437,16 +445,16 @@ mp_state_enum ntp_request(double *offset, int *offset_result, double *jitter, in nptr = NULL; /* Convert the value if we have one */ if (value != NULL) { - *stratum = strtol(value, &nptr, 10); + result.stratum = strtol(value, &nptr, 10); } if (value == NULL || value == nptr) { if (verbose) { printf("error: unable to read server stratum response.\n"); } - *stratum = -1; + result.stratum = -1; } else { if (verbose) { - printf("%i\n", *stratum); + printf("%li\n", result.stratum); } } } @@ -458,7 +466,7 @@ mp_state_enum ntp_request(double *offset, int *offset_result, double *jitter, in free(peers); } - return status; + return result; } check_ntp_peer_config_wrapper process_arguments(int argc, char **argv) { @@ -564,25 +572,30 @@ check_ntp_peer_config_wrapper process_arguments(int argc, char **argv) { usage4(_("Hostname was not supplied")); } + set_thresholds(&result.config.offset_thresholds, result.config.owarn, result.config.ocrit); + set_thresholds(&result.config.jitter_thresholds, result.config.jwarn, result.config.jcrit); + set_thresholds(&result.config.stratum_thresholds, result.config.swarn, result.config.scrit); + set_thresholds(&result.config.truechimer_thresholds, result.config.twarn, result.config.tcrit); + return result; } -char *perfd_offset(double offset) { +char *perfd_offset(double offset, thresholds *offset_thresholds) { return fperfdata("offset", offset, "s", true, offset_thresholds->warning->end, true, offset_thresholds->critical->end, false, 0, false, 0); } -char *perfd_jitter(double jitter, bool do_jitter) { +char *perfd_jitter(double jitter, bool do_jitter, thresholds *jitter_thresholds) { return fperfdata("jitter", jitter, "", do_jitter, jitter_thresholds->warning->end, do_jitter, jitter_thresholds->critical->end, true, 0, false, 0); } -char *perfd_stratum(int stratum, bool do_stratum) { +char *perfd_stratum(int stratum, bool do_stratum, thresholds *stratum_thresholds) { return perfdata("stratum", stratum, "", do_stratum, (int)stratum_thresholds->warning->end, do_stratum, (int)stratum_thresholds->critical->end, true, 0, true, 16); } -char *perfd_truechimers(int num_truechimers, const bool do_truechimers) { +char *perfd_truechimers(int num_truechimers, const bool do_truechimers, thresholds *truechimer_thresholds) { return perfdata("truechimers", num_truechimers, "", do_truechimers, (int)truechimer_thresholds->warning->end, do_truechimers, (int)truechimer_thresholds->critical->end, true, 0, false, 0); } @@ -603,26 +616,17 @@ int main(int argc, char *argv[]) { const check_ntp_peer_config config = tmp_config.config; - set_thresholds(&offset_thresholds, config.owarn, config.ocrit); - set_thresholds(&jitter_thresholds, config.jwarn, config.jcrit); - set_thresholds(&stratum_thresholds, config.swarn, config.scrit); - set_thresholds(&truechimer_thresholds, config.twarn, config.tcrit); - /* initialize alarm signal handling */ signal(SIGALRM, socket_timeout_alarm_handler); /* set socket timeout */ alarm(socket_timeout); - int offset_result; - int stratum; - int num_truechimers; - double offset = 0; - double jitter = 0; /* This returns either OK or WARNING (See comment preceding ntp_request) */ - mp_state_enum result = ntp_request(&offset, &offset_result, &jitter, &stratum, &num_truechimers, config); + ntp_request_result ntp_res = ntp_request(config); + mp_state_enum result = STATE_UNKNOWN; - if (offset_result == STATE_UNKNOWN) { + if (ntp_res.offset_result == STATE_UNKNOWN) { /* if there's no sync peer (this overrides ntp_request output): */ result = (config.quiet ? STATE_UNKNOWN : STATE_CRITICAL); } else { @@ -630,28 +634,28 @@ int main(int argc, char *argv[]) { if (config.quiet && result == STATE_WARNING) { result = STATE_UNKNOWN; } - result = max_state_alt(result, get_status(fabs(offset), offset_thresholds)); + result = max_state_alt(result, get_status(fabs(ntp_res.offset), config.offset_thresholds)); } mp_state_enum oresult = result; mp_state_enum tresult = STATE_UNKNOWN; if (config.do_truechimers) { - tresult = get_status(num_truechimers, truechimer_thresholds); + tresult = get_status(ntp_res.num_truechimers, config.truechimer_thresholds); result = max_state_alt(result, tresult); } mp_state_enum sresult = STATE_UNKNOWN; if (config.do_stratum) { - sresult = get_status(stratum, stratum_thresholds); + sresult = get_status((double)ntp_res.stratum, config.stratum_thresholds); result = max_state_alt(result, sresult); } mp_state_enum jresult = STATE_UNKNOWN; if (config.do_jitter) { - jresult = get_status(jitter, jitter_thresholds); + jresult = get_status(ntp_res.jitter, config.jitter_thresholds); result = max_state_alt(result, jresult); } @@ -678,50 +682,52 @@ int main(int argc, char *argv[]) { } char *perfdata_line; - if (offset_result == STATE_UNKNOWN) { + if (ntp_res.offset_result == STATE_UNKNOWN) { xasprintf(&result_line, "%s %s", result_line, _("Offset unknown")); xasprintf(&perfdata_line, ""); } else if (oresult == STATE_WARNING) { - xasprintf(&result_line, "%s %s %.10g secs (WARNING)", result_line, _("Offset"), offset); + xasprintf(&result_line, "%s %s %.10g secs (WARNING)", result_line, _("Offset"), ntp_res.offset); } else if (oresult == STATE_CRITICAL) { - xasprintf(&result_line, "%s %s %.10g secs (CRITICAL)", result_line, _("Offset"), offset); + xasprintf(&result_line, "%s %s %.10g secs (CRITICAL)", result_line, _("Offset"), ntp_res.offset); } else { - xasprintf(&result_line, "%s %s %.10g secs", result_line, _("Offset"), offset); + xasprintf(&result_line, "%s %s %.10g secs", result_line, _("Offset"), ntp_res.offset); } - xasprintf(&perfdata_line, "%s", perfd_offset(offset)); + xasprintf(&perfdata_line, "%s", perfd_offset(ntp_res.offset, config.offset_thresholds)); if (config.do_jitter) { if (jresult == STATE_WARNING) { - xasprintf(&result_line, "%s, jitter=%f (WARNING)", result_line, jitter); + xasprintf(&result_line, "%s, jitter=%f (WARNING)", result_line, ntp_res.jitter); } else if (jresult == STATE_CRITICAL) { - xasprintf(&result_line, "%s, jitter=%f (CRITICAL)", result_line, jitter); + xasprintf(&result_line, "%s, jitter=%f (CRITICAL)", result_line, ntp_res.jitter); } else { - xasprintf(&result_line, "%s, jitter=%f", result_line, jitter); + xasprintf(&result_line, "%s, jitter=%f", result_line, ntp_res.jitter); } - xasprintf(&perfdata_line, "%s %s", perfdata_line, perfd_jitter(jitter, config.do_jitter)); + xasprintf(&perfdata_line, "%s %s", perfdata_line, perfd_jitter(ntp_res.jitter, config.do_jitter, config.jitter_thresholds)); } if (config.do_stratum) { if (sresult == STATE_WARNING) { - xasprintf(&result_line, "%s, stratum=%i (WARNING)", result_line, stratum); + xasprintf(&result_line, "%s, stratum=%i (WARNING)", result_line, ntp_res.stratum); } else if (sresult == STATE_CRITICAL) { - xasprintf(&result_line, "%s, stratum=%i (CRITICAL)", result_line, stratum); + xasprintf(&result_line, "%s, stratum=%i (CRITICAL)", result_line, ntp_res.stratum); } else { - xasprintf(&result_line, "%s, stratum=%i", result_line, stratum); + xasprintf(&result_line, "%s, stratum=%i", result_line, ntp_res.stratum); } - xasprintf(&perfdata_line, "%s %s", perfdata_line, perfd_stratum(stratum, config.do_stratum)); + xasprintf(&perfdata_line, "%s %s", perfdata_line, perfd_stratum(ntp_res.stratum, config.do_stratum, config.stratum_thresholds)); } if (config.do_truechimers) { if (tresult == STATE_WARNING) { - xasprintf(&result_line, "%s, truechimers=%i (WARNING)", result_line, num_truechimers); + xasprintf(&result_line, "%s, truechimers=%i (WARNING)", result_line, ntp_res.num_truechimers); } else if (tresult == STATE_CRITICAL) { - xasprintf(&result_line, "%s, truechimers=%i (CRITICAL)", result_line, num_truechimers); + xasprintf(&result_line, "%s, truechimers=%i (CRITICAL)", result_line, ntp_res.num_truechimers); } else { - xasprintf(&result_line, "%s, truechimers=%i", result_line, num_truechimers); + xasprintf(&result_line, "%s, truechimers=%i", result_line, ntp_res.num_truechimers); } - xasprintf(&perfdata_line, "%s %s", perfdata_line, perfd_truechimers(num_truechimers, config.do_truechimers)); + xasprintf(&perfdata_line, "%s %s", perfdata_line, + perfd_truechimers(ntp_res.num_truechimers, config.do_truechimers, config.truechimer_thresholds)); } + printf("%s|%s\n", result_line, perfdata_line); if (config.server_address != NULL) { diff --git a/plugins/check_ntp_peer.d/config.h b/plugins/check_ntp_peer.d/config.h index 1907af7c..00e6b05d 100644 --- a/plugins/check_ntp_peer.d/config.h +++ b/plugins/check_ntp_peer.d/config.h @@ -1,6 +1,7 @@ #pragma once #include "../../config.h" +#include "thresholds.h" #include enum { @@ -17,19 +18,24 @@ typedef struct { bool do_truechimers; char *twarn; char *tcrit; + thresholds *truechimer_thresholds; char *owarn; char *ocrit; + thresholds *offset_thresholds; // stratum stuff bool do_stratum; char *swarn; char *scrit; + thresholds *stratum_thresholds; // jitter stuff bool do_jitter; char *jwarn; char *jcrit; + thresholds *jitter_thresholds; + } check_ntp_peer_config; check_ntp_peer_config check_ntp_peer_config_init() { @@ -41,14 +47,21 @@ check_ntp_peer_config check_ntp_peer_config_init() { .do_truechimers = false, .twarn = "0:", .tcrit = "0:", + .truechimer_thresholds = NULL, + .owarn = "60", .ocrit = "120", + .offset_thresholds = NULL, + .do_stratum = false, .swarn = "-1:16", .scrit = "-1:16", + .stratum_thresholds = NULL, + .do_jitter = false, .jwarn = "-1:5000", .jcrit = "-1:10000", + .jitter_thresholds = NULL, }; return tmp; } -- cgit v1.2.3-74-g34f1 From 2765379e3b2b18f6ca108ea96617fe8582078650 Mon Sep 17 00:00:00 2001 From: Lorenz Kästle <12514511+RincewindsHat@users.noreply.github.com> Date: Wed, 12 Mar 2025 13:47:13 +0100 Subject: Fix format specifier --- plugins/check_ntp_peer.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/plugins/check_ntp_peer.c b/plugins/check_ntp_peer.c index 19e8a11f..6e76bf23 100644 --- a/plugins/check_ntp_peer.c +++ b/plugins/check_ntp_peer.c @@ -707,11 +707,11 @@ int main(int argc, char *argv[]) { if (config.do_stratum) { if (sresult == STATE_WARNING) { - xasprintf(&result_line, "%s, stratum=%i (WARNING)", result_line, ntp_res.stratum); + xasprintf(&result_line, "%s, stratum=%l (WARNING)", result_line, ntp_res.stratum); } else if (sresult == STATE_CRITICAL) { - xasprintf(&result_line, "%s, stratum=%i (CRITICAL)", result_line, ntp_res.stratum); + xasprintf(&result_line, "%s, stratum=%l (CRITICAL)", result_line, ntp_res.stratum); } else { - xasprintf(&result_line, "%s, stratum=%i", result_line, ntp_res.stratum); + xasprintf(&result_line, "%s, stratum=%l", result_line, ntp_res.stratum); } xasprintf(&perfdata_line, "%s %s", perfdata_line, perfd_stratum(ntp_res.stratum, config.do_stratum, config.stratum_thresholds)); } -- cgit v1.2.3-74-g34f1 From 6fcc97400a8e6926e6700a050e33cd767d6e67f3 Mon Sep 17 00:00:00 2001 From: Lorenz Kästle <12514511+RincewindsHat@users.noreply.github.com> Date: Wed, 12 Mar 2025 16:19:38 +0100 Subject: check_radius: clang-format --- plugins/check_radius.c | 451 ++++++++++++++++++++++++------------------------- 1 file changed, 221 insertions(+), 230 deletions(-) diff --git a/plugins/check_radius.c b/plugins/check_radius.c index d9ff8fa7..646ffcbe 100644 --- a/plugins/check_radius.c +++ b/plugins/check_radius.c @@ -1,32 +1,32 @@ /***************************************************************************** -* -* Monitoring check_radius plugin -* -* License: GPL -* Copyright (c) 1999-2024 Monitoring Plugins Development Team -* -* Description: -* -* This file contains the check_radius plugin -* -* Tests to see if a radius server is accepting connections. -* -* -* This program is free software: you can redistribute it and/or modify -* it under the terms of the GNU General Public License as published by -* the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU General Public License for more details. -* -* You should have received a copy of the GNU General Public License -* along with this program. If not, see . -* -* -*****************************************************************************/ + * + * Monitoring check_radius plugin + * + * License: GPL + * Copyright (c) 1999-2024 Monitoring Plugins Development Team + * + * Description: + * + * This file contains the check_radius plugin + * + * Tests to see if a radius server is accepting connections. + * + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + * + *****************************************************************************/ const char *progname = "check_radius"; const char *copyright = "2000-2024"; @@ -37,45 +37,45 @@ const char *email = "devel@monitoring-plugins.org"; #include "netutils.h" #if defined(HAVE_LIBRADCLI) -#include +# include #elif defined(HAVE_LIBFREERADIUS_CLIENT) -#include +# include #elif defined(HAVE_LIBRADIUSCLIENT_NG) -#include +# include #else -#include +# include #endif -static int process_arguments (int /*argc*/, char ** /*argv*/); -static void print_help (void); -void print_usage (void); +static int process_arguments(int /*argc*/, char ** /*argv*/); +static void print_help(void); +void print_usage(void); #if defined(HAVE_LIBFREERADIUS_CLIENT) || defined(HAVE_LIBRADIUSCLIENT_NG) || defined(HAVE_LIBRADCLI) -#define my_rc_conf_str(a) rc_conf_str(rch,a) -#if defined(HAVE_LIBRADCLI) -#define my_rc_send_server(a,b) rc_send_server(rch,a,b,AUTH) -#else -#define my_rc_send_server(a,b) rc_send_server(rch,a,b) -#endif -#if defined(HAVE_LIBFREERADIUS_CLIENT) || defined(HAVE_LIBRADCLI) -#define my_rc_buildreq(a,b,c,d,e,f) rc_buildreq(rch,a,b,c,d,(a)->secret,e,f) -#else -#define my_rc_buildreq(a,b,c,d,e,f) rc_buildreq(rch,a,b,c,d,e,f) -#endif -#define my_rc_avpair_add(a,b,c,d) rc_avpair_add(rch,a,b,c,-1,d) -#define my_rc_read_dictionary(a) rc_read_dictionary(rch, a) +# define my_rc_conf_str(a) rc_conf_str(rch, a) +# if defined(HAVE_LIBRADCLI) +# define my_rc_send_server(a, b) rc_send_server(rch, a, b, AUTH) +# else +# define my_rc_send_server(a, b) rc_send_server(rch, a, b) +# endif +# if defined(HAVE_LIBFREERADIUS_CLIENT) || defined(HAVE_LIBRADCLI) +# define my_rc_buildreq(a, b, c, d, e, f) rc_buildreq(rch, a, b, c, d, (a)->secret, e, f) +# else +# define my_rc_buildreq(a, b, c, d, e, f) rc_buildreq(rch, a, b, c, d, e, f) +# endif +# define my_rc_avpair_add(a, b, c, d) rc_avpair_add(rch, a, b, c, -1, d) +# define my_rc_read_dictionary(a) rc_read_dictionary(rch, a) #else -#define my_rc_conf_str(a) rc_conf_str(a) -#define my_rc_send_server(a,b) rc_send_server(a, b) -#define my_rc_buildreq(a,b,c,d,e,f) rc_buildreq(a,b,c,d,e,f) -#define my_rc_avpair_add(a,b,c,d) rc_avpair_add(a, b, c, d) -#define my_rc_read_dictionary(a) rc_read_dictionary(a) +# define my_rc_conf_str(a) rc_conf_str(a) +# define my_rc_send_server(a, b) rc_send_server(a, b) +# define my_rc_buildreq(a, b, c, d, e, f) rc_buildreq(a, b, c, d, e, f) +# define my_rc_avpair_add(a, b, c, d) rc_avpair_add(a, b, c, d) +# define my_rc_read_dictionary(a) rc_read_dictionary(a) #endif /* REJECT_RC is only defined in some version of radiusclient. It has * been reported from radiusclient-ng 0.5.6 on FreeBSD 7.2-RELEASE */ #ifndef REJECT_RC -#define REJECT_RC BADRESP_RC +# define REJECT_RC BADRESP_RC #endif static int my_rc_read_config(char * /*a*/); @@ -148,11 +148,7 @@ Please note that all tags must be lowercase to use the DocBook XML DTD. -@@ ******************************************************************************/ - - -int -main (int argc, char **argv) -{ +int main(int argc, char **argv) { struct sockaddr_storage ss; char name[HOST_NAME_MAX]; #ifdef RC_BUFFER_LEN @@ -165,131 +161,130 @@ main (int argc, char **argv) uint32_t client_id, service; char *str; - setlocale (LC_ALL, ""); - bindtextdomain (PACKAGE, LOCALEDIR); - textdomain (PACKAGE); + setlocale(LC_ALL, ""); + bindtextdomain(PACKAGE, LOCALEDIR); + textdomain(PACKAGE); /* Parse extra opts if any */ - argv=np_extra_opts (&argc, argv, progname); + argv = np_extra_opts(&argc, argv, progname); - if (process_arguments (argc, argv) == ERROR) - usage4 (_("Could not parse arguments")); + if (process_arguments(argc, argv) == ERROR) { + usage4(_("Could not parse arguments")); + } - str = strdup ("dictionary"); - if ((config_file && my_rc_read_config (config_file)) || - my_rc_read_dictionary (my_rc_conf_str (str))) - die (STATE_UNKNOWN, _("Config file error\n")); + str = strdup("dictionary"); + if ((config_file && my_rc_read_config(config_file)) || my_rc_read_dictionary(my_rc_conf_str(str))) { + die(STATE_UNKNOWN, _("Config file error\n")); + } service = PW_AUTHENTICATE_ONLY; - memset (&data, 0, sizeof(data)); - if (!(my_rc_avpair_add (&data.send_pairs, PW_SERVICE_TYPE, &service, 0) && - my_rc_avpair_add (&data.send_pairs, PW_USER_NAME, username, 0) && - my_rc_avpair_add (&data.send_pairs, PW_USER_PASSWORD, password, 0) - )) - die (STATE_UNKNOWN, _("Out of Memory?\n")); + memset(&data, 0, sizeof(data)); + if (!(my_rc_avpair_add(&data.send_pairs, PW_SERVICE_TYPE, &service, 0) && + my_rc_avpair_add(&data.send_pairs, PW_USER_NAME, username, 0) && + my_rc_avpair_add(&data.send_pairs, PW_USER_PASSWORD, password, 0))) { + die(STATE_UNKNOWN, _("Out of Memory?\n")); + } if (nasid != NULL) { - if (!(my_rc_avpair_add (&data.send_pairs, PW_NAS_IDENTIFIER, nasid, 0))) - die (STATE_UNKNOWN, _("Invalid NAS-Identifier\n")); + if (!(my_rc_avpair_add(&data.send_pairs, PW_NAS_IDENTIFIER, nasid, 0))) { + die(STATE_UNKNOWN, _("Invalid NAS-Identifier\n")); + } } if (nasipaddress == NULL) { - if (gethostname (name, sizeof(name)) != 0) - die (STATE_UNKNOWN, _("gethostname() failed!\n")); + if (gethostname(name, sizeof(name)) != 0) { + die(STATE_UNKNOWN, _("gethostname() failed!\n")); + } nasipaddress = name; } - if (!dns_lookup (nasipaddress, &ss, AF_INET)) /* TODO: Support IPv6. */ - die (STATE_UNKNOWN, _("Invalid NAS-IP-Address\n")); - client_id = ntohl (((struct sockaddr_in *)&ss)->sin_addr.s_addr); - if (my_rc_avpair_add (&(data.send_pairs), PW_NAS_IP_ADDRESS, &client_id, 0) == NULL) - die (STATE_UNKNOWN, _("Invalid NAS-IP-Address\n")); - - my_rc_buildreq (&data, PW_ACCESS_REQUEST, server, port, (int)timeout_interval, - retries); - - result = my_rc_send_server (&data, msg); - rc_avpair_free (data.send_pairs); - if (data.receive_pairs) - rc_avpair_free (data.receive_pairs); - - if (result == TIMEOUT_RC) - die (STATE_CRITICAL, _("Timeout\n")); - if (result == ERROR_RC) - die (STATE_CRITICAL, _("Auth Error\n")); - if (result == REJECT_RC) - die (STATE_WARNING, _("Auth Failed\n")); - if (result == BADRESP_RC) - die (STATE_WARNING, _("Bad Response\n")); - if (expect && !strstr (msg, expect)) - die (STATE_WARNING, "%s\n", msg); - if (result == OK_RC) - die (STATE_OK, _("Auth OK\n")); - (void)snprintf(msg, sizeof(msg), _("Unexpected result code %d"), result); - die (STATE_UNKNOWN, "%s\n", msg); -} + if (!dns_lookup(nasipaddress, &ss, AF_INET)) { /* TODO: Support IPv6. */ + die(STATE_UNKNOWN, _("Invalid NAS-IP-Address\n")); + } + client_id = ntohl(((struct sockaddr_in *)&ss)->sin_addr.s_addr); + if (my_rc_avpair_add(&(data.send_pairs), PW_NAS_IP_ADDRESS, &client_id, 0) == NULL) { + die(STATE_UNKNOWN, _("Invalid NAS-IP-Address\n")); + } + + my_rc_buildreq(&data, PW_ACCESS_REQUEST, server, port, (int)timeout_interval, retries); + result = my_rc_send_server(&data, msg); + rc_avpair_free(data.send_pairs); + if (data.receive_pairs) { + rc_avpair_free(data.receive_pairs); + } + if (result == TIMEOUT_RC) { + die(STATE_CRITICAL, _("Timeout\n")); + } + if (result == ERROR_RC) { + die(STATE_CRITICAL, _("Auth Error\n")); + } + if (result == REJECT_RC) { + die(STATE_WARNING, _("Auth Failed\n")); + } + if (result == BADRESP_RC) { + die(STATE_WARNING, _("Bad Response\n")); + } + if (expect && !strstr(msg, expect)) { + die(STATE_WARNING, "%s\n", msg); + } + if (result == OK_RC) { + die(STATE_OK, _("Auth OK\n")); + } + (void)snprintf(msg, sizeof(msg), _("Unexpected result code %d"), result); + die(STATE_UNKNOWN, "%s\n", msg); +} /* process command-line arguments */ -int -process_arguments (int argc, char **argv) -{ +int process_arguments(int argc, char **argv) { int c; int option = 0; - static struct option longopts[] = { - {"hostname", required_argument, 0, 'H'}, - {"port", required_argument, 0, 'P'}, - {"username", required_argument, 0, 'u'}, - {"password", required_argument, 0, 'p'}, - {"nas-id", required_argument, 0, 'n'}, - {"nas-ip-address", required_argument, 0, 'N'}, - {"filename", required_argument, 0, 'F'}, - {"expect", required_argument, 0, 'e'}, - {"retries", required_argument, 0, 'r'}, - {"timeout", required_argument, 0, 't'}, - {"verbose", no_argument, 0, 'v'}, - {"version", no_argument, 0, 'V'}, - {"help", no_argument, 0, 'h'}, - {0, 0, 0, 0} - }; + static struct option longopts[] = {{"hostname", required_argument, 0, 'H'}, {"port", required_argument, 0, 'P'}, + {"username", required_argument, 0, 'u'}, {"password", required_argument, 0, 'p'}, + {"nas-id", required_argument, 0, 'n'}, {"nas-ip-address", required_argument, 0, 'N'}, + {"filename", required_argument, 0, 'F'}, {"expect", required_argument, 0, 'e'}, + {"retries", required_argument, 0, 'r'}, {"timeout", required_argument, 0, 't'}, + {"verbose", no_argument, 0, 'v'}, {"version", no_argument, 0, 'V'}, + {"help", no_argument, 0, 'h'}, {0, 0, 0, 0}}; while (1) { - c = getopt_long (argc, argv, "+hVvH:P:F:u:p:n:N:t:r:e:", longopts, - &option); + c = getopt_long(argc, argv, "+hVvH:P:F:u:p:n:N:t:r:e:", longopts, &option); - if (c == -1 || c == EOF || c == 1) + if (c == -1 || c == EOF || c == 1) { break; + } switch (c) { - case '?': /* print short usage statement if args not parsable */ - usage5 (); - case 'h': /* help */ - print_help (); - exit (STATE_UNKNOWN); - case 'V': /* version */ - print_revision (progname, NP_VERSION); - exit (STATE_UNKNOWN); - case 'v': /* verbose mode */ + case '?': /* print short usage statement if args not parsable */ + usage5(); + case 'h': /* help */ + print_help(); + exit(STATE_UNKNOWN); + case 'V': /* version */ + print_revision(progname, NP_VERSION); + exit(STATE_UNKNOWN); + case 'v': /* verbose mode */ verbose = true; break; - case 'H': /* hostname */ - if (!is_host (optarg)) { - usage2 (_("Invalid hostname/address"), optarg); + case 'H': /* hostname */ + if (!is_host(optarg)) { + usage2(_("Invalid hostname/address"), optarg); } server = optarg; break; - case 'P': /* port */ - if (is_intnonneg (optarg)) - port = (unsigned short)atoi (optarg); - else - usage4 (_("Port must be a positive integer")); + case 'P': /* port */ + if (is_intnonneg(optarg)) { + port = (unsigned short)atoi(optarg); + } else { + usage4(_("Port must be a positive integer")); + } break; - case 'u': /* username */ + case 'u': /* username */ username = optarg; break; - case 'p': /* password */ + case 'p': /* password */ password = strdup(optarg); /* Delete the password from process list */ @@ -298,115 +293,111 @@ process_arguments (int argc, char **argv) optarg++; } break; - case 'n': /* nas id */ + case 'n': /* nas id */ nasid = optarg; break; - case 'N': /* nas ip address */ + case 'N': /* nas ip address */ nasipaddress = optarg; break; - case 'F': /* configuration file */ + case 'F': /* configuration file */ config_file = optarg; break; - case 'e': /* expect */ + case 'e': /* expect */ expect = optarg; break; - case 'r': /* retries */ - if (is_intpos (optarg)) - retries = atoi (optarg); - else - usage4 (_("Number of retries must be a positive integer")); + case 'r': /* retries */ + if (is_intpos(optarg)) { + retries = atoi(optarg); + } else { + usage4(_("Number of retries must be a positive integer")); + } break; - case 't': /* timeout */ - if (is_intpos (optarg)) - timeout_interval = (unsigned)atoi (optarg); - else - usage2 (_("Timeout interval must be a positive integer"), optarg); + case 't': /* timeout */ + if (is_intpos(optarg)) { + timeout_interval = (unsigned)atoi(optarg); + } else { + usage2(_("Timeout interval must be a positive integer"), optarg); + } break; } } - if (server == NULL) - usage4 (_("Hostname was not supplied")); - if (username == NULL) - usage4 (_("User not specified")); - if (password == NULL) - usage4 (_("Password not specified")); - if (config_file == NULL) - usage4 (_("Configuration file not specified")); + if (server == NULL) { + usage4(_("Hostname was not supplied")); + } + if (username == NULL) { + usage4(_("User not specified")); + } + if (password == NULL) { + usage4(_("Password not specified")); + } + if (config_file == NULL) { + usage4(_("Configuration file not specified")); + } return OK; } - - -void -print_help (void) -{ +void print_help(void) { char *myport; - xasprintf (&myport, "%d", PW_AUTH_UDP_PORT); + xasprintf(&myport, "%d", PW_AUTH_UDP_PORT); - print_revision (progname, NP_VERSION); + print_revision(progname, NP_VERSION); - printf ("Copyright (c) 1999 Robert August Vincent II\n"); - printf (COPYRIGHT, copyright, email); + printf("Copyright (c) 1999 Robert August Vincent II\n"); + printf(COPYRIGHT, copyright, email); printf("%s\n", _("Tests to see if a RADIUS server is accepting connections.")); - printf ("\n\n"); - - print_usage (); - - printf (UT_HELP_VRSN); - printf (UT_EXTRA_OPTS); - - printf (UT_HOST_PORT, 'P', myport); - - printf (" %s\n", "-u, --username=STRING"); - printf (" %s\n", _("The user to authenticate")); - printf (" %s\n", "-p, --password=STRING"); - printf (" %s\n", _("Password for authentication (SECURITY RISK)")); - printf (" %s\n", "-n, --nas-id=STRING"); - printf (" %s\n", _("NAS identifier")); - printf (" %s\n", "-N, --nas-ip-address=STRING"); - printf (" %s\n", _("NAS IP Address")); - printf (" %s\n", "-F, --filename=STRING"); - printf (" %s\n", _("Configuration file")); - printf (" %s\n", "-e, --expect=STRING"); - printf (" %s\n", _("Response string to expect from the server")); - printf (" %s\n", "-r, --retries=INTEGER"); - printf (" %s\n", _("Number of times to retry a failed connection")); - - printf (UT_CONN_TIMEOUT, timeout_interval); - - printf ("\n"); - printf ("%s\n", _("This plugin tests a RADIUS server to see if it is accepting connections.")); - printf ("%s\n", _("The server to test must be specified in the invocation, as well as a user")); - printf ("%s\n", _("name and password. A configuration file must be present. The format of")); - printf ("%s\n", _("the configuration file is described in the radiusclient library sources.")); - printf ("%s\n", _("The password option presents a substantial security issue because the")); - printf ("%s\n", _("password can possibly be determined by careful watching of the command line")); - printf ("%s\n", _("in a process listing. This risk is exacerbated because the plugin will")); - printf ("%s\n", _("typically be executed at regular predictable intervals. Please be sure that")); - printf ("%s\n", _("the password used does not allow access to sensitive system resources.")); - - printf (UT_SUPPORT); + printf("\n\n"); + + print_usage(); + + printf(UT_HELP_VRSN); + printf(UT_EXTRA_OPTS); + + printf(UT_HOST_PORT, 'P', myport); + + printf(" %s\n", "-u, --username=STRING"); + printf(" %s\n", _("The user to authenticate")); + printf(" %s\n", "-p, --password=STRING"); + printf(" %s\n", _("Password for authentication (SECURITY RISK)")); + printf(" %s\n", "-n, --nas-id=STRING"); + printf(" %s\n", _("NAS identifier")); + printf(" %s\n", "-N, --nas-ip-address=STRING"); + printf(" %s\n", _("NAS IP Address")); + printf(" %s\n", "-F, --filename=STRING"); + printf(" %s\n", _("Configuration file")); + printf(" %s\n", "-e, --expect=STRING"); + printf(" %s\n", _("Response string to expect from the server")); + printf(" %s\n", "-r, --retries=INTEGER"); + printf(" %s\n", _("Number of times to retry a failed connection")); + + printf(UT_CONN_TIMEOUT, timeout_interval); + + printf("\n"); + printf("%s\n", _("This plugin tests a RADIUS server to see if it is accepting connections.")); + printf("%s\n", _("The server to test must be specified in the invocation, as well as a user")); + printf("%s\n", _("name and password. A configuration file must be present. The format of")); + printf("%s\n", _("the configuration file is described in the radiusclient library sources.")); + printf("%s\n", _("The password option presents a substantial security issue because the")); + printf("%s\n", _("password can possibly be determined by careful watching of the command line")); + printf("%s\n", _("in a process listing. This risk is exacerbated because the plugin will")); + printf("%s\n", _("typically be executed at regular predictable intervals. Please be sure that")); + printf("%s\n", _("the password used does not allow access to sensitive system resources.")); + + printf(UT_SUPPORT); } - - -void -print_usage (void) -{ - printf ("%s\n", _("Usage:")); - printf ("%s -H host -F config_file -u username -p password\n\ +void print_usage(void) { + printf("%s\n", _("Usage:")); + printf("%s -H host -F config_file -u username -p password\n\ [-P port] [-t timeout] [-r retries] [-e expect]\n\ - [-n nas-id] [-N nas-ip-addr]\n", progname); + [-n nas-id] [-N nas-ip-addr]\n", + progname); } - - -int my_rc_read_config(char * a) -{ +int my_rc_read_config(char *a) { #if defined(HAVE_LIBFREERADIUS_CLIENT) || defined(HAVE_LIBRADIUSCLIENT_NG) || defined(HAVE_LIBRADCLI) rch = rc_read_config(a); return (rch == NULL) ? 1 : 0; -- cgit v1.2.3-74-g34f1 From 0728456d73d4b3c62a2f26f4c918de571b4fbc3d Mon Sep 17 00:00:00 2001 From: Lorenz Kästle <12514511+RincewindsHat@users.noreply.github.com> Date: Wed, 12 Mar 2025 16:29:53 +0100 Subject: check_radius: general refactoring --- plugins/check_radius.c | 44 +++++++++++++++++++++----------------------- 1 file changed, 21 insertions(+), 23 deletions(-) diff --git a/plugins/check_radius.c b/plugins/check_radius.c index 646ffcbe..ab7c6519 100644 --- a/plugins/check_radius.c +++ b/plugins/check_radius.c @@ -35,6 +35,7 @@ const char *email = "devel@monitoring-plugins.org"; #include "common.h" #include "utils.h" #include "netutils.h" +#include "states.h" #if defined(HAVE_LIBRADCLI) # include @@ -149,18 +150,6 @@ Please note that all tags must be lowercase to use the DocBook XML DTD. ******************************************************************************/ int main(int argc, char **argv) { - struct sockaddr_storage ss; - char name[HOST_NAME_MAX]; -#ifdef RC_BUFFER_LEN - char msg[RC_BUFFER_LEN]; -#else - char msg[BUFFER_LEN]; -#endif - SEND_DATA data; - int result = STATE_UNKNOWN; - uint32_t client_id, service; - char *str; - setlocale(LC_ALL, ""); bindtextdomain(PACKAGE, LOCALEDIR); textdomain(PACKAGE); @@ -172,13 +161,14 @@ int main(int argc, char **argv) { usage4(_("Could not parse arguments")); } - str = strdup("dictionary"); + char *str = strdup("dictionary"); if ((config_file && my_rc_read_config(config_file)) || my_rc_read_dictionary(my_rc_conf_str(str))) { die(STATE_UNKNOWN, _("Config file error\n")); } - service = PW_AUTHENTICATE_ONLY; + uint32_t service = PW_AUTHENTICATE_ONLY; + SEND_DATA data; memset(&data, 0, sizeof(data)); if (!(my_rc_avpair_add(&data.send_pairs, PW_SERVICE_TYPE, &service, 0) && my_rc_avpair_add(&data.send_pairs, PW_USER_NAME, username, 0) && @@ -192,23 +182,33 @@ int main(int argc, char **argv) { } } + char name[HOST_NAME_MAX]; if (nasipaddress == NULL) { if (gethostname(name, sizeof(name)) != 0) { die(STATE_UNKNOWN, _("gethostname() failed!\n")); } nasipaddress = name; } + + struct sockaddr_storage ss; if (!dns_lookup(nasipaddress, &ss, AF_INET)) { /* TODO: Support IPv6. */ die(STATE_UNKNOWN, _("Invalid NAS-IP-Address\n")); } - client_id = ntohl(((struct sockaddr_in *)&ss)->sin_addr.s_addr); + + uint32_t client_id = ntohl(((struct sockaddr_in *)&ss)->sin_addr.s_addr); if (my_rc_avpair_add(&(data.send_pairs), PW_NAS_IP_ADDRESS, &client_id, 0) == NULL) { die(STATE_UNKNOWN, _("Invalid NAS-IP-Address\n")); } my_rc_buildreq(&data, PW_ACCESS_REQUEST, server, port, (int)timeout_interval, retries); - result = my_rc_send_server(&data, msg); +#ifdef RC_BUFFER_LEN + char msg[RC_BUFFER_LEN]; +#else + char msg[BUFFER_LEN]; +#endif + + mp_state_enum result = my_rc_send_server(&data, msg); rc_avpair_free(data.send_pairs); if (data.receive_pairs) { rc_avpair_free(data.receive_pairs); @@ -238,9 +238,6 @@ int main(int argc, char **argv) { /* process command-line arguments */ int process_arguments(int argc, char **argv) { - int c; - - int option = 0; static struct option longopts[] = {{"hostname", required_argument, 0, 'H'}, {"port", required_argument, 0, 'P'}, {"username", required_argument, 0, 'u'}, {"password", required_argument, 0, 'p'}, {"nas-id", required_argument, 0, 'n'}, {"nas-ip-address", required_argument, 0, 'N'}, @@ -249,14 +246,15 @@ int process_arguments(int argc, char **argv) { {"verbose", no_argument, 0, 'v'}, {"version", no_argument, 0, 'V'}, {"help", no_argument, 0, 'h'}, {0, 0, 0, 0}}; - while (1) { - c = getopt_long(argc, argv, "+hVvH:P:F:u:p:n:N:t:r:e:", longopts, &option); + while (true) { + int option = 0; + int option_index = getopt_long(argc, argv, "+hVvH:P:F:u:p:n:N:t:r:e:", longopts, &option); - if (c == -1 || c == EOF || c == 1) { + if (option_index == -1 || option_index == EOF || option_index == 1) { break; } - switch (c) { + switch (option_index) { case '?': /* print short usage statement if args not parsable */ usage5(); case 'h': /* help */ -- cgit v1.2.3-74-g34f1 From 3008d521c1284f6f182d9cc10d56afdaa3978a04 Mon Sep 17 00:00:00 2001 From: Lorenz Kästle <12514511+RincewindsHat@users.noreply.github.com> Date: Wed, 12 Mar 2025 16:51:02 +0100 Subject: Refactor check_radius --- plugins/Makefile.am | 1 + plugins/check_radius.c | 126 +++++++++++++++++++++++----------------- plugins/check_radius.d/config.h | 42 ++++++++++++++ 3 files changed, 115 insertions(+), 54 deletions(-) create mode 100644 plugins/check_radius.d/config.h diff --git a/plugins/Makefile.am b/plugins/Makefile.am index 6c582a15..dacd36e8 100644 --- a/plugins/Makefile.am +++ b/plugins/Makefile.am @@ -53,6 +53,7 @@ EXTRA_DIST = t \ check_ldap.d \ check_hpjd.d \ check_game.d \ + check_radius.d \ check_nagios.d \ check_dbi.d \ check_ssh.d \ diff --git a/plugins/check_radius.c b/plugins/check_radius.c index ab7c6519..6a27e113 100644 --- a/plugins/check_radius.c +++ b/plugins/check_radius.c @@ -36,6 +36,7 @@ const char *email = "devel@monitoring-plugins.org"; #include "utils.h" #include "netutils.h" #include "states.h" +#include "check_radius.d/config.h" #if defined(HAVE_LIBRADCLI) # include @@ -47,7 +48,11 @@ const char *email = "devel@monitoring-plugins.org"; # include #endif -static int process_arguments(int /*argc*/, char ** /*argv*/); +typedef struct { + int errorcode; + check_radius_config config; +} check_radius_config_wrapper; +static check_radius_config_wrapper process_arguments(int /*argc*/, char ** /*argv*/); static void print_help(void); void print_usage(void); @@ -79,21 +84,8 @@ void print_usage(void); # define REJECT_RC BADRESP_RC #endif -static int my_rc_read_config(char * /*a*/); +static int my_rc_read_config(char * /*a*/, rc_handle ** /*rch*/); -#if defined(HAVE_LIBFREERADIUS_CLIENT) || defined(HAVE_LIBRADIUSCLIENT_NG) || defined(HAVE_LIBRADCLI) -static rc_handle *rch = NULL; -#endif - -static char *server = NULL; -static char *username = NULL; -static char *password = NULL; -static char *nasid = NULL; -static char *nasipaddress = NULL; -static char *expect = NULL; -static char *config_file = NULL; -static unsigned short port = PW_AUTH_UDP_PORT; -static int retries = 1; static bool verbose = false; /****************************************************************************** @@ -157,12 +149,20 @@ 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_radius_config_wrapper tmp_config = process_arguments(argc, argv); + + if (tmp_config.errorcode == ERROR) { usage4(_("Could not parse arguments")); } + check_radius_config config = tmp_config.config; + +#if defined(HAVE_LIBFREERADIUS_CLIENT) || defined(HAVE_LIBRADIUSCLIENT_NG) || defined(HAVE_LIBRADCLI) + rc_handle *rch = NULL; +#endif + char *str = strdup("dictionary"); - if ((config_file && my_rc_read_config(config_file)) || my_rc_read_dictionary(my_rc_conf_str(str))) { + if ((config.config_file && my_rc_read_config(config.config_file, &rch)) || my_rc_read_dictionary(my_rc_conf_str(str))) { die(STATE_UNKNOWN, _("Config file error\n")); } @@ -171,36 +171,36 @@ int main(int argc, char **argv) { SEND_DATA data; memset(&data, 0, sizeof(data)); if (!(my_rc_avpair_add(&data.send_pairs, PW_SERVICE_TYPE, &service, 0) && - my_rc_avpair_add(&data.send_pairs, PW_USER_NAME, username, 0) && - my_rc_avpair_add(&data.send_pairs, PW_USER_PASSWORD, password, 0))) { + my_rc_avpair_add(&data.send_pairs, PW_USER_NAME, config.username, 0) && + my_rc_avpair_add(&data.send_pairs, PW_USER_PASSWORD, config.password, 0))) { die(STATE_UNKNOWN, _("Out of Memory?\n")); } - if (nasid != NULL) { - if (!(my_rc_avpair_add(&data.send_pairs, PW_NAS_IDENTIFIER, nasid, 0))) { + if (config.nas_id != NULL) { + if (!(my_rc_avpair_add(&data.send_pairs, PW_NAS_IDENTIFIER, config.nas_id, 0))) { die(STATE_UNKNOWN, _("Invalid NAS-Identifier\n")); } } char name[HOST_NAME_MAX]; - if (nasipaddress == NULL) { + if (config.nas_ip_address == NULL) { if (gethostname(name, sizeof(name)) != 0) { die(STATE_UNKNOWN, _("gethostname() failed!\n")); } - nasipaddress = name; + config.nas_ip_address = name; } - struct sockaddr_storage ss; - if (!dns_lookup(nasipaddress, &ss, AF_INET)) { /* TODO: Support IPv6. */ + struct sockaddr_storage radius_server_socket; + if (!dns_lookup(config.nas_ip_address, &radius_server_socket, AF_INET)) { /* TODO: Support IPv6. */ die(STATE_UNKNOWN, _("Invalid NAS-IP-Address\n")); } - uint32_t client_id = ntohl(((struct sockaddr_in *)&ss)->sin_addr.s_addr); + uint32_t client_id = ntohl(((struct sockaddr_in *)&radius_server_socket)->sin_addr.s_addr); if (my_rc_avpair_add(&(data.send_pairs), PW_NAS_IP_ADDRESS, &client_id, 0) == NULL) { die(STATE_UNKNOWN, _("Invalid NAS-IP-Address\n")); } - my_rc_buildreq(&data, PW_ACCESS_REQUEST, server, port, (int)timeout_interval, retries); + my_rc_buildreq(&data, PW_ACCESS_REQUEST, config.server, config.port, (int)timeout_interval, config.retries); #ifdef RC_BUFFER_LEN char msg[RC_BUFFER_LEN]; @@ -208,36 +208,49 @@ int main(int argc, char **argv) { char msg[BUFFER_LEN]; #endif - mp_state_enum result = my_rc_send_server(&data, msg); + int result = my_rc_send_server(&data, msg); rc_avpair_free(data.send_pairs); if (data.receive_pairs) { rc_avpair_free(data.receive_pairs); } if (result == TIMEOUT_RC) { - die(STATE_CRITICAL, _("Timeout\n")); + printf("Timeout\n"); + exit(STATE_CRITICAL); } + if (result == ERROR_RC) { - die(STATE_CRITICAL, _("Auth Error\n")); + printf(_("Auth Error\n")); + exit(STATE_CRITICAL); } + if (result == REJECT_RC) { - die(STATE_WARNING, _("Auth Failed\n")); + printf(_("Auth Failed\n")); + exit(STATE_WARNING); } + if (result == BADRESP_RC) { - die(STATE_WARNING, _("Bad Response\n")); + printf(_("Bad Response\n")); + exit(STATE_WARNING); } - if (expect && !strstr(msg, expect)) { - die(STATE_WARNING, "%s\n", msg); + + if (config.expect && !strstr(msg, config.expect)) { + printf("%s\n", msg); + exit(STATE_WARNING); } + if (result == OK_RC) { - die(STATE_OK, _("Auth OK\n")); + printf(_("Auth OK\n")); + exit(STATE_OK); } + (void)snprintf(msg, sizeof(msg), _("Unexpected result code %d"), result); - die(STATE_UNKNOWN, "%s\n", msg); + printf("%s\n", msg); + exit(STATE_UNKNOWN); } /* process command-line arguments */ -int process_arguments(int argc, char **argv) { +check_radius_config_wrapper process_arguments(int argc, char **argv) { static struct option longopts[] = {{"hostname", required_argument, 0, 'H'}, {"port", required_argument, 0, 'P'}, {"username", required_argument, 0, 'u'}, {"password", required_argument, 0, 'p'}, {"nas-id", required_argument, 0, 'n'}, {"nas-ip-address", required_argument, 0, 'N'}, @@ -246,6 +259,11 @@ int process_arguments(int argc, char **argv) { {"verbose", no_argument, 0, 'v'}, {"version", no_argument, 0, 'V'}, {"help", no_argument, 0, 'h'}, {0, 0, 0, 0}}; + check_radius_config_wrapper result = { + .errorcode = OK, + .config = check_radius_config_init(), + }; + while (true) { int option = 0; int option_index = getopt_long(argc, argv, "+hVvH:P:F:u:p:n:N:t:r:e:", longopts, &option); @@ -270,20 +288,20 @@ int process_arguments(int argc, char **argv) { if (!is_host(optarg)) { usage2(_("Invalid hostname/address"), optarg); } - server = optarg; + result.config.server = optarg; break; case 'P': /* port */ if (is_intnonneg(optarg)) { - port = (unsigned short)atoi(optarg); + result.config.port = (unsigned short)atoi(optarg); } else { usage4(_("Port must be a positive integer")); } break; case 'u': /* username */ - username = optarg; + result.config.username = optarg; break; case 'p': /* password */ - password = strdup(optarg); + result.config.password = strdup(optarg); /* Delete the password from process list */ while (*optarg != '\0') { @@ -292,20 +310,20 @@ int process_arguments(int argc, char **argv) { } break; case 'n': /* nas id */ - nasid = optarg; + result.config.nas_id = optarg; break; case 'N': /* nas ip address */ - nasipaddress = optarg; + result.config.nas_ip_address = optarg; break; case 'F': /* configuration file */ - config_file = optarg; + result.config.config_file = optarg; break; case 'e': /* expect */ - expect = optarg; + result.config.expect = optarg; break; case 'r': /* retries */ if (is_intpos(optarg)) { - retries = atoi(optarg); + result.config.retries = atoi(optarg); } else { usage4(_("Number of retries must be a positive integer")); } @@ -320,20 +338,20 @@ int process_arguments(int argc, char **argv) { } } - if (server == NULL) { + if (result.config.server == NULL) { usage4(_("Hostname was not supplied")); } - if (username == NULL) { + if (result.config.username == NULL) { usage4(_("User not specified")); } - if (password == NULL) { + if (result.config.password == NULL) { usage4(_("Password not specified")); } - if (config_file == NULL) { + if (result.config.config_file == NULL) { usage4(_("Configuration file not specified")); } - return OK; + return result; } void print_help(void) { @@ -395,11 +413,11 @@ void print_usage(void) { progname); } -int my_rc_read_config(char *a) { +int my_rc_read_config(char *config_file_name, rc_handle **rch) { #if defined(HAVE_LIBFREERADIUS_CLIENT) || defined(HAVE_LIBRADIUSCLIENT_NG) || defined(HAVE_LIBRADCLI) - rch = rc_read_config(a); + *rch = rc_read_config(config_file_name); return (rch == NULL) ? 1 : 0; #else - return rc_read_config(a); + return rc_read_config(config_file_name); #endif } diff --git a/plugins/check_radius.d/config.h b/plugins/check_radius.d/config.h new file mode 100644 index 00000000..b27d31e7 --- /dev/null +++ b/plugins/check_radius.d/config.h @@ -0,0 +1,42 @@ +#pragma once + +#include "../../config.h" +#include +#if defined(HAVE_LIBRADCLI) +# include +#elif defined(HAVE_LIBFREERADIUS_CLIENT) +# include +#elif defined(HAVE_LIBRADIUSCLIENT_NG) +# include +#else +# include +#endif + +typedef struct { + char *server; + char *username; + char *password; + char *config_file; + char *nas_id; + char *nas_ip_address; + int retries; + unsigned short port; + + char *expect; +} check_radius_config; + +check_radius_config check_radius_config_init() { + check_radius_config tmp = { + .server = NULL, + .username = NULL, + .password = NULL, + .config_file = NULL, + .nas_id = NULL, + .nas_ip_address = NULL, + .retries = 1, + .port = PW_AUTH_UDP_PORT, + + .expect = NULL, + }; + return tmp; +} -- cgit v1.2.3-74-g34f1 From c4e2cf51cba4d62add8e689e621d979aa65278cd Mon Sep 17 00:00:00 2001 From: Lorenz Kästle <12514511+RincewindsHat@users.noreply.github.com> Date: Wed, 12 Mar 2025 16:52:51 +0100 Subject: check_radius: allow IPv6 addresses --- plugins/check_radius.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/check_radius.c b/plugins/check_radius.c index 6a27e113..cc846709 100644 --- a/plugins/check_radius.c +++ b/plugins/check_radius.c @@ -191,7 +191,7 @@ int main(int argc, char **argv) { } struct sockaddr_storage radius_server_socket; - if (!dns_lookup(config.nas_ip_address, &radius_server_socket, AF_INET)) { /* TODO: Support IPv6. */ + if (!dns_lookup(config.nas_ip_address, &radius_server_socket, AF_UNSPEC)) { die(STATE_UNKNOWN, _("Invalid NAS-IP-Address\n")); } -- cgit v1.2.3-74-g34f1 From a8b7df88113ae08d1b34f6efcd7d6d971e2b7c22 Mon Sep 17 00:00:00 2001 From: Lorenz Kästle <12514511+RincewindsHat@users.noreply.github.com> Date: Wed, 12 Mar 2025 16:54:32 +0100 Subject: check_real: clang-format --- plugins/check_real.c | 108 +++++++++++++++++++++++++++++++-------------------- 1 file changed, 65 insertions(+), 43 deletions(-) diff --git a/plugins/check_real.c b/plugins/check_real.c index 369a88b1..3737f69d 100644 --- a/plugins/check_real.c +++ b/plugins/check_real.c @@ -66,8 +66,9 @@ int main(int argc, char **argv) { /* Parse extra opts if any */ argv = np_extra_opts(&argc, argv, progname); - if (process_arguments(argc, argv) == ERROR) + if (process_arguments(argc, argv) == ERROR) { usage4(_("Could not parse arguments")); + } /* initialize alarm signal handling */ signal(SIGALRM, socket_timeout_alarm_handler); @@ -78,8 +79,9 @@ int main(int argc, char **argv) { /* try to connect to the host at the given port number */ int socket; - if (my_tcp_connect(server_address, server_port, &socket) != STATE_OK) + if (my_tcp_connect(server_address, server_port, &socket) != STATE_OK) { die(STATE_CRITICAL, _("Unable to connect to %s on port %d\n"), server_address, server_port); + } /* Part I - Server Check */ @@ -100,16 +102,18 @@ int main(int argc, char **argv) { result = recv(socket, buffer, MAX_INPUT_BUFFER - 1, 0); /* return a CRITICAL status if we couldn't read any data */ - if (result == -1) + if (result == -1) { die(STATE_CRITICAL, _("No data received from %s\n"), host_name); + } char *status_line = NULL; /* make sure we find the response we are looking for */ if (!strstr(buffer, server_expect)) { - if (server_port == PORT) + if (server_port == PORT) { printf("%s\n", _("Invalid REAL response received from host")); - else + } else { printf(_("Invalid REAL response received from host on port %d\n"), server_port); + } } else { /* else we got the REAL string, so check the return code */ @@ -119,33 +123,37 @@ int main(int argc, char **argv) { status_line = (char *)strtok(buffer, "\n"); - if (strstr(status_line, "200")) + if (strstr(status_line, "200")) { result = STATE_OK; + } /* client errors result in a warning state */ - else if (strstr(status_line, "400")) + else if (strstr(status_line, "400")) { result = STATE_WARNING; - else if (strstr(status_line, "401")) + } else if (strstr(status_line, "401")) { result = STATE_WARNING; - else if (strstr(status_line, "402")) + } else if (strstr(status_line, "402")) { result = STATE_WARNING; - else if (strstr(status_line, "403")) + } else if (strstr(status_line, "403")) { result = STATE_WARNING; - else if (strstr(status_line, "404")) + } else if (strstr(status_line, "404")) { result = STATE_WARNING; + } /* server errors result in a critical state */ - else if (strstr(status_line, "500")) + else if (strstr(status_line, "500")) { result = STATE_CRITICAL; - else if (strstr(status_line, "501")) + } else if (strstr(status_line, "501")) { result = STATE_CRITICAL; - else if (strstr(status_line, "502")) + } else if (strstr(status_line, "502")) { result = STATE_CRITICAL; - else if (strstr(status_line, "503")) + } else if (strstr(status_line, "503")) { result = STATE_CRITICAL; + } - else + else { result = STATE_UNKNOWN; + } } /* Part II - Check stream exists and is ok */ @@ -176,10 +184,11 @@ int main(int argc, char **argv) { } else { /* make sure we find the response we are looking for */ if (!strstr(buffer, server_expect)) { - if (server_port == PORT) + if (server_port == PORT) { printf("%s\n", _("Invalid REAL response received from host")); - else + } else { printf(_("Invalid REAL response received from host on port %d\n"), server_port); + } } else { /* else we got the REAL string, so check the return code */ @@ -190,33 +199,37 @@ int main(int argc, char **argv) { status_line = (char *)strtok(buffer, "\n"); - if (strstr(status_line, "200")) + if (strstr(status_line, "200")) { result = STATE_OK; + } /* client errors result in a warning state */ - else if (strstr(status_line, "400")) + else if (strstr(status_line, "400")) { result = STATE_WARNING; - else if (strstr(status_line, "401")) + } else if (strstr(status_line, "401")) { result = STATE_WARNING; - else if (strstr(status_line, "402")) + } else if (strstr(status_line, "402")) { result = STATE_WARNING; - else if (strstr(status_line, "403")) + } else if (strstr(status_line, "403")) { result = STATE_WARNING; - else if (strstr(status_line, "404")) + } else if (strstr(status_line, "404")) { result = STATE_WARNING; + } /* server errors result in a critical state */ - else if (strstr(status_line, "500")) + else if (strstr(status_line, "500")) { result = STATE_CRITICAL; - else if (strstr(status_line, "501")) + } else if (strstr(status_line, "501")) { result = STATE_CRITICAL; - else if (strstr(status_line, "502")) + } else if (strstr(status_line, "502")) { result = STATE_CRITICAL; - else if (strstr(status_line, "503")) + } else if (strstr(status_line, "503")) { result = STATE_CRITICAL; + } - else + else { result = STATE_UNKNOWN; + } } } } @@ -224,15 +237,17 @@ int main(int argc, char **argv) { /* Return results */ if (result == STATE_OK) { - if (check_critical_time && (end_time - start_time) > critical_time) + if (check_critical_time && (end_time - start_time) > critical_time) { result = STATE_CRITICAL; - else if (check_warning_time && (end_time - start_time) > warning_time) + } else if (check_warning_time && (end_time - start_time) > warning_time) { result = STATE_WARNING; + } /* Put some HTML in here to create a dynamic link */ printf(_("REAL %s - %d second response time\n"), state_text(result), (int)(end_time - start_time)); - } else + } else { printf("%s\n", status_line); + } /* close the connection */ close(socket); @@ -252,16 +267,18 @@ int process_arguments(int argc, char **argv) { {"verbose", no_argument, 0, 'v'}, {"version", no_argument, 0, 'V'}, {"help", no_argument, 0, 'h'}, {0, 0, 0, 0}}; - if (argc < 2) + if (argc < 2) { return ERROR; + } for (int i = 1; i < argc; i++) { - if (strcmp("-to", argv[i]) == 0) + if (strcmp("-to", argv[i]) == 0) { strcpy(argv[i], "-t"); - else if (strcmp("-wt", argv[i]) == 0) + } else if (strcmp("-wt", argv[i]) == 0) { strcpy(argv[i], "-w"); - else if (strcmp("-ct", argv[i]) == 0) + } else if (strcmp("-ct", argv[i]) == 0) { strcpy(argv[i], "-c"); + } } int option_char; @@ -269,18 +286,20 @@ int process_arguments(int argc, char **argv) { int option = 0; option_char = getopt_long(argc, argv, "+hvVI:H:e:u:p:w:c:t:", longopts, &option); - if (option_char == -1 || option_char == EOF) + if (option_char == -1 || option_char == EOF) { break; + } switch (option_char) { case 'I': /* hostname */ case 'H': /* hostname */ - if (server_address) + if (server_address) { break; - else if (is_host(optarg)) + } else if (is_host(optarg)) { server_address = optarg; - else + } else { usage2(_("Invalid hostname/address"), optarg); + } break; case 'e': /* string to expect in response header */ server_expect = optarg; @@ -341,14 +360,17 @@ int process_arguments(int argc, char **argv) { } } - if (server_address == NULL) + if (server_address == NULL) { usage4(_("You must provide a server to check")); + } - if (host_name == NULL) + if (host_name == NULL) { host_name = strdup(server_address); + } - if (server_expect == NULL) + if (server_expect == NULL) { server_expect = strdup(EXPECT); + } return OK; } -- cgit v1.2.3-74-g34f1 From 97e65dddbda048f10b58ef8d190f2c0146a164a0 Mon Sep 17 00:00:00 2001 From: Lorenz Kästle <12514511+RincewindsHat@users.noreply.github.com> Date: Wed, 12 Mar 2025 17:22:17 +0100 Subject: Refactor check_real --- plugins/Makefile.am | 1 + plugins/check_real.c | 167 +++++++++++++++++++++++------------------- plugins/check_real.d/config.h | 37 ++++++++++ 3 files changed, 130 insertions(+), 75 deletions(-) create mode 100644 plugins/check_real.d/config.h diff --git a/plugins/Makefile.am b/plugins/Makefile.am index 6c582a15..3269b9fb 100644 --- a/plugins/Makefile.am +++ b/plugins/Makefile.am @@ -55,6 +55,7 @@ EXTRA_DIST = t \ check_game.d \ check_nagios.d \ check_dbi.d \ + check_real.d \ check_ssh.d \ check_nt.d \ check_dns.d \ diff --git a/plugins/check_real.c b/plugins/check_real.c index 3737f69d..ec0928ed 100644 --- a/plugins/check_real.c +++ b/plugins/check_real.c @@ -28,6 +28,8 @@ * *****************************************************************************/ +#include "states.h" +#include const char *progname = "check_real"; const char *copyright = "2000-2024"; const char *email = "devel@monitoring-plugins.org"; @@ -35,27 +37,20 @@ const char *email = "devel@monitoring-plugins.org"; #include "common.h" #include "netutils.h" #include "utils.h" - -enum { - PORT = 554 -}; +#include "check_real.d/config.h" #define EXPECT "RTSP/1." #define URL "" -static int process_arguments(int, char **); +typedef struct { + int errorcode; + check_real_config config; +} check_real_config_wrapper; +static check_real_config_wrapper process_arguments(int /*argc*/, char ** /*argv*/); + static void print_help(void); void print_usage(void); -static int server_port = PORT; -static char *server_address; -static char *host_name; -static char *server_url = NULL; -static char *server_expect; -static int warning_time = 0; -static bool check_warning_time = false; -static int critical_time = 0; -static bool check_critical_time = false; static bool verbose = false; int main(int argc, char **argv) { @@ -66,10 +61,13 @@ 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_real_config_wrapper tmp_config = process_arguments(argc, argv); + if (tmp_config.errorcode == ERROR) { usage4(_("Could not parse arguments")); } + const check_real_config config = tmp_config.config; + /* initialize alarm signal handling */ signal(SIGALRM, socket_timeout_alarm_handler); @@ -79,40 +77,50 @@ int main(int argc, char **argv) { /* try to connect to the host at the given port number */ int socket; - if (my_tcp_connect(server_address, server_port, &socket) != STATE_OK) { - die(STATE_CRITICAL, _("Unable to connect to %s on port %d\n"), server_address, server_port); + if (my_tcp_connect(config.server_address, config.server_port, &socket) != STATE_OK) { + die(STATE_CRITICAL, _("Unable to connect to %s on port %d\n"), config.server_address, config.server_port); } /* Part I - Server Check */ /* send the OPTIONS request */ char buffer[MAX_INPUT_BUFFER]; - sprintf(buffer, "OPTIONS rtsp://%s:%d RTSP/1.0\r\n", host_name, server_port); - int result = send(socket, buffer, strlen(buffer), 0); + sprintf(buffer, "OPTIONS rtsp://%s:%d RTSP/1.0\r\n", config.host_name, config.server_port); + ssize_t sent_bytes = send(socket, buffer, strlen(buffer), 0); + if (sent_bytes == -1) { + die(STATE_CRITICAL, _("Sending options to %s failed\n"), config.host_name); + } /* send the header sync */ sprintf(buffer, "CSeq: 1\r\n"); - result = send(socket, buffer, strlen(buffer), 0); + sent_bytes = send(socket, buffer, strlen(buffer), 0); + if (sent_bytes == -1) { + die(STATE_CRITICAL, _("Sending header sync to %s failed\n"), config.host_name); + } /* send a newline so the server knows we're done with the request */ sprintf(buffer, "\r\n"); - result = send(socket, buffer, strlen(buffer), 0); + sent_bytes = send(socket, buffer, strlen(buffer), 0); + if (sent_bytes == -1) { + die(STATE_CRITICAL, _("Sending newline to %s failed\n"), config.host_name); + } /* watch for the REAL connection string */ - result = recv(socket, buffer, MAX_INPUT_BUFFER - 1, 0); + ssize_t received_bytes = recv(socket, buffer, MAX_INPUT_BUFFER - 1, 0); /* return a CRITICAL status if we couldn't read any data */ - if (result == -1) { - die(STATE_CRITICAL, _("No data received from %s\n"), host_name); + if (received_bytes == -1) { + die(STATE_CRITICAL, _("No data received from %s\n"), config.host_name); } + mp_state_enum result = STATE_OK; char *status_line = NULL; /* make sure we find the response we are looking for */ - if (!strstr(buffer, server_expect)) { - if (server_port == PORT) { + if (!strstr(buffer, config.server_expect)) { + if (config.server_port == PORT) { printf("%s\n", _("Invalid REAL response received from host")); } else { - printf(_("Invalid REAL response received from host on port %d\n"), server_port); + printf(_("Invalid REAL response received from host on port %d\n"), config.server_port); } } else { /* else we got the REAL string, so check the return code */ @@ -121,7 +129,7 @@ int main(int argc, char **argv) { result = STATE_OK; - status_line = (char *)strtok(buffer, "\n"); + status_line = strtok(buffer, "\n"); if (strstr(status_line, "200")) { result = STATE_OK; @@ -138,10 +146,8 @@ int main(int argc, char **argv) { result = STATE_WARNING; } else if (strstr(status_line, "404")) { result = STATE_WARNING; - } - - /* server errors result in a critical state */ - else if (strstr(status_line, "500")) { + } else if (strstr(status_line, "500")) { + /* server errors result in a critical state */ result = STATE_CRITICAL; } else if (strstr(status_line, "501")) { result = STATE_CRITICAL; @@ -149,45 +155,52 @@ int main(int argc, char **argv) { result = STATE_CRITICAL; } else if (strstr(status_line, "503")) { result = STATE_CRITICAL; - } - - else { + } else { result = STATE_UNKNOWN; } } /* Part II - Check stream exists and is ok */ - if ((result == STATE_OK) && (server_url != NULL)) { + if ((result == STATE_OK) && (config.server_url != NULL)) { /* Part I - Server Check */ /* send the DESCRIBE request */ - sprintf(buffer, "DESCRIBE rtsp://%s:%d%s RTSP/1.0\r\n", host_name, server_port, server_url); - result = send(socket, buffer, strlen(buffer), 0); + sprintf(buffer, "DESCRIBE rtsp://%s:%d%s RTSP/1.0\r\n", config.host_name, config.server_port, config.server_url); + + ssize_t sent_bytes = send(socket, buffer, strlen(buffer), 0); + if (sent_bytes == -1) { + die(STATE_CRITICAL, _("Sending DESCRIBE request to %s failed\n"), config.host_name); + } /* send the header sync */ sprintf(buffer, "CSeq: 2\r\n"); - result = send(socket, buffer, strlen(buffer), 0); + sent_bytes = send(socket, buffer, strlen(buffer), 0); + if (sent_bytes == -1) { + die(STATE_CRITICAL, _("Sending DESCRIBE request to %s failed\n"), config.host_name); + } /* send a newline so the server knows we're done with the request */ sprintf(buffer, "\r\n"); - result = send(socket, buffer, strlen(buffer), 0); + sent_bytes = send(socket, buffer, strlen(buffer), 0); + if (sent_bytes == -1) { + die(STATE_CRITICAL, _("Sending DESCRIBE request to %s failed\n"), config.host_name); + } /* watch for the REAL connection string */ - result = recv(socket, buffer, MAX_INPUT_BUFFER - 1, 0); - buffer[result] = '\0'; /* null terminate received buffer */ - - /* return a CRITICAL status if we couldn't read any data */ - if (result == -1) { + ssize_t recv_bytes = recv(socket, buffer, MAX_INPUT_BUFFER - 1, 0); + if (recv_bytes == -1) { + /* return a CRITICAL status if we couldn't read any data */ printf(_("No data received from host\n")); result = STATE_CRITICAL; } else { + buffer[result] = '\0'; /* null terminate received buffer */ /* make sure we find the response we are looking for */ - if (!strstr(buffer, server_expect)) { - if (server_port == PORT) { + if (!strstr(buffer, config.server_expect)) { + if (config.server_port == PORT) { printf("%s\n", _("Invalid REAL response received from host")); } else { - printf(_("Invalid REAL response received from host on port %d\n"), server_port); + printf(_("Invalid REAL response received from host on port %d\n"), config.server_port); } } else { @@ -197,7 +210,7 @@ int main(int argc, char **argv) { result = STATE_OK; - status_line = (char *)strtok(buffer, "\n"); + status_line = strtok(buffer, "\n"); if (strstr(status_line, "200")) { result = STATE_OK; @@ -236,10 +249,9 @@ int main(int argc, char **argv) { /* Return results */ if (result == STATE_OK) { - - if (check_critical_time && (end_time - start_time) > critical_time) { + if (config.check_critical_time && (end_time - start_time) > config.critical_time) { result = STATE_CRITICAL; - } else if (check_warning_time && (end_time - start_time) > warning_time) { + } else if (config.check_warning_time && (end_time - start_time) > config.warning_time) { result = STATE_WARNING; } @@ -255,11 +267,11 @@ int main(int argc, char **argv) { /* reset the alarm */ alarm(0); - return result; + exit(result); } /* process command-line arguments */ -int process_arguments(int argc, char **argv) { +check_real_config_wrapper process_arguments(int argc, char **argv) { static struct option longopts[] = {{"hostname", required_argument, 0, 'H'}, {"IPaddress", required_argument, 0, 'I'}, {"expect", required_argument, 0, 'e'}, {"url", required_argument, 0, 'u'}, {"port", required_argument, 0, 'p'}, {"critical", required_argument, 0, 'c'}, @@ -267,8 +279,14 @@ int process_arguments(int argc, char **argv) { {"verbose", no_argument, 0, 'v'}, {"version", no_argument, 0, 'V'}, {"help", no_argument, 0, 'h'}, {0, 0, 0, 0}}; + check_real_config_wrapper result = { + .errorcode = OK, + .config = check_real_config_init(), + }; + if (argc < 2) { - return ERROR; + result.errorcode = ERROR; + return result; } for (int i = 1; i < argc; i++) { @@ -281,10 +299,9 @@ int process_arguments(int argc, char **argv) { } } - int option_char; while (true) { int option = 0; - option_char = getopt_long(argc, argv, "+hvVI:H:e:u:p:w:c:t:", longopts, &option); + int option_char = getopt_long(argc, argv, "+hvVI:H:e:u:p:w:c:t:", longopts, &option); if (option_char == -1 || option_char == EOF) { break; @@ -293,39 +310,39 @@ int process_arguments(int argc, char **argv) { switch (option_char) { case 'I': /* hostname */ case 'H': /* hostname */ - if (server_address) { + if (result.config.server_address) { break; } else if (is_host(optarg)) { - server_address = optarg; + result.config.server_address = optarg; } else { usage2(_("Invalid hostname/address"), optarg); } break; case 'e': /* string to expect in response header */ - server_expect = optarg; + result.config.server_expect = optarg; break; case 'u': /* server URL */ - server_url = optarg; + result.config.server_url = optarg; break; case 'p': /* port */ if (is_intpos(optarg)) { - server_port = atoi(optarg); + result.config.server_port = atoi(optarg); } else { usage4(_("Port must be a positive integer")); } break; case 'w': /* warning time threshold */ if (is_intnonneg(optarg)) { - warning_time = atoi(optarg); - check_warning_time = true; + result.config.warning_time = atoi(optarg); + result.config.check_warning_time = true; } else { usage4(_("Warning time must be a positive integer")); } break; case 'c': /* critical time threshold */ if (is_intnonneg(optarg)) { - critical_time = atoi(optarg); - check_critical_time = true; + result.config.critical_time = atoi(optarg); + result.config.check_critical_time = true; } else { usage4(_("Critical time must be a positive integer")); } @@ -351,28 +368,28 @@ int process_arguments(int argc, char **argv) { } } - option_char = optind; - if (server_address == NULL && argc > option_char) { + int option_char = optind; + if (result.config.server_address == NULL && argc > option_char) { if (is_host(argv[option_char])) { - server_address = argv[option_char++]; + result.config.server_address = argv[option_char++]; } else { usage2(_("Invalid hostname/address"), argv[option_char]); } } - if (server_address == NULL) { + if (result.config.server_address == NULL) { usage4(_("You must provide a server to check")); } - if (host_name == NULL) { - host_name = strdup(server_address); + if (result.config.host_name == NULL) { + result.config.host_name = strdup(result.config.server_address); } - if (server_expect == NULL) { - server_expect = strdup(EXPECT); + if (result.config.server_expect == NULL) { + result.config.server_expect = strdup(EXPECT); } - return OK; + return result; } void print_help(void) { diff --git a/plugins/check_real.d/config.h b/plugins/check_real.d/config.h new file mode 100644 index 00000000..c4663cf9 --- /dev/null +++ b/plugins/check_real.d/config.h @@ -0,0 +1,37 @@ +#pragma once + +#include "../../config.h" +#include + +enum { + PORT = 554 +}; + +typedef struct { + char *server_address; + char *host_name; + int server_port; + char *server_url; + + char *server_expect; + int warning_time; + bool check_warning_time; + int critical_time; + bool check_critical_time; +} check_real_config; + +check_real_config check_real_config_init() { + check_real_config tmp = { + .server_address = NULL, + .host_name = NULL, + .server_port = PORT, + .server_url = NULL, + + .server_expect = NULL, + .warning_time = 0, + .check_warning_time = false, + .critical_time = 0, + .check_critical_time = false, + }; + return tmp; +} -- cgit v1.2.3-74-g34f1 From a609c0214fb4fbeb86ab75e7dff4f4c7deedcc3b Mon Sep 17 00:00:00 2001 From: Lorenz Kästle <12514511+RincewindsHat@users.noreply.github.com> Date: Wed, 12 Mar 2025 16:16:53 +0100 Subject: remove nagios reference Narrow down sscanf expression --- plugins/check_ping.c | 49 +++++++++++++++++++++++++------------------------ 1 file changed, 25 insertions(+), 24 deletions(-) diff --git a/plugins/check_ping.c b/plugins/check_ping.c index fcf68f81..8d8ae7df 100644 --- a/plugins/check_ping.c +++ b/plugins/check_ping.c @@ -162,8 +162,8 @@ int main(int argc, char **argv) { /* Print performance data */ if (pinged.packet_loss != 100) { - printf("|%s", fperfdata("rta", pinged.round_trip_average, "ms", (bool)(config.wrta > 0), config.wrta, - (bool)(config.crta > 0), config.crta, true, 0, false, 0)); + printf("|%s", fperfdata("rta", pinged.round_trip_average, "ms", (bool)(config.wrta > 0), config.wrta, (bool)(config.crta > 0), + config.crta, true, 0, false, 0)); } else { printf("| rta=U;%f;%f;;", config.wrta, config.crta); } @@ -470,33 +470,36 @@ ping_result run_ping(const char *cmd, const char *addr, double crta) { /* get the percent loss statistics */ int match = 0; - if ((sscanf(buf, "%*d packets transmitted, %*d packets received, +%*d errors, %d%% packet loss%n", &result.packet_loss, &match) && + if ((sscanf(buf, "%*d packets transmitted, %*d packets received, +%*d errors, %d%% packet loss%n", &result.packet_loss, &match) == + 1 && match) || (sscanf(buf, "%*d packets transmitted, %*d packets received, +%*d duplicates, %d%% packet loss%n", &result.packet_loss, - &match) && + &match) == 1 && match) || - (sscanf(buf, "%*d packets transmitted, %*d received, +%*d duplicates, %d%% packet loss%n", &result.packet_loss, &match) && + (sscanf(buf, "%*d packets transmitted, %*d received, +%*d duplicates, %d%% packet loss%n", &result.packet_loss, &match) == 1 && match) || - (sscanf(buf, "%*d packets transmitted, %*d packets received, %d%% packet loss%n", &result.packet_loss, &match) && match) || - (sscanf(buf, "%*d packets transmitted, %*d packets received, %d%% loss, time%n", &result.packet_loss, &match) && match) || - (sscanf(buf, "%*d packets transmitted, %*d received, %d%% loss, time%n", &result.packet_loss, &match) && match) || - (sscanf(buf, "%*d packets transmitted, %*d received, %d%% packet loss, time%n", &result.packet_loss, &match) && match) || - (sscanf(buf, "%*d packets transmitted, %*d received, +%*d errors, %d%% packet loss%n", &result.packet_loss, &match) && match) || - (sscanf(buf, "%*d packets transmitted %*d received, +%*d errors, %d%% packet loss%n", &result.packet_loss, &match) && match) || - (sscanf(buf, "%*[^(](%d%% %*[^)])%n", &result.packet_loss, &match) && match)) { + (sscanf(buf, "%*d packets transmitted, %*d packets received, %d%% packet loss%n", &result.packet_loss, &match) == 1 && match) || + (sscanf(buf, "%*d packets transmitted, %*d packets received, %d%% loss, time%n", &result.packet_loss, &match) == 1 && match) || + (sscanf(buf, "%*d packets transmitted, %*d received, %d%% loss, time%n", &result.packet_loss, &match) == 1 && match) || + (sscanf(buf, "%*d packets transmitted, %*d received, %d%% packet loss, time%n", &result.packet_loss, &match) && match) == 1 || + (sscanf(buf, "%*d packets transmitted, %*d received, +%*d errors, %d%% packet loss%n", &result.packet_loss, &match) == 1 && + match) || + (sscanf(buf, "%*d packets transmitted %*d received, +%*d errors, %d%% packet loss%n", &result.packet_loss, &match) == 1 && + match) || + (sscanf(buf, "%*[^(](%d%% %*[^)])%n", &result.packet_loss, &match) == 1 && match)) { continue; } /* get the round trip average */ - if ((sscanf(buf, "round-trip min/avg/max = %*f/%lf/%*f%n", &result.round_trip_average, &match) && match) || - (sscanf(buf, "round-trip min/avg/max/mdev = %*f/%lf/%*f/%*f%n", &result.round_trip_average, &match) && match) || - (sscanf(buf, "round-trip min/avg/max/sdev = %*f/%lf/%*f/%*f%n", &result.round_trip_average, &match) && match) || - (sscanf(buf, "round-trip min/avg/max/stddev = %*f/%lf/%*f/%*f%n", &result.round_trip_average, &match) && match) || - (sscanf(buf, "round-trip min/avg/max/std-dev = %*f/%lf/%*f/%*f%n", &result.round_trip_average, &match) && match) || - (sscanf(buf, "round-trip (ms) min/avg/max = %*f/%lf/%*f%n", &result.round_trip_average, &match) && match) || - (sscanf(buf, "round-trip (ms) min/avg/max/stddev = %*f/%lf/%*f/%*f%n", &result.round_trip_average, &match) && match) || - (sscanf(buf, "rtt min/avg/max/mdev = %*f/%lf/%*f/%*f ms%n", &result.round_trip_average, &match) && match) || - (sscanf(buf, "%*[^=] = %*fms, %*[^=] = %*fms, %*[^=] = %lfms%n", &result.round_trip_average, &match) && match)) { + if ((sscanf(buf, "round-trip min/avg/max = %*f/%lf/%*f%n", &result.round_trip_average, &match) == 1 && match) || + (sscanf(buf, "round-trip min/avg/max/mdev = %*f/%lf/%*f/%*f%n", &result.round_trip_average, &match) == 1 && match) || + (sscanf(buf, "round-trip min/avg/max/sdev = %*f/%lf/%*f/%*f%n", &result.round_trip_average, &match) == 1 && match) || + (sscanf(buf, "round-trip min/avg/max/stddev = %*f/%lf/%*f/%*f%n", &result.round_trip_average, &match) == 1 && match) || + (sscanf(buf, "round-trip min/avg/max/std-dev = %*f/%lf/%*f/%*f%n", &result.round_trip_average, &match) == 1 && match) || + (sscanf(buf, "round-trip (ms) min/avg/max = %*f/%lf/%*f%n", &result.round_trip_average, &match) == 1 && match) || + (sscanf(buf, "round-trip (ms) min/avg/max/stddev = %*f/%lf/%*f/%*f%n", &result.round_trip_average, &match) == 1 && match) || + (sscanf(buf, "rtt min/avg/max/mdev = %*f/%lf/%*f/%*f ms%n", &result.round_trip_average, &match) == 1 && match) || + (sscanf(buf, "%*[^=] = %*fms, %*[^=] = %*fms, %*[^=] = %lfms%n", &result.round_trip_average, &match) == 1 && match)) { continue; } } @@ -610,9 +613,7 @@ void print_help(void) { printf("\n"); printf("%s\n", _("This plugin uses the ping command to probe the specified host for packet loss")); - printf("%s\n", _("(percentage) and round trip average (milliseconds). It can produce HTML output")); - printf("%s\n", _("linking to a traceroute CGI contributed by Ian Cass. The CGI can be found in")); - printf("%s\n", _("the contrib area of the downloads section at http://www.nagios.org/")); + printf("%s\n", _("(percentage) and round trip average (milliseconds). It can produce HTML output.")); printf(UT_SUPPORT); } -- cgit v1.2.3-74-g34f1 From 04c5e4024fd922cdae4b6b302668af44187c1193 Mon Sep 17 00:00:00 2001 From: Lorenz Kästle <12514511+RincewindsHat@users.noreply.github.com> Date: Wed, 12 Mar 2025 17:26:32 +0100 Subject: Fix another sscanf instance --- plugins/check_ping.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/plugins/check_ping.c b/plugins/check_ping.c index 8d8ae7df..940b9475 100644 --- a/plugins/check_ping.c +++ b/plugins/check_ping.c @@ -481,7 +481,8 @@ ping_result run_ping(const char *cmd, const char *addr, double crta) { (sscanf(buf, "%*d packets transmitted, %*d packets received, %d%% packet loss%n", &result.packet_loss, &match) == 1 && match) || (sscanf(buf, "%*d packets transmitted, %*d packets received, %d%% loss, time%n", &result.packet_loss, &match) == 1 && match) || (sscanf(buf, "%*d packets transmitted, %*d received, %d%% loss, time%n", &result.packet_loss, &match) == 1 && match) || - (sscanf(buf, "%*d packets transmitted, %*d received, %d%% packet loss, time%n", &result.packet_loss, &match) && match) == 1 || + (sscanf(buf, "%*d packets transmitted, %*d received, %d%% packet loss, time%n", &result.packet_loss, &match) == 1 && match) == + 1 || (sscanf(buf, "%*d packets transmitted, %*d received, +%*d errors, %d%% packet loss%n", &result.packet_loss, &match) == 1 && match) || (sscanf(buf, "%*d packets transmitted %*d received, +%*d errors, %d%% packet loss%n", &result.packet_loss, &match) == 1 && -- cgit v1.2.3-74-g34f1 From 53e102b6ace40138df373e078916d1a345ec5aa0 Mon Sep 17 00:00:00 2001 From: Lorenz Kästle <12514511+RincewindsHat@users.noreply.github.com> Date: Wed, 12 Mar 2025 18:01:31 +0100 Subject: check_time: clang-format --- plugins/check_time.c | 85 +++++++++++++++++++++++++++++++--------------------- 1 file changed, 51 insertions(+), 34 deletions(-) diff --git a/plugins/check_time.c b/plugins/check_time.c index d1f50683..02b152c0 100644 --- a/plugins/check_time.c +++ b/plugins/check_time.c @@ -68,8 +68,9 @@ int main(int argc, char **argv) { /* Parse extra opts if any */ argv = np_extra_opts(&argc, argv, progname); - if (process_arguments(argc, argv) == ERROR) + if (process_arguments(argc, argv) == ERROR) { usage4(_("Could not parse arguments")); + } /* initialize alarm signal handling */ signal(SIGALRM, socket_timeout_alarm_handler); @@ -88,23 +89,25 @@ int main(int argc, char **argv) { } if (result != STATE_OK) { - if (check_critical_time) + if (check_critical_time) { result = STATE_CRITICAL; - else if (check_warning_time) + } else if (check_warning_time) { result = STATE_WARNING; - else + } else { result = STATE_UNKNOWN; + } die(result, _("TIME UNKNOWN - could not connect to server %s, port %d\n"), server_address, server_port); } if (use_udp) { if (send(socket, "", 0, 0) < 0) { - if (check_critical_time) + if (check_critical_time) { result = STATE_CRITICAL; - else if (check_warning_time) + } else if (check_warning_time) { result = STATE_WARNING; - else + } else { result = STATE_UNKNOWN; + } die(result, _("TIME UNKNOWN - could not send UDP request to server %s, port %d\n"), server_address, server_port); } } @@ -121,38 +124,43 @@ int main(int argc, char **argv) { /* return a WARNING status if we couldn't read any data */ if (result <= 0) { - if (check_critical_time) + if (check_critical_time) { result = STATE_CRITICAL; - else if (check_warning_time) + } else if (check_warning_time) { result = STATE_WARNING; - else + } else { result = STATE_UNKNOWN; + } die(result, _("TIME UNKNOWN - no data received from server %s, port %d\n"), server_address, server_port); } result = STATE_OK; time_t conntime = (end_time - start_time); - if (check_critical_time && conntime > critical_time) + if (check_critical_time && conntime > critical_time) { result = STATE_CRITICAL; - else if (check_warning_time && conntime > warning_time) + } else if (check_warning_time && conntime > warning_time) { result = STATE_WARNING; + } - if (result != STATE_OK) + if (result != STATE_OK) { die(result, _("TIME %s - %d second response time|%s\n"), state_text(result), (int)conntime, perfdata("time", (long)conntime, "s", check_warning_time, (long)warning_time, check_critical_time, (long)critical_time, true, 0, false, 0)); + } server_time = ntohl(raw_server_time) - UNIX_EPOCH; - if (server_time > (unsigned long)end_time) + if (server_time > (unsigned long)end_time) { diff_time = server_time - (unsigned long)end_time; - else + } else { diff_time = (unsigned long)end_time - server_time; + } - if (check_critical_diff && diff_time > critical_diff) + if (check_critical_diff && diff_time > critical_diff) { result = STATE_CRITICAL; - else if (check_warning_diff && diff_time > warning_diff) + } else if (check_warning_diff && diff_time > warning_diff) { result = STATE_WARNING; + } printf(_("TIME %s - %lu second time difference|%s %s\n"), state_text(result), diff_time, perfdata("time", (long)conntime, "s", check_warning_time, (long)warning_time, check_critical_time, (long)critical_time, true, 0, @@ -175,20 +183,22 @@ int process_arguments(int argc, char **argv) { {"help", no_argument, 0, 'h'}, {0, 0, 0, 0}}; - if (argc < 2) + if (argc < 2) { usage("\n"); + } for (int i = 1; i < argc; i++) { - if (strcmp("-to", argv[i]) == 0) + if (strcmp("-to", argv[i]) == 0) { strcpy(argv[i], "-t"); - else if (strcmp("-wd", argv[i]) == 0) + } else if (strcmp("-wd", argv[i]) == 0) { strcpy(argv[i], "-w"); - else if (strcmp("-cd", argv[i]) == 0) + } else if (strcmp("-cd", argv[i]) == 0) { strcpy(argv[i], "-c"); - else if (strcmp("-wt", argv[i]) == 0) + } else if (strcmp("-wt", argv[i]) == 0) { strcpy(argv[i], "-W"); - else if (strcmp("-ct", argv[i]) == 0) + } else if (strcmp("-ct", argv[i]) == 0) { strcpy(argv[i], "-C"); + } } int option_char; @@ -196,8 +206,9 @@ int process_arguments(int argc, char **argv) { int option = 0; option_char = getopt_long(argc, argv, "hVH:w:c:W:C:p:t:u", longopts, &option); - if (option_char == -1 || option_char == EOF) + if (option_char == -1 || option_char == EOF) { break; + } switch (option_char) { case '?': /* print short usage statement if args not parsable */ @@ -209,8 +220,9 @@ int process_arguments(int argc, char **argv) { print_revision(progname, NP_VERSION); exit(STATE_UNKNOWN); case 'H': /* hostname */ - if (!is_host(optarg)) + if (!is_host(optarg)) { usage2(_("Invalid hostname/address"), optarg); + } server_address = optarg; break; case 'w': /* warning-variance */ @@ -244,30 +256,34 @@ int process_arguments(int argc, char **argv) { } break; case 'W': /* warning-connect */ - if (!is_intnonneg(optarg)) + if (!is_intnonneg(optarg)) { usage4(_("Warning threshold must be a positive integer")); - else + } else { warning_time = atoi(optarg); + } check_warning_time = true; break; case 'C': /* critical-connect */ - if (!is_intnonneg(optarg)) + if (!is_intnonneg(optarg)) { usage4(_("Critical threshold must be a positive integer")); - else + } else { critical_time = atoi(optarg); + } check_critical_time = true; break; case 'p': /* port */ - if (!is_intnonneg(optarg)) + if (!is_intnonneg(optarg)) { usage4(_("Port must be a positive integer")); - else + } else { server_port = atoi(optarg); + } break; case 't': /* timeout */ - if (!is_intnonneg(optarg)) + if (!is_intnonneg(optarg)) { usage2(_("Timeout interval must be a positive integer"), optarg); - else + } else { socket_timeout = atoi(optarg); + } break; case 'u': /* udp */ use_udp = true; @@ -277,8 +293,9 @@ int process_arguments(int argc, char **argv) { option_char = optind; if (server_address == NULL) { if (argc > option_char) { - if (!is_host(argv[option_char])) + if (!is_host(argv[option_char])) { usage2(_("Invalid hostname/address"), optarg); + } server_address = argv[option_char]; } else { usage4(_("Hostname was not supplied")); -- cgit v1.2.3-74-g34f1 From 2d70bd3bc09ff95cd8525449925938ebf56cbfbb Mon Sep 17 00:00:00 2001 From: Lorenz Kästle <12514511+RincewindsHat@users.noreply.github.com> Date: Wed, 12 Mar 2025 18:14:54 +0100 Subject: Refactor check_time --- plugins/Makefile.am | 1 + plugins/check_time.c | 128 +++++++++++++++++++++--------------------- plugins/check_time.d/config.h | 42 ++++++++++++++ 3 files changed, 107 insertions(+), 64 deletions(-) create mode 100644 plugins/check_time.d/config.h diff --git a/plugins/Makefile.am b/plugins/Makefile.am index bb3f029e..5d03f160 100644 --- a/plugins/Makefile.am +++ b/plugins/Makefile.am @@ -54,6 +54,7 @@ EXTRA_DIST = t \ check_hpjd.d \ check_game.d \ check_radius.d \ + check_time.d \ check_nagios.d \ check_dbi.d \ check_real.d \ diff --git a/plugins/check_time.c b/plugins/check_time.c index 02b152c0..debf59f3 100644 --- a/plugins/check_time.c +++ b/plugins/check_time.c @@ -28,6 +28,7 @@ * *****************************************************************************/ +#include "states.h" const char *progname = "check_time"; const char *copyright = "1999-2024"; const char *email = "devel@monitoring-plugins.org"; @@ -35,28 +36,15 @@ const char *email = "devel@monitoring-plugins.org"; #include "common.h" #include "netutils.h" #include "utils.h" - -enum { - TIME_PORT = 37 -}; +#include "check_time.d/config.h" #define UNIX_EPOCH 2208988800UL -static uint32_t raw_server_time; -static unsigned long server_time, diff_time; -static int warning_time = 0; -static bool check_warning_time = false; -static int critical_time = 0; -static bool check_critical_time = false; -static unsigned long warning_diff = 0; -static bool check_warning_diff = false; -static unsigned long critical_diff = 0; -static bool check_critical_diff = false; -static int server_port = TIME_PORT; -static char *server_address = NULL; -static bool use_udp = false; - -static int process_arguments(int, char **); +typedef struct { + int errorcode; + check_time_config config; +} check_time_config_wrapper; +static check_time_config_wrapper process_arguments(int /*argc*/, char ** /*argv*/); static void print_help(void); void print_usage(void); @@ -68,10 +56,13 @@ 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_time_config_wrapper tmp_config = process_arguments(argc, argv); + if (tmp_config.errorcode == ERROR) { usage4(_("Could not parse arguments")); } + const check_time_config config = tmp_config.config; + /* initialize alarm signal handling */ signal(SIGALRM, socket_timeout_alarm_handler); @@ -80,39 +71,40 @@ int main(int argc, char **argv) { time(&start_time); int socket; - int result = STATE_UNKNOWN; + mp_state_enum result = STATE_UNKNOWN; /* try to connect to the host at the given port number */ - if (use_udp) { - result = my_udp_connect(server_address, server_port, &socket); + if (config.use_udp) { + result = my_udp_connect(config.server_address, config.server_port, &socket); } else { - result = my_tcp_connect(server_address, server_port, &socket); + result = my_tcp_connect(config.server_address, config.server_port, &socket); } if (result != STATE_OK) { - if (check_critical_time) { + if (config.check_critical_time) { result = STATE_CRITICAL; - } else if (check_warning_time) { + } else if (config.check_warning_time) { result = STATE_WARNING; } else { result = STATE_UNKNOWN; } - die(result, _("TIME UNKNOWN - could not connect to server %s, port %d\n"), server_address, server_port); + die(result, _("TIME UNKNOWN - could not connect to server %s, port %d\n"), config.server_address, config.server_port); } - if (use_udp) { + if (config.use_udp) { if (send(socket, "", 0, 0) < 0) { - if (check_critical_time) { + if (config.check_critical_time) { result = STATE_CRITICAL; - } else if (check_warning_time) { + } else if (config.check_warning_time) { result = STATE_WARNING; } else { result = STATE_UNKNOWN; } - die(result, _("TIME UNKNOWN - could not send UDP request to server %s, port %d\n"), server_address, server_port); + die(result, _("TIME UNKNOWN - could not send UDP request to server %s, port %d\n"), config.server_address, config.server_port); } } /* watch for the connection string */ + uint32_t raw_server_time; result = recv(socket, (void *)&raw_server_time, sizeof(raw_server_time), 0); /* close the connection */ @@ -124,31 +116,33 @@ int main(int argc, char **argv) { /* return a WARNING status if we couldn't read any data */ if (result <= 0) { - if (check_critical_time) { + if (config.check_critical_time) { result = STATE_CRITICAL; - } else if (check_warning_time) { + } else if (config.check_warning_time) { result = STATE_WARNING; } else { result = STATE_UNKNOWN; } - die(result, _("TIME UNKNOWN - no data received from server %s, port %d\n"), server_address, server_port); + die(result, _("TIME UNKNOWN - no data received from server %s, port %d\n"), config.server_address, config.server_port); } result = STATE_OK; time_t conntime = (end_time - start_time); - if (check_critical_time && conntime > critical_time) { + if (config.check_critical_time && conntime > config.critical_time) { result = STATE_CRITICAL; - } else if (check_warning_time && conntime > warning_time) { + } else if (config.check_warning_time && conntime > config.warning_time) { result = STATE_WARNING; } if (result != STATE_OK) { die(result, _("TIME %s - %d second response time|%s\n"), state_text(result), (int)conntime, - perfdata("time", (long)conntime, "s", check_warning_time, (long)warning_time, check_critical_time, (long)critical_time, true, 0, - false, 0)); + perfdata("time", (long)conntime, "s", config.check_warning_time, (long)config.warning_time, config.check_critical_time, + (long)config.critical_time, true, 0, false, 0)); } + unsigned long server_time; + unsigned long diff_time; server_time = ntohl(raw_server_time) - UNIX_EPOCH; if (server_time > (unsigned long)end_time) { diff_time = server_time - (unsigned long)end_time; @@ -156,21 +150,22 @@ int main(int argc, char **argv) { diff_time = (unsigned long)end_time - server_time; } - if (check_critical_diff && diff_time > critical_diff) { + if (config.check_critical_diff && diff_time > config.critical_diff) { result = STATE_CRITICAL; - } else if (check_warning_diff && diff_time > warning_diff) { + } else if (config.check_warning_diff && diff_time > config.warning_diff) { result = STATE_WARNING; } printf(_("TIME %s - %lu second time difference|%s %s\n"), state_text(result), diff_time, - perfdata("time", (long)conntime, "s", check_warning_time, (long)warning_time, check_critical_time, (long)critical_time, true, 0, - false, 0), - perfdata("offset", diff_time, "s", check_warning_diff, warning_diff, check_critical_diff, critical_diff, true, 0, false, 0)); + perfdata("time", (long)conntime, "s", config.check_warning_time, (long)config.warning_time, config.check_critical_time, + (long)config.critical_time, true, 0, false, 0), + perfdata("offset", diff_time, "s", config.check_warning_diff, config.warning_diff, config.check_critical_diff, + config.critical_diff, true, 0, false, 0)); return result; } /* process command-line arguments */ -int process_arguments(int argc, char **argv) { +check_time_config_wrapper process_arguments(int argc, char **argv) { static struct option longopts[] = {{"hostname", required_argument, 0, 'H'}, {"warning-variance", required_argument, 0, 'w'}, {"critical-variance", required_argument, 0, 'c'}, @@ -201,6 +196,11 @@ int process_arguments(int argc, char **argv) { } } + check_time_config_wrapper result = { + .errorcode = OK, + .config = check_time_config_init(), + }; + int option_char; while (true) { int option = 0; @@ -223,16 +223,16 @@ int process_arguments(int argc, char **argv) { if (!is_host(optarg)) { usage2(_("Invalid hostname/address"), optarg); } - server_address = optarg; + result.config.server_address = optarg; break; case 'w': /* warning-variance */ if (is_intnonneg(optarg)) { - warning_diff = strtoul(optarg, NULL, 10); - check_warning_diff = true; + result.config.warning_diff = strtoul(optarg, NULL, 10); + result.config.check_warning_diff = true; } else if (strspn(optarg, "0123456789:,") > 0) { - if (sscanf(optarg, "%lu%*[:,]%d", &warning_diff, &warning_time) == 2) { - check_warning_diff = true; - check_warning_time = true; + if (sscanf(optarg, "%lu%*[:,]%d", &result.config.warning_diff, &result.config.warning_time) == 2) { + result.config.check_warning_diff = true; + result.config.check_warning_time = true; } else { usage4(_("Warning thresholds must be a positive integer")); } @@ -242,12 +242,12 @@ int process_arguments(int argc, char **argv) { break; case 'c': /* critical-variance */ if (is_intnonneg(optarg)) { - critical_diff = strtoul(optarg, NULL, 10); - check_critical_diff = true; + result.config.critical_diff = strtoul(optarg, NULL, 10); + result.config.check_critical_diff = true; } else if (strspn(optarg, "0123456789:,") > 0) { - if (sscanf(optarg, "%lu%*[:,]%d", &critical_diff, &critical_time) == 2) { - check_critical_diff = true; - check_critical_time = true; + if (sscanf(optarg, "%lu%*[:,]%d", &result.config.critical_diff, &result.config.critical_time) == 2) { + result.config.check_critical_diff = true; + result.config.check_critical_time = true; } else { usage4(_("Critical thresholds must be a positive integer")); } @@ -259,23 +259,23 @@ int process_arguments(int argc, char **argv) { if (!is_intnonneg(optarg)) { usage4(_("Warning threshold must be a positive integer")); } else { - warning_time = atoi(optarg); + result.config.warning_time = atoi(optarg); } - check_warning_time = true; + result.config.check_warning_time = true; break; case 'C': /* critical-connect */ if (!is_intnonneg(optarg)) { usage4(_("Critical threshold must be a positive integer")); } else { - critical_time = atoi(optarg); + result.config.critical_time = atoi(optarg); } - check_critical_time = true; + result.config.check_critical_time = true; break; case 'p': /* port */ if (!is_intnonneg(optarg)) { usage4(_("Port must be a positive integer")); } else { - server_port = atoi(optarg); + result.config.server_port = atoi(optarg); } break; case 't': /* timeout */ @@ -286,23 +286,23 @@ int process_arguments(int argc, char **argv) { } break; case 'u': /* udp */ - use_udp = true; + result.config.use_udp = true; } } option_char = optind; - if (server_address == NULL) { + if (result.config.server_address == NULL) { if (argc > option_char) { if (!is_host(argv[option_char])) { usage2(_("Invalid hostname/address"), optarg); } - server_address = argv[option_char]; + result.config.server_address = argv[option_char]; } else { usage4(_("Hostname was not supplied")); } } - return OK; + return result; } void print_help(void) { diff --git a/plugins/check_time.d/config.h b/plugins/check_time.d/config.h new file mode 100644 index 00000000..09bd7c45 --- /dev/null +++ b/plugins/check_time.d/config.h @@ -0,0 +1,42 @@ +#pragma once + +#include "../../config.h" +#include + +enum { + TIME_PORT = 37 +}; + +typedef struct { + char *server_address; + int server_port; + bool use_udp; + + int warning_time; + bool check_warning_time; + int critical_time; + bool check_critical_time; + unsigned long warning_diff; + bool check_warning_diff; + unsigned long critical_diff; + bool check_critical_diff; +} check_time_config; + +check_time_config check_time_config_init() { + check_time_config tmp = { + .server_address = NULL, + .server_port = TIME_PORT, + .use_udp = false, + + .warning_time = 0, + .check_warning_time = false, + .critical_time = 0, + .check_critical_time = false, + + .warning_diff = 0, + .check_warning_diff = false, + .critical_diff = 0, + .check_critical_diff = false, + }; + return tmp; +} -- cgit v1.2.3-74-g34f1 From 29b1be07c81099013317b10f25c5f48f6d40312b Mon Sep 17 00:00:00 2001 From: Lorenz Kästle <12514511+RincewindsHat@users.noreply.github.com> Date: Wed, 12 Mar 2025 18:40:14 +0100 Subject: Refactor check_ups --- plugins/Makefile.am | 1 + plugins/check_ups.c | 274 +++++++++++++++++++------------------------ plugins/check_ups.d/config.h | 55 +++++++++ 3 files changed, 178 insertions(+), 152 deletions(-) create mode 100644 plugins/check_ups.d/config.h diff --git a/plugins/Makefile.am b/plugins/Makefile.am index bb3f029e..f1b9acf6 100644 --- a/plugins/Makefile.am +++ b/plugins/Makefile.am @@ -73,6 +73,7 @@ EXTRA_DIST = t \ check_ntp_time.d \ check_dig.d \ check_cluster.d \ + check_ups.d \ check_fping.d PLUGINHDRS = common.h diff --git a/plugins/check_ups.c b/plugins/check_ups.c index 526a29df..ecc0760f 100644 --- a/plugins/check_ups.c +++ b/plugins/check_ups.c @@ -39,69 +39,29 @@ const char *email = "devel@monitoring-plugins.org"; #include "common.h" #include "netutils.h" #include "utils.h" - -enum { - PORT = 3493 -}; - -#define UPS_NONE 0 /* no supported options */ -#define UPS_UTILITY 1 /* supports utility line */ -#define UPS_BATTPCT 2 /* supports percent battery remaining */ -#define UPS_STATUS 4 /* supports UPS status */ -#define UPS_TEMP 8 /* supports UPS temperature */ -#define UPS_LOADPCT 16 /* supports load percent */ -#define UPS_REALPOWER 32 /* supports real power */ - -#define UPSSTATUS_NONE 0 -#define UPSSTATUS_OFF 1 -#define UPSSTATUS_OL 2 -#define UPSSTATUS_OB 4 -#define UPSSTATUS_LB 8 -#define UPSSTATUS_CAL 16 -#define UPSSTATUS_RB 32 /*Replace Battery */ -#define UPSSTATUS_BYPASS 64 -#define UPSSTATUS_OVER 128 -#define UPSSTATUS_TRIM 256 -#define UPSSTATUS_BOOST 512 -#define UPSSTATUS_CHRG 1024 -#define UPSSTATUS_DISCHRG 2048 -#define UPSSTATUS_UNKNOWN 4096 -#define UPSSTATUS_ALARM 8192 +#include "check_ups.d/config.h" +#include "states.h" enum { NOSUCHVAR = ERROR - 1 }; -typedef struct ups_config { - unsigned int server_port; - char *server_address; - char *ups_name; - double warning_value; - double critical_value; - bool check_warn; - bool check_crit; - int check_variable; - int status; - bool temp_output_c; -} ups_config; - -ups_config ups_config_init(void) { - ups_config tmp = {0}; - tmp.server_port = PORT; - tmp.server_address = NULL; - tmp.ups_name = NULL; - tmp.check_variable = UPS_NONE; - tmp.status = UPSSTATUS_NONE; - - return tmp; -} - // Forward declarations -static int determine_status(ups_config * /*config*/, int *supported_options); -static int get_ups_variable(const char * /*varname*/, char * /*buf*/, ups_config config); +typedef struct { + int errorcode; + int ups_status; + int supported_options; +} determine_status_result; +static determine_status_result determine_status(check_ups_config /*config*/); +static int get_ups_variable(const char * /*varname*/, char * /*buf*/, check_ups_config config); + +typedef struct { + int errorcode; + check_ups_config config; +} check_ups_config_wrapper; +static check_ups_config_wrapper process_arguments(int /*argc*/, char ** /*argv*/); +static check_ups_config_wrapper validate_arguments(check_ups_config_wrapper /*config_wrapper*/); -static int process_arguments(int /*argc*/, char ** /*argv*/, ups_config * /*config*/); -static int validate_arguments(ups_config /*config*/); static void print_help(void); void print_usage(void); @@ -109,28 +69,16 @@ int main(int argc, char **argv) { setlocale(LC_ALL, ""); bindtextdomain(PACKAGE, LOCALEDIR); textdomain(PACKAGE); - - char *ups_status; - ups_status = strdup("N/A"); - - char *data; - data = strdup(""); - - char *message; - message = strdup(""); - - // Exit result - int result = STATE_UNKNOWN; - /* Parse extra opts if any */ argv = np_extra_opts(&argc, argv, progname); - // Config from commandline - ups_config config = ups_config_init(); + check_ups_config_wrapper tmp_config = process_arguments(argc, argv); - if (process_arguments(argc, argv, &config) == ERROR) { + if (tmp_config.errorcode == ERROR) { usage4(_("Could not parse arguments")); } + // Config from commandline + check_ups_config config = tmp_config.config; /* initialize alarm signal handling */ signal(SIGALRM, socket_timeout_alarm_handler); @@ -138,71 +86,75 @@ int main(int argc, char **argv) { /* set socket timeout */ alarm(socket_timeout); - int supported_options = UPS_NONE; - /* get the ups status if possible */ - if (determine_status(&config, &supported_options) != OK) { + determine_status_result query_result = determine_status(config); + if (query_result.errorcode != OK) { return STATE_CRITICAL; } - if (supported_options & UPS_STATUS) { + int ups_status_flags = query_result.ups_status; + int supported_options = query_result.supported_options; - ups_status = strdup(""); + // Exit result + mp_state_enum result = STATE_UNKNOWN; + char *message = NULL; + if (supported_options & UPS_STATUS) { + char *ups_status = strdup(""); result = STATE_OK; - if (config.status & UPSSTATUS_OFF) { + if (ups_status_flags & UPSSTATUS_OFF) { xasprintf(&ups_status, "Off"); result = STATE_CRITICAL; - } else if ((config.status & (UPSSTATUS_OB | UPSSTATUS_LB)) == (UPSSTATUS_OB | UPSSTATUS_LB)) { + } else if ((ups_status_flags & (UPSSTATUS_OB | UPSSTATUS_LB)) == (UPSSTATUS_OB | UPSSTATUS_LB)) { xasprintf(&ups_status, _("On Battery, Low Battery")); result = STATE_CRITICAL; } else { - if (config.status & UPSSTATUS_OL) { + if (ups_status_flags & UPSSTATUS_OL) { xasprintf(&ups_status, "%s%s", ups_status, _("Online")); } - if (config.status & UPSSTATUS_OB) { + if (ups_status_flags & UPSSTATUS_OB) { xasprintf(&ups_status, "%s%s", ups_status, _("On Battery")); result = max_state(result, STATE_WARNING); } - if (config.status & UPSSTATUS_LB) { + if (ups_status_flags & UPSSTATUS_LB) { xasprintf(&ups_status, "%s%s", ups_status, _(", Low Battery")); result = max_state(result, STATE_WARNING); } - if (config.status & UPSSTATUS_CAL) { + if (ups_status_flags & UPSSTATUS_CAL) { xasprintf(&ups_status, "%s%s", ups_status, _(", Calibrating")); } - if (config.status & UPSSTATUS_RB) { + if (ups_status_flags & UPSSTATUS_RB) { xasprintf(&ups_status, "%s%s", ups_status, _(", Replace Battery")); result = max_state(result, STATE_WARNING); } - if (config.status & UPSSTATUS_BYPASS) { + if (ups_status_flags & UPSSTATUS_BYPASS) { xasprintf(&ups_status, "%s%s", ups_status, _(", On Bypass")); // Bypassing the battery is likely a bad thing result = STATE_CRITICAL; } - if (config.status & UPSSTATUS_OVER) { + if (ups_status_flags & UPSSTATUS_OVER) { xasprintf(&ups_status, "%s%s", ups_status, _(", Overload")); result = max_state(result, STATE_WARNING); } - if (config.status & UPSSTATUS_TRIM) { + if (ups_status_flags & UPSSTATUS_TRIM) { xasprintf(&ups_status, "%s%s", ups_status, _(", Trimming")); } - if (config.status & UPSSTATUS_BOOST) { + if (ups_status_flags & UPSSTATUS_BOOST) { xasprintf(&ups_status, "%s%s", ups_status, _(", Boosting")); } - if (config.status & UPSSTATUS_CHRG) { + if (ups_status_flags & UPSSTATUS_CHRG) { xasprintf(&ups_status, "%s%s", ups_status, _(", Charging")); } - if (config.status & UPSSTATUS_DISCHRG) { + if (ups_status_flags & UPSSTATUS_DISCHRG) { xasprintf(&ups_status, "%s%s", ups_status, _(", Discharging")); result = max_state(result, STATE_WARNING); } - if (config.status & UPSSTATUS_ALARM) { + if (ups_status_flags & UPSSTATUS_ALARM) { xasprintf(&ups_status, "%s%s", ups_status, _(", ALARM")); result = STATE_CRITICAL; } - if (config.status & UPSSTATUS_UNKNOWN) { + if (ups_status_flags & UPSSTATUS_UNKNOWN) { xasprintf(&ups_status, "%s%s", ups_status, _(", Unknown")); } } @@ -211,7 +163,7 @@ int main(int argc, char **argv) { int res; char temp_buffer[MAX_INPUT_BUFFER]; - + char *performance_data = strdup(""); /* get the ups utility voltage if possible */ res = get_ups_variable("input.voltage", temp_buffer, config); if (res == NOSUCHVAR) { @@ -239,11 +191,12 @@ int main(int argc, char **argv) { } else if (config.check_warn && ups_utility_deviation >= config.warning_value) { result = max_state(result, STATE_WARNING); } - xasprintf(&data, "%s", + xasprintf(&performance_data, "%s", perfdata("voltage", (long)(1000 * ups_utility_voltage), "mV", config.check_warn, (long)(1000 * config.warning_value), config.check_crit, (long)(1000 * config.critical_value), true, 0, false, 0)); } else { - xasprintf(&data, "%s", perfdata("voltage", (long)(1000 * ups_utility_voltage), "mV", false, 0, false, 0, true, 0, false, 0)); + xasprintf(&performance_data, "%s", + perfdata("voltage", (long)(1000 * ups_utility_voltage), "mV", false, 0, false, 0, true, 0, false, 0)); } } @@ -266,11 +219,12 @@ int main(int argc, char **argv) { } else if (config.check_warn && ups_battery_percent <= config.warning_value) { result = max_state(result, STATE_WARNING); } - xasprintf(&data, "%s %s", data, + xasprintf(&performance_data, "%s %s", performance_data, perfdata("battery", (long)ups_battery_percent, "%", config.check_warn, (long)(config.warning_value), config.check_crit, (long)(config.critical_value), true, 0, true, 100)); } else { - xasprintf(&data, "%s %s", data, perfdata("battery", (long)ups_battery_percent, "%", false, 0, false, 0, true, 0, true, 100)); + xasprintf(&performance_data, "%s %s", performance_data, + perfdata("battery", (long)ups_battery_percent, "%", false, 0, false, 0, true, 0, true, 100)); } } @@ -293,11 +247,12 @@ int main(int argc, char **argv) { } else if (config.check_warn && ups_load_percent >= config.warning_value) { result = max_state(result, STATE_WARNING); } - xasprintf(&data, "%s %s", data, + xasprintf(&performance_data, "%s %s", performance_data, perfdata("load", (long)ups_load_percent, "%", config.check_warn, (long)(config.warning_value), config.check_crit, (long)(config.critical_value), true, 0, true, 100)); } else { - xasprintf(&data, "%s %s", data, perfdata("load", (long)ups_load_percent, "%", false, 0, false, 0, true, 0, true, 100)); + xasprintf(&performance_data, "%s %s", performance_data, + perfdata("load", (long)ups_load_percent, "%", false, 0, false, 0, true, 0, true, 100)); } } @@ -329,11 +284,12 @@ int main(int argc, char **argv) { } else if (config.check_warn && ups_temperature >= config.warning_value) { result = max_state(result, STATE_WARNING); } - xasprintf(&data, "%s %s", data, + xasprintf(&performance_data, "%s %s", performance_data, perfdata("temp", (long)ups_temperature, tunits, config.check_warn, (long)(config.warning_value), config.check_crit, (long)(config.critical_value), true, 0, false, 0)); } else { - xasprintf(&data, "%s %s", data, perfdata("temp", (long)ups_temperature, tunits, false, 0, false, 0, true, 0, false, 0)); + xasprintf(&performance_data, "%s %s", performance_data, + perfdata("temp", (long)ups_temperature, tunits, false, 0, false, 0, true, 0, false, 0)); } } @@ -355,11 +311,12 @@ int main(int argc, char **argv) { } else if (config.check_warn && ups_realpower >= config.warning_value) { result = max_state(result, STATE_WARNING); } - xasprintf(&data, "%s %s", data, + xasprintf(&performance_data, "%s %s", performance_data, perfdata("realpower", (long)ups_realpower, "W", config.check_warn, (long)(config.warning_value), config.check_crit, (long)(config.critical_value), true, 0, false, 0)); } else { - xasprintf(&data, "%s %s", data, perfdata("realpower", (long)ups_realpower, "W", false, 0, false, 0, true, 0, false, 0)); + xasprintf(&performance_data, "%s %s", performance_data, + perfdata("realpower", (long)ups_realpower, "W", false, 0, false, 0, true, 0, false, 0)); } } @@ -373,66 +330,73 @@ int main(int argc, char **argv) { /* reset timeout */ alarm(0); - printf("UPS %s - %s|%s\n", state_text(result), message, data); - return result; + printf("UPS %s - %s|%s\n", state_text(result), message, performance_data); + exit(result); } /* determines what options are supported by the UPS */ -int determine_status(ups_config *config, int *supported_options) { - char recv_buffer[MAX_INPUT_BUFFER]; +determine_status_result determine_status(const check_ups_config config) { - int res = get_ups_variable("ups.status", recv_buffer, *config); + determine_status_result result = { + .errorcode = OK, + .ups_status = UPSSTATUS_NONE, + .supported_options = 0, + }; + + char recv_buffer[MAX_INPUT_BUFFER]; + int res = get_ups_variable("ups.status", recv_buffer, config); if (res == NOSUCHVAR) { - return OK; + return result; } if (res != STATE_OK) { printf("%s\n", _("Invalid response received from host")); - return ERROR; + result.errorcode = ERROR; + return result; } - *supported_options |= UPS_STATUS; + result.supported_options |= UPS_STATUS; char temp_buffer[MAX_INPUT_BUFFER]; strcpy(temp_buffer, recv_buffer); - for (char *ptr = (char *)strtok(temp_buffer, " "); ptr != NULL; ptr = (char *)strtok(NULL, " ")) { + for (char *ptr = strtok(temp_buffer, " "); ptr != NULL; ptr = strtok(NULL, " ")) { if (!strcmp(ptr, "OFF")) { - config->status |= UPSSTATUS_OFF; + result.ups_status |= UPSSTATUS_OFF; } else if (!strcmp(ptr, "OL")) { - config->status |= UPSSTATUS_OL; + result.ups_status |= UPSSTATUS_OL; } else if (!strcmp(ptr, "OB")) { - config->status |= UPSSTATUS_OB; + result.ups_status |= UPSSTATUS_OB; } else if (!strcmp(ptr, "LB")) { - config->status |= UPSSTATUS_LB; + result.ups_status |= UPSSTATUS_LB; } else if (!strcmp(ptr, "CAL")) { - config->status |= UPSSTATUS_CAL; + result.ups_status |= UPSSTATUS_CAL; } else if (!strcmp(ptr, "RB")) { - config->status |= UPSSTATUS_RB; + result.ups_status |= UPSSTATUS_RB; } else if (!strcmp(ptr, "BYPASS")) { - config->status |= UPSSTATUS_BYPASS; + result.ups_status |= UPSSTATUS_BYPASS; } else if (!strcmp(ptr, "OVER")) { - config->status |= UPSSTATUS_OVER; + result.ups_status |= UPSSTATUS_OVER; } else if (!strcmp(ptr, "TRIM")) { - config->status |= UPSSTATUS_TRIM; + result.ups_status |= UPSSTATUS_TRIM; } else if (!strcmp(ptr, "BOOST")) { - config->status |= UPSSTATUS_BOOST; + result.ups_status |= UPSSTATUS_BOOST; } else if (!strcmp(ptr, "CHRG")) { - config->status |= UPSSTATUS_CHRG; + result.ups_status |= UPSSTATUS_CHRG; } else if (!strcmp(ptr, "DISCHRG")) { - config->status |= UPSSTATUS_DISCHRG; + result.ups_status |= UPSSTATUS_DISCHRG; } else if (!strcmp(ptr, "ALARM")) { - config->status |= UPSSTATUS_ALARM; + result.ups_status |= UPSSTATUS_ALARM; } else { - config->status |= UPSSTATUS_UNKNOWN; + result.ups_status |= UPSSTATUS_UNKNOWN; } } - return OK; + return result; } /* gets a variable value for a specific UPS */ -int get_ups_variable(const char *varname, char *buf, const ups_config config) { +int get_ups_variable(const char *varname, char *buf, const check_ups_config config) { char send_buffer[MAX_INPUT_BUFFER]; /* create the command string to send to the UPS daemon */ @@ -500,7 +464,7 @@ int get_ups_variable(const char *varname, char *buf, const ups_config config) { [-wv warn_value] [-cv crit_value] [-to to_sec] */ /* process command-line arguments */ -int process_arguments(int argc, char **argv, ups_config *config) { +check_ups_config_wrapper process_arguments(int argc, char **argv) { static struct option longopts[] = {{"hostname", required_argument, 0, 'H'}, {"ups", required_argument, 0, 'u'}, @@ -514,8 +478,14 @@ int process_arguments(int argc, char **argv, ups_config *config) { {"help", no_argument, 0, 'h'}, {0, 0, 0, 0}}; + check_ups_config_wrapper result = { + .errorcode = OK, + .config = check_ups_config_init(), + }; + if (argc < 2) { - return ERROR; + result.errorcode = ERROR; + return result; } int c; @@ -542,52 +512,52 @@ int process_arguments(int argc, char **argv, ups_config *config) { usage5(); case 'H': /* hostname */ if (is_host(optarg)) { - config->server_address = optarg; + result.config.server_address = optarg; } else { usage2(_("Invalid hostname/address"), optarg); } break; case 'T': /* FIXME: to be improved (ie "-T C" for Celsius or "-T F" for Fahrenheit) */ - config->temp_output_c = true; + result.config.temp_output_c = true; break; case 'u': /* ups name */ - config->ups_name = optarg; + result.config.ups_name = optarg; break; case 'p': /* port */ if (is_intpos(optarg)) { - config->server_port = atoi(optarg); + result.config.server_port = atoi(optarg); } else { usage2(_("Port must be a positive integer"), optarg); } break; case 'c': /* critical time threshold */ if (is_intnonneg(optarg)) { - config->critical_value = atoi(optarg); - config->check_crit = true; + result.config.critical_value = atoi(optarg); + result.config.check_crit = true; } else { usage2(_("Critical time must be a positive integer"), optarg); } break; case 'w': /* warning time threshold */ if (is_intnonneg(optarg)) { - config->warning_value = atoi(optarg); - config->check_warn = true; + result.config.warning_value = atoi(optarg); + result.config.check_warn = true; } else { usage2(_("Warning time must be a positive integer"), optarg); } break; case 'v': /* variable */ if (!strcmp(optarg, "LINE")) { - config->check_variable = UPS_UTILITY; + result.config.check_variable = UPS_UTILITY; } else if (!strcmp(optarg, "TEMP")) { - config->check_variable = UPS_TEMP; + result.config.check_variable = UPS_TEMP; } else if (!strcmp(optarg, "BATTPCT")) { - config->check_variable = UPS_BATTPCT; + result.config.check_variable = UPS_BATTPCT; } else if (!strcmp(optarg, "LOADPCT")) { - config->check_variable = UPS_LOADPCT; + result.config.check_variable = UPS_LOADPCT; } else if (!strcmp(optarg, "REALPOWER")) { - config->check_variable = UPS_REALPOWER; + result.config.check_variable = UPS_REALPOWER; } else { usage2(_("Unrecognized UPS variable"), optarg); } @@ -608,27 +578,27 @@ int process_arguments(int argc, char **argv, ups_config *config) { } } - if (config->server_address == NULL && argc > optind) { + if (result.config.server_address == NULL && argc > optind) { if (is_host(argv[optind])) { - config->server_address = argv[optind++]; + result.config.server_address = argv[optind++]; } else { usage2(_("Invalid hostname/address"), optarg); } } - if (config->server_address == NULL) { - config->server_address = strdup("127.0.0.1"); + if (result.config.server_address == NULL) { + result.config.server_address = strdup("127.0.0.1"); } - return validate_arguments(*config); + return validate_arguments(result); } -int validate_arguments(ups_config config) { - if (!config.ups_name) { +check_ups_config_wrapper validate_arguments(check_ups_config_wrapper config_wrapper) { + if (config_wrapper.config.ups_name) { printf("%s\n", _("Error : no UPS indicated")); - return ERROR; + config_wrapper.errorcode = ERROR; } - return OK; + return config_wrapper; } void print_help(void) { diff --git a/plugins/check_ups.d/config.h b/plugins/check_ups.d/config.h new file mode 100644 index 00000000..353104f2 --- /dev/null +++ b/plugins/check_ups.d/config.h @@ -0,0 +1,55 @@ +#pragma once + +#include "../../config.h" +#include + +#define UPS_NONE 0 /* no supported options */ +#define UPS_UTILITY 1 /* supports utility line */ +#define UPS_BATTPCT 2 /* supports percent battery remaining */ +#define UPS_STATUS 4 /* supports UPS status */ +#define UPS_TEMP 8 /* supports UPS temperature */ +#define UPS_LOADPCT 16 /* supports load percent */ +#define UPS_REALPOWER 32 /* supports real power */ + +#define UPSSTATUS_NONE 0 +#define UPSSTATUS_OFF 1 +#define UPSSTATUS_OL 2 +#define UPSSTATUS_OB 4 +#define UPSSTATUS_LB 8 +#define UPSSTATUS_CAL 16 +#define UPSSTATUS_RB 32 /*Replace Battery */ +#define UPSSTATUS_BYPASS 64 +#define UPSSTATUS_OVER 128 +#define UPSSTATUS_TRIM 256 +#define UPSSTATUS_BOOST 512 +#define UPSSTATUS_CHRG 1024 +#define UPSSTATUS_DISCHRG 2048 +#define UPSSTATUS_UNKNOWN 4096 +#define UPSSTATUS_ALARM 8192 + +enum { + PORT = 3493 +}; + +typedef struct ups_config { + unsigned int server_port; + char *server_address; + char *ups_name; + double warning_value; + double critical_value; + bool check_warn; + bool check_crit; + int check_variable; + bool temp_output_c; +} check_ups_config; + +check_ups_config check_ups_config_init(void) { + check_ups_config tmp = {0}; + tmp.server_port = PORT; + tmp.server_address = NULL; + tmp.ups_name = NULL; + tmp.check_variable = UPS_NONE; + + return tmp; +} + -- cgit v1.2.3-74-g34f1 From 53e72bfa25a17b253c171f6ec4d936bb2cb87cca Mon Sep 17 00:00:00 2001 From: Lorenz Kästle <12514511+RincewindsHat@users.noreply.github.com> Date: Wed, 12 Mar 2025 18:41:57 +0100 Subject: negate: clang-format --- plugins/negate.c | 35 +++++++++++++++++++++++------------ 1 file changed, 23 insertions(+), 12 deletions(-) diff --git a/plugins/negate.c b/plugins/negate.c index 750c0bfb..6c53a1b9 100644 --- a/plugins/negate.c +++ b/plugins/negate.c @@ -64,8 +64,9 @@ int main(int argc, char **argv) { char **command_line = (char **)process_arguments(argc, argv); /* Set signal handling and alarm */ - if (signal(SIGALRM, timeout_alarm_handler) == SIG_ERR) + if (signal(SIGALRM, timeout_alarm_handler) == SIG_ERR) { die(STATE_UNKNOWN, _("Cannot catch SIGALRM")); + } (void)alarm((unsigned)timeout_interval); @@ -86,8 +87,9 @@ int main(int argc, char **argv) { } /* Return UNKNOWN or worse if no output is returned */ - if (chld_out.lines == 0) + if (chld_out.lines == 0) { die(max_state_alt(result, STATE_UNKNOWN), _("No data returned from command\n")); + } char *sub; for (size_t i = 0; i < chld_out.lines; i++) { @@ -124,8 +126,9 @@ static const char **process_arguments(int argc, char **argv) { int option = 0; int option_char = getopt_long(argc, argv, "+hVt:T:o:w:c:u:s", longopts, &option); - if (option_char == -1 || option_char == EOF) + if (option_char == -1 || option_char == EOF) { break; + } switch (option_char) { case '?': /* help */ @@ -139,34 +142,40 @@ static const char **process_arguments(int argc, char **argv) { print_revision(progname, NP_VERSION); exit(STATE_UNKNOWN); case 't': /* timeout period */ - if (!is_integer(optarg)) + if (!is_integer(optarg)) { usage2(_("Timeout interval must be a positive integer"), optarg); - else + } else { timeout_interval = atoi(optarg); + } break; case 'T': /* Result to return on timeouts */ - if ((timeout_state = mp_translate_state(optarg)) == ERROR) + if ((timeout_state = mp_translate_state(optarg)) == ERROR) { usage4(_("Timeout result must be a valid state name (OK, WARNING, CRITICAL, UNKNOWN) or integer (0-3).")); + } break; case 'o': /* replacement for OK */ - if ((state[STATE_OK] = mp_translate_state(optarg)) == ERROR) + if ((state[STATE_OK] = mp_translate_state(optarg)) == ERROR) { usage4(_("Ok must be a valid state name (OK, WARNING, CRITICAL, UNKNOWN) or integer (0-3).")); + } permute = false; break; case 'w': /* replacement for WARNING */ - if ((state[STATE_WARNING] = mp_translate_state(optarg)) == ERROR) + if ((state[STATE_WARNING] = mp_translate_state(optarg)) == ERROR) { usage4(_("Warning must be a valid state name (OK, WARNING, CRITICAL, UNKNOWN) or integer (0-3).")); + } permute = false; break; case 'c': /* replacement for CRITICAL */ - if ((state[STATE_CRITICAL] = mp_translate_state(optarg)) == ERROR) + if ((state[STATE_CRITICAL] = mp_translate_state(optarg)) == ERROR) { usage4(_("Critical must be a valid state name (OK, WARNING, CRITICAL, UNKNOWN) or integer (0-3).")); + } permute = false; break; case 'u': /* replacement for UNKNOWN */ - if ((state[STATE_UNKNOWN] = mp_translate_state(optarg)) == ERROR) + if ((state[STATE_UNKNOWN] = mp_translate_state(optarg)) == ERROR) { usage4(_("Unknown must be a valid state name (OK, WARNING, CRITICAL, UNKNOWN) or integer (0-3).")); + } permute = false; break; case 's': /* Substitute status text */ @@ -186,11 +195,13 @@ static const char **process_arguments(int argc, char **argv) { } void validate_arguments(char **command_line) { - if (command_line[0] == NULL) + if (command_line[0] == NULL) { usage4(_("Could not parse arguments")); + } - if (strncmp(command_line[0], "/", 1) != 0 && strncmp(command_line[0], "./", 2) != 0) + if (strncmp(command_line[0], "/", 1) != 0 && strncmp(command_line[0], "./", 2) != 0) { usage4(_("Require path to command")); + } } void print_help(void) { -- cgit v1.2.3-74-g34f1 From 5ae0a8d49559d66695f6f2591f4bbe0bb185ef73 Mon Sep 17 00:00:00 2001 From: Lorenz Kästle <12514511+RincewindsHat@users.noreply.github.com> Date: Wed, 12 Mar 2025 21:22:50 +0100 Subject: Refactor negate --- plugins/Makefile.am | 1 + plugins/negate.c | 73 +++++++++++++++++++++++++++-------------------- plugins/negate.d/config.h | 24 ++++++++++++++++ 3 files changed, 67 insertions(+), 31 deletions(-) create mode 100644 plugins/negate.d/config.h diff --git a/plugins/Makefile.am b/plugins/Makefile.am index bb3f029e..a420d23d 100644 --- a/plugins/Makefile.am +++ b/plugins/Makefile.am @@ -49,6 +49,7 @@ np_test_scripts = tests/test_check_swap.t EXTRA_DIST = t \ tests \ $(np_test_scripts) \ + negate.d \ check_swap.d \ check_ldap.d \ check_hpjd.d \ diff --git a/plugins/negate.c b/plugins/negate.c index 6c53a1b9..08fa1470 100644 --- a/plugins/negate.c +++ b/plugins/negate.c @@ -29,6 +29,7 @@ * *****************************************************************************/ +#include "states.h" const char *progname = "negate"; const char *copyright = "2002-2024"; const char *email = "devel@monitoring-plugins.org"; @@ -38,21 +39,17 @@ const char *email = "devel@monitoring-plugins.org"; #include "common.h" #include "utils.h" #include "utils_cmd.h" +#include "negate.d/config.h" -#include +typedef struct { + int errorcode; + negate_config config; +} negate_config_wrapper; +static negate_config_wrapper process_arguments(int /*argc*/, char ** /*argv*/); +static negate_config_wrapper validate_arguments(negate_config_wrapper /*config_wrapper*/); -static const char **process_arguments(int /*argc*/, char ** /*argv*/); -static void validate_arguments(char ** /*command_line*/); static void print_help(void); void print_usage(void); -static bool subst_text = false; - -static int state[4] = { - STATE_OK, - STATE_WARNING, - STATE_CRITICAL, - STATE_UNKNOWN, -}; int main(int argc, char **argv) { setlocale(LC_ALL, ""); @@ -61,16 +58,24 @@ int main(int argc, char **argv) { timeout_interval = DEFAULT_TIMEOUT; - char **command_line = (char **)process_arguments(argc, argv); + negate_config_wrapper tmp_config = process_arguments(argc, argv); + + if (tmp_config.errorcode == ERROR) { + die(STATE_UNKNOWN, _("negate: Failed to parse input")); + } + + negate_config config = tmp_config.config; + + char **command_line = config.command_line; /* Set signal handling and alarm */ if (signal(SIGALRM, timeout_alarm_handler) == SIG_ERR) { die(STATE_UNKNOWN, _("Cannot catch SIGALRM")); } - (void)alarm((unsigned)timeout_interval); + (void)alarm(timeout_interval); - int result = STATE_UNKNOWN; + mp_state_enum result = STATE_UNKNOWN; output chld_out; output chld_err; @@ -93,34 +98,38 @@ int main(int argc, char **argv) { char *sub; for (size_t i = 0; i < chld_out.lines; i++) { - if (subst_text && result >= 0 && result <= 4 && result != state[result]) { + if (config.subst_text && result >= 0 && result <= 4 && result != config.state[result]) { /* Loop over each match found */ while ((sub = strstr(chld_out.line[i], state_text(result)))) { /* Terminate the first part and skip over the string we'll substitute */ *sub = '\0'; sub += strlen(state_text(result)); /* then put everything back together */ - xasprintf(&chld_out.line[i], "%s%s%s", chld_out.line[i], state_text(state[result]), sub); + xasprintf(&chld_out.line[i], "%s%s%s", chld_out.line[i], state_text(config.state[result]), sub); } } printf("%s\n", chld_out.line[i]); } if (result >= 0 && result <= 4) { - exit(state[result]); + exit(config.state[result]); } else { exit(result); } } /* process command-line arguments */ -static const char **process_arguments(int argc, char **argv) { +static negate_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'}, {"timeout-result", required_argument, 0, 'T'}, {"ok", required_argument, 0, 'o'}, {"warning", required_argument, 0, 'w'}, {"critical", required_argument, 0, 'c'}, {"unknown", required_argument, 0, 'u'}, {"substitute", no_argument, 0, 's'}, {0, 0, 0, 0}}; + negate_config_wrapper result = { + .errorcode = OK, + .config = negate_config_init(), + }; bool permute = true; while (true) { int option = 0; @@ -154,54 +163,56 @@ static const char **process_arguments(int argc, char **argv) { } break; case 'o': /* replacement for OK */ - if ((state[STATE_OK] = mp_translate_state(optarg)) == ERROR) { + if ((result.config.state[STATE_OK] = mp_translate_state(optarg)) == ERROR) { usage4(_("Ok must be a valid state name (OK, WARNING, CRITICAL, UNKNOWN) or integer (0-3).")); } permute = false; break; case 'w': /* replacement for WARNING */ - if ((state[STATE_WARNING] = mp_translate_state(optarg)) == ERROR) { + if ((result.config.state[STATE_WARNING] = mp_translate_state(optarg)) == ERROR) { usage4(_("Warning must be a valid state name (OK, WARNING, CRITICAL, UNKNOWN) or integer (0-3).")); } permute = false; break; case 'c': /* replacement for CRITICAL */ - if ((state[STATE_CRITICAL] = mp_translate_state(optarg)) == ERROR) { + if ((result.config.state[STATE_CRITICAL] = mp_translate_state(optarg)) == ERROR) { usage4(_("Critical must be a valid state name (OK, WARNING, CRITICAL, UNKNOWN) or integer (0-3).")); } permute = false; break; case 'u': /* replacement for UNKNOWN */ - if ((state[STATE_UNKNOWN] = mp_translate_state(optarg)) == ERROR) { + if ((result.config.state[STATE_UNKNOWN] = mp_translate_state(optarg)) == ERROR) { usage4(_("Unknown must be a valid state name (OK, WARNING, CRITICAL, UNKNOWN) or integer (0-3).")); } permute = false; break; case 's': /* Substitute status text */ - subst_text = true; + result.config.subst_text = true; break; } } - validate_arguments(&argv[optind]); - if (permute) { /* No [owcu] switch specified, default to this */ - state[STATE_OK] = STATE_CRITICAL; - state[STATE_CRITICAL] = STATE_OK; + result.config.state[STATE_OK] = STATE_CRITICAL; + result.config.state[STATE_CRITICAL] = STATE_OK; } - return (const char **)&argv[optind]; + result.config.command_line = &argv[optind]; + + return validate_arguments(result); } -void validate_arguments(char **command_line) { - if (command_line[0] == NULL) { +negate_config_wrapper validate_arguments(negate_config_wrapper config_wrapper) { + if (config_wrapper.config.command_line[0] == NULL) { usage4(_("Could not parse arguments")); } - if (strncmp(command_line[0], "/", 1) != 0 && strncmp(command_line[0], "./", 2) != 0) { + if (strncmp(config_wrapper.config.command_line[0], "/", 1) != 0 && strncmp(config_wrapper.config.command_line[0], "./", 2) != 0) { usage4(_("Require path to command")); } + + return config_wrapper; } void print_help(void) { diff --git a/plugins/negate.d/config.h b/plugins/negate.d/config.h new file mode 100644 index 00000000..0cf30cd4 --- /dev/null +++ b/plugins/negate.d/config.h @@ -0,0 +1,24 @@ +#pragma once + +#include "states.h" + +typedef struct { + mp_state_enum state[4]; + bool subst_text; + char **command_line; +} negate_config; + +negate_config negate_config_init() { + negate_config tmp = { + .state = + { + STATE_OK, + STATE_WARNING, + STATE_CRITICAL, + STATE_UNKNOWN, + }, + .subst_text = false, + .command_line = NULL, + }; + return tmp; +} -- cgit v1.2.3-74-g34f1 From 33f44c4c5a96196661d596d082ed1a6b9e0236fc Mon Sep 17 00:00:00 2001 From: Lorenz Kästle <12514511+RincewindsHat@users.noreply.github.com> Date: Wed, 12 Mar 2025 21:28:40 +0100 Subject: Reposition include --- plugins/negate.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/negate.c b/plugins/negate.c index 08fa1470..0520d298 100644 --- a/plugins/negate.c +++ b/plugins/negate.c @@ -29,7 +29,6 @@ * *****************************************************************************/ -#include "states.h" const char *progname = "negate"; const char *copyright = "2002-2024"; const char *email = "devel@monitoring-plugins.org"; @@ -40,6 +39,7 @@ const char *email = "devel@monitoring-plugins.org"; #include "utils.h" #include "utils_cmd.h" #include "negate.d/config.h" +#include "../lib/states.h" typedef struct { int errorcode; -- cgit v1.2.3-74-g34f1