From 554bf3e5256f5489aed0cd56f0c600bcb281a7f5 Mon Sep 17 00:00:00 2001 From: Lorenz Kästle <12514511+RincewindsHat@users.noreply.github.com> Date: Tue, 4 Mar 2025 11:02:33 +0100 Subject: Refactor check_tcp and implement new output format --- plugins/check_tcp.c | 742 ++++++++++++++++++++++++------------------- plugins/check_tcp.d/config.h | 78 +++++ 2 files changed, 493 insertions(+), 327 deletions(-) create mode 100644 plugins/check_tcp.d/config.h (limited to 'plugins') diff --git a/plugins/check_tcp.c b/plugins/check_tcp.c index 49ad096c..f93152e5 100644 --- a/plugins/check_tcp.c +++ b/plugins/check_tcp.c @@ -3,7 +3,7 @@ * Monitoring check_tcp plugin * * License: GPL - * Copyright (c) 1999-2024 Monitoring Plugins Development Team + * Copyright (c) 1999-2025 Monitoring Plugins Development Team * * Description: * @@ -28,75 +28,63 @@ *****************************************************************************/ /* progname "check_tcp" changes depending on symlink called */ +#include "states.h" char *progname; -const char *copyright = "1999-2024"; +const char *copyright = "1999-2025"; const char *email = "devel@monitoring-plugins.org"; -#include "common.h" -#include "netutils.h" -#include "utils.h" -#include "utils_tcp.h" +#include "./common.h" +#include "./netutils.h" +#include "./utils.h" +#include "./check_tcp.d/config.h" +#include #include #include +ssize_t my_recv(char *buf, size_t len) { #ifdef HAVE_SSL -static bool check_cert = false; -static int days_till_exp_warn, days_till_exp_crit; -# define my_recv(buf, len) ((flags & FLAG_SSL) ? np_net_ssl_read(buf, len) : read(sd, buf, len)) -# define my_send(buf, len) ((flags & FLAG_SSL) ? np_net_ssl_write(buf, len) : send(sd, buf, len, 0)) + return np_net_ssl_read(buf, (int)len); #else -# define my_recv(buf, len) read(sd, buf, len) -# define my_send(buf, len) send(sd, buf, len, 0) -#endif + return read(socket_descriptor, buf, len); +#endif // HAVE_SSL +} + +ssize_t my_send(char *buf, size_t len) { +#ifdef HAVE_SSL + return np_net_ssl_write(buf, (int)len); +#else + return write(socket_descriptor, buf, len); +#endif // HAVE_SSL +} + +typedef struct process_arguments_wrapper { + int errorcode; + check_tcp_config config; +} process_arguments_wrapper; /* int my_recv(char *, size_t); */ -static int process_arguments(int /*argc*/, char ** /*argv*/); -static void print_help(void); +static process_arguments_wrapper process_arguments(int /*argc*/, char ** /*argv*/, check_tcp_config /*config*/); +void print_help(const char *service); void print_usage(void); -#define EXPECT server_expect[0] -static char *SERVICE = "TCP"; -static char *SEND = NULL; -static char *QUIT = NULL; -static int PROTOCOL = IPPROTO_TCP; /* most common is default */ -static int PORT = 0; -static int READ_TIMEOUT = 2; - -static int server_port = 0; -static char *server_address = NULL; -static bool host_specified = false; -static char *server_send = NULL; -static char *server_quit = NULL; -static char **server_expect; -static size_t server_expect_count = 0; -static ssize_t maxbytes = 0; -static char **warn_codes = NULL; -static size_t warn_codes_count = 0; -static char **crit_codes = NULL; -static size_t crit_codes_count = 0; -static unsigned int delay = 0; -static double warning_time = 0; -static double critical_time = 0; -static double elapsed_time = 0; -static long microsec; -static int sd = 0; -#define MAXBUF 1024 -static char buffer[MAXBUF]; -static int expect_mismatch_state = STATE_WARNING; -static int match_flags = NP_MATCH_EXACT; +int verbosity = 0; -#ifdef HAVE_SSL -static char *sni = NULL; -static bool sni_specified = false; -#endif +static const int READ_TIMEOUT = 2; -#define FLAG_SSL 0x01 -#define FLAG_VERBOSE 0x02 -#define FLAG_TIME_WARN 0x04 -#define FLAG_TIME_CRIT 0x08 -#define FLAG_HIDE_OUTPUT 0x10 -static size_t flags; +const int MAXBUF = 1024; + +const int DEFAULT_FTP_PORT = 21; +const int DEFAULT_POP_PORT = 110; +const int DEFAULT_SPOP_PORT = 995; +const int DEFAULT_SMTP_PORT = 25; +const int DEFAULT_SSMTP_PORT = 465; +const int DEFAULT_IMAP_PORT = 143; +const int DEFAULT_SIMAP_PORT = 993; +const int DEFAULT_XMPP_C2S_PORT = 5222; +const int DEFAULT_NNTP_PORT = 119; +const int DEFAULT_NNTPS_PORT = 563; +const int DEFAULT_CLAMD_PORT = 3310; int main(int argc, char **argv) { setlocale(LC_ALL, ""); @@ -105,279 +93,371 @@ int main(int argc, char **argv) { /* determine program- and service-name quickly */ progname = strrchr(argv[0], '/'); - if (progname != NULL) + if (progname != NULL) { progname++; - else + } else { progname = argv[0]; + } + + // Initialize config here with values from above, + // might be changed by on disk config or cli commands + check_tcp_config config = check_tcp_config_init(); size_t prog_name_len = strlen(progname); - if (prog_name_len > 6 && !memcmp(progname, "check_", 6)) { - SERVICE = strdup(progname + 6); - for (size_t i = 0; i < prog_name_len - 6; i++) - SERVICE[i] = toupper(SERVICE[i]); + const size_t prefix_length = strlen("check_"); + + if (prog_name_len <= prefix_length) { + die(STATE_UNKNOWN, _("Weird progname")); + } + + if (!memcmp(progname, "check_", prefix_length)) { + config.service = strdup(progname + prefix_length); + if (config.service == NULL) { + die(STATE_UNKNOWN, _("Allocation failed")); + } + + for (size_t i = 0; i < prog_name_len - prefix_length; i++) { + config.service[i] = toupper(config.service[i]); + } } /* set up a reasonable buffer at first (will be realloc()'ed if * user specifies other options) */ - server_expect = calloc(2, sizeof(char *)); + config.server_expect = calloc(2, sizeof(char *)); + + if (config.server_expect == NULL) { + die(STATE_UNKNOWN, _("Allocation failed")); + } /* determine defaults for this service's protocol */ - if (!strncmp(SERVICE, "UDP", 3)) { - PROTOCOL = IPPROTO_UDP; - } else if (!strncmp(SERVICE, "FTP", 3)) { - EXPECT = "220"; - QUIT = "QUIT\r\n"; - PORT = 21; - } else if (!strncmp(SERVICE, "POP", 3) || !strncmp(SERVICE, "POP3", 4)) { - EXPECT = "+OK"; - QUIT = "QUIT\r\n"; - PORT = 110; - } else if (!strncmp(SERVICE, "SMTP", 4)) { - EXPECT = "220"; - QUIT = "QUIT\r\n"; - PORT = 25; - } else if (!strncmp(SERVICE, "IMAP", 4)) { - EXPECT = "* OK"; - QUIT = "a1 LOGOUT\r\n"; - PORT = 143; + if (!strncmp(config.service, "UDP", strlen("UDP"))) { + config.protocol = IPPROTO_UDP; + } else if (!strncmp(config.service, "FTP", strlen("FTP"))) { + config.server_expect[0] = "220"; + config.quit = "QUIT\r\n"; + config.server_port = DEFAULT_FTP_PORT; + } else if (!strncmp(config.service, "POP", strlen("POP")) || !strncmp(config.service, "POP3", strlen("POP3"))) { + config.server_expect[0] = "+OK"; + config.quit = "QUIT\r\n"; + config.server_port = DEFAULT_POP_PORT; + } else if (!strncmp(config.service, "SMTP", strlen("SMTP"))) { + config.server_expect[0] = "220"; + config.quit = "QUIT\r\n"; + config.server_port = DEFAULT_SMTP_PORT; + } else if (!strncmp(config.service, "IMAP", strlen("IMAP"))) { + config.server_expect[0] = "* OK"; + config.quit = "a1 LOGOUT\r\n"; + config.server_port = DEFAULT_IMAP_PORT; } #ifdef HAVE_SSL - else if (!strncmp(SERVICE, "SIMAP", 5)) { - EXPECT = "* OK"; - QUIT = "a1 LOGOUT\r\n"; - flags |= FLAG_SSL; - PORT = 993; - } else if (!strncmp(SERVICE, "SPOP", 4)) { - EXPECT = "+OK"; - QUIT = "QUIT\r\n"; - flags |= FLAG_SSL; - PORT = 995; - } else if (!strncmp(SERVICE, "SSMTP", 5)) { - EXPECT = "220"; - QUIT = "QUIT\r\n"; - flags |= FLAG_SSL; - PORT = 465; - } else if (!strncmp(SERVICE, "JABBER", 6)) { - SEND = "\n"; - EXPECT = "\n"; - flags |= FLAG_HIDE_OUTPUT; - PORT = 5222; - } else if (!strncmp(SERVICE, "NNTPS", 5)) { - server_expect_count = 2; - server_expect[0] = "200"; - server_expect[1] = "201"; - QUIT = "QUIT\r\n"; - flags |= FLAG_SSL; - PORT = 563; + else if (!strncmp(config.service, "SIMAP", strlen("SIMAP"))) { + config.server_expect[0] = "* OK"; + config.quit = "a1 LOGOUT\r\n"; + config.use_tls = true; + config.server_port = DEFAULT_SIMAP_PORT; + } else if (!strncmp(config.service, "SPOP", strlen("SPOP"))) { + config.server_expect[0] = "+OK"; + config.quit = "QUIT\r\n"; + config.use_tls = true; + config.server_port = DEFAULT_SPOP_PORT; + } else if (!strncmp(config.service, "SSMTP", strlen("SSMTP"))) { + config.server_expect[0] = "220"; + config.quit = "QUIT\r\n"; + config.use_tls = true; + config.server_port = DEFAULT_SSMTP_PORT; + } else if (!strncmp(config.service, "JABBER", strlen("JABBER"))) { + config.send = "\n"; + config.server_expect[0] = "\n"; + config.hide_output = true; + config.server_port = DEFAULT_XMPP_C2S_PORT; + } else if (!strncmp(config.service, "NNTPS", strlen("NNTPS"))) { + config.server_expect_count = 2; + config.server_expect[0] = "200"; + config.server_expect[1] = "201"; + config.quit = "QUIT\r\n"; + config.use_tls = true; + config.server_port = DEFAULT_NNTPS_PORT; } #endif - else if (!strncmp(SERVICE, "NNTP", 4)) { - server_expect_count = 2; - server_expect = malloc(sizeof(char *) * server_expect_count); - server_expect[0] = strdup("200"); - server_expect[1] = strdup("201"); - QUIT = "QUIT\r\n"; - PORT = 119; - } else if (!strncmp(SERVICE, "CLAMD", 5)) { - SEND = "PING"; - EXPECT = "PONG"; - QUIT = NULL; - PORT = 3310; + else if (!strncmp(config.service, "NNTP", strlen("NNTP"))) { + config.server_expect_count = 2; + char **tmp = realloc(config.server_expect, config.server_expect_count * sizeof(char *)); + if (tmp == NULL) { + free(config.server_expect); + die(STATE_UNKNOWN, _("Allocation failed")); + } + config.server_expect = tmp; + + config.server_expect[0] = strdup("200"); + config.server_expect[1] = strdup("201"); + config.quit = "QUIT\r\n"; + config.server_port = DEFAULT_NNTP_PORT; + } else if (!strncmp(config.service, "CLAMD", strlen("CLAMD"))) { + config.send = "PING"; + config.server_expect[0] = "PONG"; + config.quit = NULL; + config.server_port = DEFAULT_CLAMD_PORT; } /* fallthrough check, so it's supposed to use reverse matching */ - else if (strcmp(SERVICE, "TCP")) + else if (strcmp(config.service, "TCP")) { usage(_("CRITICAL - Generic check_tcp called with unknown service\n")); - - server_address = "127.0.0.1"; - server_port = PORT; - server_send = SEND; - server_quit = QUIT; - char *status = NULL; + } /* Parse extra opts if any */ argv = np_extra_opts(&argc, argv, progname); - if (process_arguments(argc, argv) == ERROR) + process_arguments_wrapper paw = process_arguments(argc, argv, config); + if (paw.errorcode == ERROR) { usage4(_("Could not parse arguments")); + } + + config = paw.config; - if (flags & FLAG_VERBOSE) { - printf("Using service %s\n", SERVICE); - printf("Port: %d\n", server_port); - printf("flags: 0x%x\n", (int)flags); + if (verbosity > 0) { + printf("Using service %s\n", config.service); + printf("Port: %d\n", config.server_port); } - if (EXPECT && !server_expect_count) - server_expect_count++; + if ((config.server_expect_count == 0) && config.server_expect[0]) { + config.server_expect_count++; + } - if (PROTOCOL == IPPROTO_UDP && !(server_expect_count && server_send)) { + if (config.protocol == IPPROTO_UDP && !(config.server_expect_count && config.send)) { usage(_("With UDP checks, a send/expect string must be specified.")); } + // Initialize check stuff before setting timers + mp_check overall = mp_check_init(); + /* set up the timer */ signal(SIGALRM, socket_timeout_alarm_handler); alarm(socket_timeout); /* try to connect to the host at the given port number */ - struct timeval tv; - gettimeofday(&tv, NULL); - - int result = STATE_UNKNOWN; - result = np_net_connect(server_address, server_port, &sd, PROTOCOL); - if (result == STATE_CRITICAL) - return econn_refuse_state; + struct timeval start_time; + gettimeofday(&start_time, NULL); + + int socket_descriptor = 0; + mp_subcheck inital_connect_result = mp_subcheck_init(); + + // Try initial connection + if (np_net_connect(config.server_address, config.server_port, &socket_descriptor, config.protocol) == STATE_CRITICAL) { + // Early exit here, we got connection refused + inital_connect_result = mp_set_subcheck_state(inital_connect_result, config.econn_refuse_state); + xasprintf(&inital_connect_result.output, "Connection to %s on port %i was REFUSED", config.server_address, config.server_port); + mp_add_subcheck_to_check(&overall, inital_connect_result); + mp_exit(overall); + } else { + inital_connect_result = mp_set_subcheck_state(inital_connect_result, STATE_OK); + xasprintf(&inital_connect_result.output, "Connection to %s on port %i was a SUCCESS", config.server_address, config.server_port); + mp_add_subcheck_to_check(&overall, inital_connect_result); + } #ifdef HAVE_SSL - if (flags & FLAG_SSL) { - result = np_net_ssl_init_with_hostname(sd, (sni_specified ? sni : NULL)); - if (result == STATE_OK && check_cert) { - result = np_net_ssl_check_cert(days_till_exp_warn, days_till_exp_crit); + if (config.use_tls) { + mp_subcheck tls_connection_result = mp_subcheck_init(); + int result = np_net_ssl_init_with_hostname(socket_descriptor, (config.sni_specified ? config.sni : NULL)); + tls_connection_result = mp_set_subcheck_state(tls_connection_result, result); + + if (result == STATE_OK) { + xasprintf(&tls_connection_result.output, "TLS connection succeded"); + + if (config.check_cert) { + result = np_net_ssl_check_cert(config.days_till_exp_warn, config.days_till_exp_crit); + + mp_subcheck tls_certificate_lifetime_result = mp_subcheck_init(); + tls_certificate_lifetime_result = mp_set_subcheck_state(tls_certificate_lifetime_result, result); + + if (result == STATE_OK) { + xasprintf(&tls_certificate_lifetime_result.output, "Certificate lifetime is within thresholds"); + } else if (result == STATE_WARNING) { + xasprintf(&tls_certificate_lifetime_result.output, "Certificate lifetime is violating warning threshold (%i)", + config.days_till_exp_warn); + } else if (result == STATE_CRITICAL) { + xasprintf(&tls_certificate_lifetime_result.output, "Certificate lifetime is violating critical threshold (%i)", + config.days_till_exp_crit); + } else { + xasprintf(&tls_certificate_lifetime_result.output, "Certificate lifetime is somehow unknown"); + } + + mp_add_subcheck_to_subcheck(&tls_connection_result, tls_certificate_lifetime_result); + } + + mp_add_subcheck_to_check(&overall, tls_connection_result); + } else { + xasprintf(&tls_connection_result.output, "TLS connection failed"); + mp_add_subcheck_to_check(&overall, tls_connection_result); + + if (socket_descriptor) { + close(socket_descriptor); + } + np_net_ssl_cleanup(); + + mp_exit(overall); } } - if (result != STATE_OK) { - if (sd) - close(sd); - np_net_ssl_cleanup(); - return result; - } #endif /* HAVE_SSL */ - if (server_send != NULL) { /* Something to send? */ - my_send(server_send, strlen(server_send)); + if (config.send != NULL) { /* Something to send? */ + my_send(config.send, strlen(config.send)); } - if (delay > 0) { - tv.tv_sec += delay; - sleep(delay); + if (config.delay > 0) { + start_time.tv_sec += config.delay; + sleep(config.delay); } - if (flags & FLAG_VERBOSE) { - if (server_send) { - printf("Send string: %s\n", server_send); + if (verbosity > 0) { + if (config.send) { + printf("Send string: %s\n", config.send); } - if (server_quit) { - printf("Quit string: %s\n", server_quit); + if (config.quit) { + printf("Quit string: %s\n", config.quit); + } + printf("server_expect_count: %d\n", (int)config.server_expect_count); + for (size_t i = 0; i < config.server_expect_count; i++) { + printf("\t%zd: %s\n", i, config.server_expect[i]); } - printf("server_expect_count: %d\n", (int)server_expect_count); - for (size_t i = 0; i < server_expect_count; i++) - printf("\t%zd: %s\n", i, server_expect[i]); } /* if(len) later on, we know we have a non-NULL response */ ssize_t len = 0; - + char *status = NULL; int match = -1; - struct timeval timeout; - fd_set rfds; - FD_ZERO(&rfds); - if (server_expect_count) { + mp_subcheck expected_data_result = mp_subcheck_init(); + + if (config.server_expect_count) { ssize_t received = 0; + char buffer[MAXBUF]; /* watch for the expect string */ while ((received = my_recv(buffer, sizeof(buffer))) > 0) { status = realloc(status, len + received + 1); + + if (status == NULL) { + die(STATE_UNKNOWN, _("Allocation failed")); + } + memcpy(&status[len], buffer, received); len += received; status[len] = '\0'; /* stop reading if user-forced */ - if (maxbytes && len >= maxbytes) + if (config.maxbytes && len >= config.maxbytes) { break; + } - if ((match = np_expect_match(status, server_expect, server_expect_count, match_flags)) != NP_MATCH_RETRY) + if ((match = np_expect_match(status, config.server_expect, config.server_expect_count, config.match_flags)) != NP_MATCH_RETRY) { break; + } + + fd_set rfds; + FD_ZERO(&rfds); + FD_SET(socket_descriptor, &rfds); /* some protocols wait for further input, so make sure we don't wait forever */ - FD_SET(sd, &rfds); + struct timeval timeout; timeout.tv_sec = READ_TIMEOUT; timeout.tv_usec = 0; - if (select(sd + 1, &rfds, NULL, NULL, &timeout) <= 0) + + if (select(socket_descriptor + 1, &rfds, NULL, NULL, &timeout) <= 0) { break; + } } - if (match == NP_MATCH_RETRY) + if (match == NP_MATCH_RETRY) { match = NP_MATCH_FAILURE; + } /* no data when expected, so return critical */ - if (len == 0) - die(STATE_CRITICAL, _("No data received from host\n")); + if (len == 0) { + xasprintf(&expected_data_result.output, "Received no data when some was expected"); + expected_data_result = mp_set_subcheck_state(expected_data_result, STATE_CRITICAL); + mp_add_subcheck_to_check(&overall, expected_data_result); + mp_exit(overall); + } /* print raw output if we're debugging */ - if (flags & FLAG_VERBOSE) + if (verbosity > 0) { printf("received %d bytes from host\n#-raw-recv-------#\n%s\n#-raw-recv-------#\n", (int)len + 1, status); + } /* strip whitespace from end of output */ - while (--len > 0 && isspace(status[len])) + while (--len > 0 && isspace(status[len])) { status[len] = '\0'; + } + } + + if (config.quit != NULL) { + my_send(config.quit, strlen(config.quit)); } - if (server_quit != NULL) { - my_send(server_quit, strlen(server_quit)); + if (socket_descriptor) { + close(socket_descriptor); } - if (sd) - close(sd); #ifdef HAVE_SSL np_net_ssl_cleanup(); #endif - microsec = deltime(tv); - elapsed_time = (double)microsec / 1.0e6; + long microsec = deltime(start_time); + double elapsed_time = (double)microsec / 1.0e6; - if (flags & FLAG_TIME_CRIT && elapsed_time > critical_time) - result = STATE_CRITICAL; - else if (flags & FLAG_TIME_WARN && elapsed_time > warning_time) - result = STATE_WARNING; + mp_subcheck elapsed_time_result = mp_subcheck_init(); - /* did we get the response we hoped? */ - if (match == NP_MATCH_FAILURE && result != STATE_CRITICAL) - result = expect_mismatch_state; + mp_perfdata time_pd = perfdata_init(); + time_pd = mp_set_pd_value(time_pd, elapsed_time); + time_pd.label = "time"; + time_pd.uom = "s"; - /* reset the alarm */ - alarm(0); + if (config.critical_time_set && elapsed_time > config.critical_time) { + xasprintf(&elapsed_time_result.output, "Connection time %fs exceeded critical threshold (%f)", elapsed_time, config.critical_time); + + elapsed_time_result = mp_set_subcheck_state(elapsed_time_result, STATE_CRITICAL); + time_pd.crit_present = true; + mp_range crit_val = mp_range_init(); + + crit_val.end = mp_create_pd_value(config.critical_time); + crit_val.end_infinity = false; + + time_pd.crit = crit_val; + } else if (config.warning_time_set && elapsed_time > config.warning_time) { + xasprintf(&elapsed_time_result.output, "Connection time %fs exceeded warning threshold (%f)", elapsed_time, config.critical_time); - /* this is a bit stupid, because we don't want to print the - * response time (which can look ok to the user) if we didn't get - * the response we were looking for. if-else */ - printf("%s %s - ", SERVICE, state_text(result)); - - if (match == NP_MATCH_FAILURE && len && !(flags & FLAG_HIDE_OUTPUT)) - printf("Unexpected response from host/socket: %s", status); - else { - if (match == NP_MATCH_FAILURE) - printf("Unexpected response from host/socket on "); - else - printf("%.3f second response time on ", elapsed_time); - if (server_address[0] != '/') { - if (host_specified) - printf("%s port %d", server_address, server_port); - else - printf("port %d", server_port); - } else - printf("socket %s", server_address); + elapsed_time_result = mp_set_subcheck_state(elapsed_time_result, STATE_WARNING); + time_pd.warn_present = true; + mp_range warn_val = mp_range_init(); + warn_val.end = mp_create_pd_value(config.critical_time); + warn_val.end_infinity = false; + + time_pd.warn = warn_val; + } else { + elapsed_time_result = mp_set_subcheck_state(elapsed_time_result, STATE_OK); + xasprintf(&elapsed_time_result.output, "Connection time %fs is within thresholds", elapsed_time); } - if (match != NP_MATCH_FAILURE && !(flags & FLAG_HIDE_OUTPUT) && len) - printf(" [%s]", status); + mp_add_perfdata_to_subcheck(&elapsed_time_result, time_pd); + mp_add_subcheck_to_check(&overall, elapsed_time_result); - /* perf-data doesn't apply when server doesn't talk properly, - * so print all zeroes on warn and crit. Use fperfdata since - * localisation settings can make different outputs */ - if (match == NP_MATCH_FAILURE) - printf("|%s", fperfdata("time", elapsed_time, "s", (flags & FLAG_TIME_WARN ? true : false), 0, - (flags & FLAG_TIME_CRIT ? true : false), 0, true, 0, true, socket_timeout)); - else - printf("|%s", fperfdata("time", elapsed_time, "s", (flags & FLAG_TIME_WARN ? true : false), warning_time, - (flags & FLAG_TIME_CRIT ? true : false), critical_time, true, 0, true, socket_timeout)); + /* did we get the response we hoped? */ + if (match == NP_MATCH_FAILURE) { + expected_data_result = mp_set_subcheck_state(expected_data_result, config.expect_mismatch_state); + xasprintf(&expected_data_result.output, "Answer failed to match expectation"); + mp_add_subcheck_to_check(&overall, expected_data_result); + } - putchar('\n'); - return result; + /* reset the alarm */ + alarm(0); + + mp_exit(overall); } /* process command-line arguments */ -static int process_arguments(int argc, char **argv) { +static process_arguments_wrapper process_arguments(int argc, char **argv, check_tcp_config config) { enum { SNI_OPTION = CHAR_MAX + 1 }; + int option = 0; static struct option longopts[] = {{"hostname", required_argument, 0, 'H'}, {"critical", required_argument, 0, 'c'}, {"warning", required_argument, 0, 'w'}, @@ -406,52 +486,44 @@ static int process_arguments(int argc, char **argv) { {"certificate", required_argument, 0, 'D'}, {0, 0, 0, 0}}; - if (argc < 2) + if (argc < 2) { usage4(_("No arguments found")); - - /* backwards compatibility */ - for (int i = 1; i < argc; i++) { - if (strcmp("-to", argv[i]) == 0) - strcpy(argv[i], "-t"); - else if (strcmp("-wt", argv[i]) == 0) - strcpy(argv[i], "-w"); - else if (strcmp("-ct", argv[i]) == 0) - strcpy(argv[i], "-c"); } if (!is_option(argv[1])) { - server_address = argv[1]; + config.server_address = argv[1]; argv[1] = argv[0]; argv = &argv[1]; argc--; } - int option_char; + int c; bool escape = false; + while (true) { - int option = 0; - option_char = getopt_long(argc, argv, "+hVv46EAH:s:e:q:m:c:w:t:p:C:W:d:Sr:jD:M:", longopts, &option); + c = getopt_long(argc, argv, "+hVv46EAH:s:e:q:m:c:w:t:p:C:W:d:Sr:jD:M:", longopts, &option); - if (option_char == -1 || option_char == EOF || option_char == 1) + if (c == -1 || c == EOF || c == 1) { break; + } - switch (option_char) { + switch (c) { case '?': /* print short usage statement if args not parsable */ usage5(); case 'h': /* help */ - print_help(); + print_help(config.service); exit(STATE_UNKNOWN); case 'V': /* version */ print_revision(progname, NP_VERSION); exit(STATE_UNKNOWN); case 'v': /* verbose mode */ - flags |= FLAG_VERBOSE; - match_flags |= NP_MATCH_VERBOSE; + verbosity++; + config.match_flags |= NP_MATCH_VERBOSE; break; - case '4': + case '4': // Apparently unused TODO address_family = AF_INET; break; - case '6': + case '6': // Apparently unused TODO #ifdef USE_IPV6 address_family = AF_INET6; #else @@ -459,163 +531,178 @@ static int process_arguments(int argc, char **argv) { #endif break; case 'H': /* hostname */ - host_specified = true; - server_address = optarg; + config.host_specified = true; + config.server_address = optarg; break; case 'c': /* critical */ - critical_time = strtod(optarg, NULL); - flags |= FLAG_TIME_CRIT; + config.critical_time = strtod(optarg, NULL); + config.critical_time_set = true; break; case 'j': /* hide output */ - flags |= FLAG_HIDE_OUTPUT; + config.hide_output = true; break; case 'w': /* warning */ - warning_time = strtod(optarg, NULL); - flags |= FLAG_TIME_WARN; - break; - case 'C': - crit_codes = realloc(crit_codes, ++crit_codes_count); - crit_codes[crit_codes_count - 1] = optarg; - break; - case 'W': - warn_codes = realloc(warn_codes, ++warn_codes_count); - warn_codes[warn_codes_count - 1] = optarg; + config.warning_time = strtod(optarg, NULL); + config.warning_time_set = true; break; case 't': /* timeout */ - if (!is_intpos(optarg)) + if (!is_intpos(optarg)) { usage4(_("Timeout interval must be a positive integer")); - else + } else { socket_timeout = atoi(optarg); + } break; case 'p': /* port */ - if (!is_intpos(optarg)) + if (!is_intpos(optarg)) { usage4(_("Port must be a positive integer")); - else - server_port = atoi(optarg); + } else { + config.server_port = atoi(optarg); + } break; case 'E': escape = true; break; case 's': - if (escape) - server_send = np_escaped_string(optarg); - else - xasprintf(&server_send, "%s", optarg); + if (escape) { + config.send = np_escaped_string(optarg); + } else { + xasprintf(&config.send, "%s", optarg); + } break; case 'e': /* expect string (may be repeated) */ - match_flags &= ~NP_MATCH_EXACT; - if (server_expect_count == 0) - server_expect = malloc(sizeof(char *) * (++server_expect_count)); - else - server_expect = realloc(server_expect, sizeof(char *) * (++server_expect_count)); - server_expect[server_expect_count - 1] = optarg; + config.match_flags &= ~NP_MATCH_EXACT; + if (config.server_expect_count == 0) { + config.server_expect = malloc(sizeof(char *) * (++config.server_expect_count)); + } else { + config.server_expect = realloc(config.server_expect, sizeof(char *) * (++config.server_expect_count)); + } + + if (config.server_expect == NULL) { + die(STATE_UNKNOWN, _("Allocation failed")); + } + config.server_expect[config.server_expect_count - 1] = optarg; break; case 'm': - if (!is_intpos(optarg)) + if (!is_intpos(optarg)) { usage4(_("Maxbytes must be a positive integer")); - else - maxbytes = strtol(optarg, NULL, 0); + } else { + config.maxbytes = strtol(optarg, NULL, 0); + } break; case 'q': - if (escape) - server_quit = np_escaped_string(optarg); - else - xasprintf(&server_quit, "%s\r\n", optarg); + if (escape) { + config.quit = np_escaped_string(optarg); + } else { + xasprintf(&config.quit, "%s\r\n", optarg); + } break; case 'r': - if (!strncmp(optarg, "ok", 2)) - econn_refuse_state = STATE_OK; - else if (!strncmp(optarg, "warn", 4)) - econn_refuse_state = STATE_WARNING; - else if (!strncmp(optarg, "crit", 4)) - econn_refuse_state = STATE_CRITICAL; - else + if (!strncmp(optarg, "ok", 2)) { + config.econn_refuse_state = STATE_OK; + } else if (!strncmp(optarg, "warn", 4)) { + config.econn_refuse_state = STATE_WARNING; + } else if (!strncmp(optarg, "crit", 4)) { + config.econn_refuse_state = STATE_CRITICAL; + } else { usage4(_("Refuse must be one of ok, warn, crit")); + } break; case 'M': - if (!strncmp(optarg, "ok", 2)) - expect_mismatch_state = STATE_OK; - else if (!strncmp(optarg, "warn", 4)) - expect_mismatch_state = STATE_WARNING; - else if (!strncmp(optarg, "crit", 4)) - expect_mismatch_state = STATE_CRITICAL; - else + if (!strncmp(optarg, "ok", 2)) { + config.expect_mismatch_state = STATE_OK; + } else if (!strncmp(optarg, "warn", 4)) { + config.expect_mismatch_state = STATE_WARNING; + } else if (!strncmp(optarg, "crit", 4)) { + config.expect_mismatch_state = STATE_CRITICAL; + } else { usage4(_("Mismatch must be one of ok, warn, crit")); + } break; case 'd': - if (is_intpos(optarg)) - delay = atoi(optarg); - else + if (is_intpos(optarg)) { + config.delay = atoi(optarg); + } else { usage4(_("Delay must be a positive integer")); + } break; - case 'D': { /* Check SSL cert validity - days 'til certificate expiration */ + case 'D': /* Check SSL cert validity - days 'til certificate expiration */ #ifdef HAVE_SSL # ifdef USE_OPENSSL /* XXX */ + { char *temp; if ((temp = strchr(optarg, ',')) != NULL) { *temp = '\0'; - if (!is_intnonneg(optarg)) + if (!is_intnonneg(optarg)) { usage2(_("Invalid certificate expiration period"), optarg); - days_till_exp_warn = atoi(optarg); + } + config.days_till_exp_warn = atoi(optarg); *temp = ','; temp++; - if (!is_intnonneg(temp)) + if (!is_intnonneg(temp)) { usage2(_("Invalid certificate expiration period"), temp); - days_till_exp_crit = atoi(temp); + } + config.days_till_exp_crit = atoi(temp); } else { - days_till_exp_crit = 0; - if (!is_intnonneg(optarg)) + config.days_till_exp_crit = 0; + if (!is_intnonneg(optarg)) { usage2(_("Invalid certificate expiration period"), optarg); - days_till_exp_warn = atoi(optarg); + } + config.days_till_exp_warn = atoi(optarg); } - check_cert = true; - flags |= FLAG_SSL; + config.check_cert = true; + config.use_tls = true; } break; # endif /* USE_OPENSSL */ #endif /* fallthrough if we don't have ssl */ case 'S': #ifdef HAVE_SSL - flags |= FLAG_SSL; + config.use_tls = true; #else die(STATE_UNKNOWN, _("Invalid option - SSL is not available")); #endif break; case SNI_OPTION: #ifdef HAVE_SSL - flags |= FLAG_SSL; - sni_specified = true; - sni = optarg; + config.use_tls = true; + config.sni_specified = true; + config.sni = optarg; #else die(STATE_UNKNOWN, _("Invalid option - SSL is not available")); #endif break; case 'A': - match_flags |= NP_MATCH_ALL; + config.match_flags |= NP_MATCH_ALL; break; } } - option_char = optind; - if (!host_specified && option_char < argc) - server_address = strdup(argv[option_char++]); + c = optind; + if (!config.host_specified && c < argc) { + config.server_address = strdup(argv[c++]); + } - if (server_address == NULL) + if (config.server_address == NULL) { usage4(_("You must provide a server address")); - else if (server_address[0] != '/' && !is_host(server_address)) - die(STATE_CRITICAL, "%s %s - %s: %s\n", SERVICE, state_text(STATE_CRITICAL), _("Invalid hostname, address or socket"), - server_address); + } else if (config.server_address[0] != '/' && !is_host(config.server_address)) { + die(STATE_CRITICAL, "%s %s - %s: %s\n", config.service, state_text(STATE_CRITICAL), _("Invalid hostname, address or socket"), + config.server_address); + } - return OK; + process_arguments_wrapper result = { + .config = config, + .errorcode = OK, + }; + return result; } -void print_help(void) { +void print_help(const char *service) { print_revision(progname, NP_VERSION); printf("Copyright (c) 1999 Ethan Galstad \n"); printf(COPYRIGHT, copyright, email); - printf(_("This plugin tests %s connections with the specified host (or unix socket).\n\n"), SERVICE); + printf(_("This plugin tests %s connections with the specified host (or unix socket).\n\n"), service); print_usage(); @@ -662,6 +749,7 @@ void print_help(void) { printf(UT_CONN_TIMEOUT, DEFAULT_SOCKET_TIMEOUT); + printf(UT_OUTPUT_FORMAT); printf(UT_VERBOSE); printf(UT_SUPPORT); diff --git a/plugins/check_tcp.d/config.h b/plugins/check_tcp.d/config.h new file mode 100644 index 00000000..7ecf51a6 --- /dev/null +++ b/plugins/check_tcp.d/config.h @@ -0,0 +1,78 @@ +#pragma once + +#include "../common.h" +#include "../../lib/utils_tcp.h" +#include + +typedef struct check_tcp_config { + char *server_address; + bool host_specified; + int server_port; // TODO can this be a uint16? + + int protocol; /* most common is default */ + char *service; + char *send; + char *quit; + char **server_expect; + size_t server_expect_count; +#ifdef HAVE_SSL + bool use_tls; + char *sni; + bool sni_specified; + bool check_cert; + int days_till_exp_warn; + int days_till_exp_crit; +#endif // HAVE_SSL + int match_flags; + int expect_mismatch_state; + unsigned int delay; + + bool warning_time_set; + double warning_time; + bool critical_time_set; + double critical_time; + + int econn_refuse_state; + + ssize_t maxbytes; + + bool hide_output; +} check_tcp_config; + +check_tcp_config check_tcp_config_init() { + check_tcp_config result = { + .server_address = "127.0.0.1", + .host_specified = false, + .server_port = 0, + + .protocol = IPPROTO_TCP, + .service = "TCP", + .send = NULL, + .quit = NULL, + .server_expect = NULL, + .server_expect_count = 0, +#ifdef HAVE_SSL + .use_tls = false, + .sni = NULL, + .sni_specified = false, + .check_cert = false, + .days_till_exp_warn = 0, + .days_till_exp_crit = 0, +#endif // HAVE_SSL + .match_flags = NP_MATCH_EXACT, + .expect_mismatch_state = STATE_WARNING, + .delay = 0, + + .warning_time_set = false, + .warning_time = 0, + .critical_time_set = false, + .critical_time = 0, + + .econn_refuse_state = STATE_CRITICAL, + + .maxbytes = 0, + + .hide_output = false, + }; + return result; +} -- 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(-) (limited to 'plugins') 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 (limited to 'plugins') 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(-) (limited to 'plugins') 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 (limited to 'plugins') 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(-) (limited to 'plugins') 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 (limited to 'plugins') 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(-) (limited to 'plugins') 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 (limited to 'plugins') 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(-) (limited to 'plugins') 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(-) (limited to 'plugins') 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 (limited to 'plugins') 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 (limited to 'plugins') 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(-) (limited to 'plugins') 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 (limited to 'plugins') 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 (limited to 'plugins') 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(-) (limited to 'plugins') 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 (limited to 'plugins') 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(-) (limited to 'plugins') 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(-) (limited to 'plugins') 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(-) (limited to 'plugins') 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 (limited to 'plugins') 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(-) (limited to 'plugins') 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 (limited to 'plugins') 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(-) (limited to 'plugins') 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(-) (limited to 'plugins') 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 (limited to 'plugins') 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(-) (limited to 'plugins') 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 (limited to 'plugins') 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(-) (limited to 'plugins') 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 (limited to 'plugins') 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(-) (limited to 'plugins') 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(-) (limited to 'plugins') 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 (limited to 'plugins') 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(-) (limited to 'plugins') 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(-) (limited to 'plugins') 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 37c543e2b20657a8f4c120ba6b52e8e605a417bb Mon Sep 17 00:00:00 2001 From: Lorenz Kästle <12514511+RincewindsHat@users.noreply.github.com> Date: Wed, 12 Mar 2025 13:50:39 +0100 Subject: Remove check_nwstat check_nwstat is a plugin which was used to determine the health of things on Novel machines. Since Novel is quite dead (even more so the product, this can be removed and this commit does just that to reduce ressource usage. --- .github/monitoring-plugins.spec | 14 - .gitignore | 1 - REQUIREMENTS | 4 - plugins/Makefile.am | 3 +- plugins/check_nwstat.c | 1527 --------------------------------------- 5 files changed, 1 insertion(+), 1548 deletions(-) delete mode 100644 plugins/check_nwstat.c (limited to 'plugins') diff --git a/.github/monitoring-plugins.spec b/.github/monitoring-plugins.spec index 64ee34f2..10799128 100644 --- a/.github/monitoring-plugins.spec +++ b/.github/monitoring-plugins.spec @@ -191,7 +191,6 @@ Requires: %{name}-nt Requires: %{name}-ntp Requires: %{name}-ntp_peer Requires: %{name}-ntp_time -Requires: %{name}-nwstat Requires: %{name}-oracle Requires: %{name}-pgsql Requires: %{name}-ping @@ -702,19 +701,6 @@ Provides check_ntp_time of the Monitoring Plugins. -# check_nwstat -%package nwstat -Summary: Monitoring Plugins - check_nwstat -Requires: %{name} = %{version}-%{release} - -%description nwstat -Provides check_nwstat of the Monitoring Plugins. - -%files nwstat -%{plugindir}/check_nwstat - - - # check_oracle %package oracle Summary: Monitoring Plugins - check_oracle diff --git a/.gitignore b/.gitignore index f9cb37e4..7f79265f 100644 --- a/.gitignore +++ b/.gitignore @@ -177,7 +177,6 @@ NP-VERSION-FILE /plugins/check_ntp /plugins/check_ntp_peer /plugins/check_ntp_time -/plugins/check_nwstat /plugins/check_pgsql /plugins/check_ping /plugins/check_pop diff --git a/REQUIREMENTS b/REQUIREMENTS index f3b1c01d..551fdb1a 100644 --- a/REQUIREMENTS +++ b/REQUIREMENTS @@ -87,10 +87,6 @@ check_ifstatus/check_ifoperstatus - Requires Net::SNMP perl module http://www.perl.com/CPAN/modules/by-authors/id/D/DT/DTOWN/ -check_nwstat: - - Requires MRTGEXT NLM for Novell Servers - http://forge.novell.com/modules/xfmod/project/?mrtgext - check_nt: - Requires NSClient to run on the NT server to monitor http://nsclient.ready2run.nl/ diff --git a/plugins/Makefile.am b/plugins/Makefile.am index 6c582a15..7c404a3b 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_ping \ + check_mrtg check_mrtgtraf check_ntp check_ntp_peer check_ping \ check_real check_smtp check_ssh check_tcp check_time check_ntp_time \ check_ups check_users negate \ urlize @EXTRAS@ @@ -131,7 +131,6 @@ check_nagios_LDADD = $(BASEOBJS) check_nt_LDADD = $(NETLIBS) check_ntp_LDADD = $(NETLIBS) $(MATHLIBS) check_ntp_peer_LDADD = $(NETLIBS) $(MATHLIBS) -check_nwstat_LDADD = $(NETLIBS) check_pgsql_LDADD = $(NETLIBS) $(PGLIBS) check_ping_LDADD = $(NETLIBS) check_procs_LDADD = $(BASEOBJS) diff --git a/plugins/check_nwstat.c b/plugins/check_nwstat.c deleted file mode 100644 index 176dfbc8..00000000 --- a/plugins/check_nwstat.c +++ /dev/null @@ -1,1527 +0,0 @@ -/***************************************************************************** - * - * Monitoring check_nwstat plugin - * - * License: GPL - * Copyright (c) 2000-2024 Monitoring Plugins Development Team - * - * Description: - * - * This file contains the check_nwstat plugin - * - * This plugin attempts to contact the MRTGEXT NLM running on a - * Novell server 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_nwstat"; -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, /* check 1 minute CPU load */ - LOAD5, /* check 5 minute CPU load */ - LOAD15, /* check 15 minute CPU load */ - CONNS, /* check number of connections */ - VPF, /* check % free space on volume */ - VMF, /* check MB free space on volume */ - VMU, /* check MB used space on volume */ - VPU, /* check % used space on volume */ - VMP, /* check MB purgeable space on volume */ - VKF, /* check KB free space on volume */ - LTCH, /* check long-term cache hit percentage */ - CBUFF, /* check total cache buffers */ - CDBUFF, /* check dirty cache buffers */ - LRUM, /* check LRU sitting time in minutes */ - DSDB, /* check to see if DS Database is open */ - LOGINS, /* check to see if logins are enabled */ - NRMH, /* check to see NRM Health Status */ - PUPRB, /* check % of used packet receive buffers */ - UPRB, /* check used packet receive buffers */ - SAPENTRIES, /* check SAP entries */ - OFILES, /* check number of open files */ - VKP, /* check KB purgeable space on volume */ - VPP, /* check % purgeable space on volume */ - VKNP, /* check KB not yet purgeable space on volume */ - VPNP, /* check % not yet purgeable space on volume */ - ABENDS, /* check abended thread count */ - CSPROCS, /* check number of current service processes */ - TSYNC, /* check timesync status 0=no 1=yes in sync to the network */ - LRUS, /* check LRU sitting time in seconds */ - DCB, /* check dirty cache buffers as a percentage of the total */ - TCB, /* check total cache buffers as a percentage of the original */ - DSVER, /* check NDS version */ - UPTIME, /* check server uptime */ - NLM, /* check NLM loaded */ - NRMP, /* check NRM Process Values */ - NRMM, /* check NRM Memory Values */ - NRMS, /* check NRM Values */ - NSS1, /* check Statistics from _Admin:Manage_NSS\GeneralStats.xml */ - NSS2, /* check Statistics from _Admin:Manage_NSS\BufferCache.xml */ - NSS3, /* check statistics from _Admin:Manage_NSS\NameCache.xml */ - NSS4, /* check statistics from _Admin:Manage_NSS\FileStats.xml */ - NSS5, /* check statistics from _Admin:Manage_NSS\ObjectCache.xml */ - NSS6, /* check statistics from _Admin:Manage_NSS\Thread.xml */ - NSS7 /* check statistics from _Admin:Manage_NSS\AuthorizationCache.xml */ -}; - -enum { - PORT = 9999 -}; - -static char *server_address = NULL; -static char *volume_name = NULL; -static char *nlm_name = NULL; -static char *nrmp_name = NULL; -static char *nrmm_name = NULL; -static char *nrms_name = NULL; -static char *nss1_name = NULL; -static char *nss2_name = NULL; -static char *nss3_name = NULL; -static char *nss4_name = NULL; -static char *nss5_name = NULL; -static char *nss6_name = NULL; -static char *nss7_name = NULL; -static int server_port = PORT; -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 bool check_netware_version = false; -static enum checkvar vars_to_check = NONE; -static int sap_number = -1; - -static int process_arguments(int /*argc*/, char ** /*argv*/); -static void print_help(void); -void print_usage(void); - -int main(int argc, char **argv) { - int result = STATE_UNKNOWN; - int sd; - char *send_buffer = NULL; - char recv_buffer[MAX_INPUT_BUFFER]; - char *output_message = NULL; - char *temp_buffer = NULL; - char *netware_version = NULL; - - int time_sync_status = 0; - int nrm_health_status = 0; - unsigned long total_cache_buffers = 0; - unsigned long dirty_cache_buffers = 0; - unsigned long open_files = 0; - unsigned long abended_threads = 0; - unsigned long max_service_processes = 0; - unsigned long current_service_processes = 0; - unsigned long free_disk_space = 0L; - unsigned long nrmp_value = 0L; - unsigned long nrmm_value = 0L; - unsigned long nrms_value = 0L; - unsigned long nss1_value = 0L; - unsigned long nss2_value = 0L; - unsigned long nss3_value = 0L; - unsigned long nss4_value = 0L; - unsigned long nss5_value = 0L; - unsigned long nss6_value = 0L; - unsigned long nss7_value = 0L; - unsigned long total_disk_space = 0L; - unsigned long used_disk_space = 0L; - unsigned long percent_used_disk_space = 0L; - unsigned long purgeable_disk_space = 0L; - unsigned long non_purgeable_disk_space = 0L; - unsigned long percent_free_space = 0; - unsigned long percent_purgeable_space = 0; - unsigned long percent_non_purgeable_space = 0; - unsigned long current_connections = 0L; - unsigned long utilization = 0L; - unsigned long cache_hits = 0; - unsigned long cache_buffers = 0L; - unsigned long lru_time = 0L; - unsigned long max_packet_receive_buffers = 0; - unsigned long used_packet_receive_buffers = 0; - unsigned long percent_used_packet_receive_buffers = 0L; - unsigned long sap_entries = 0; - char uptime[MAX_INPUT_BUFFER]; - - 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); - - /* open connection */ - my_tcp_connect(server_address, server_port, &sd); - - /* get OS version string */ - if (check_netware_version) { - send_buffer = strdup("S19\r\n"); - result = send_tcp_request(sd, send_buffer, recv_buffer, sizeof(recv_buffer)); - if (result != STATE_OK) - return result; - if (!strcmp(recv_buffer, "-1\n")) - netware_version = strdup(""); - else { - recv_buffer[strlen(recv_buffer) - 1] = 0; - xasprintf(&netware_version, _("NetWare %s: "), recv_buffer); - } - } else - netware_version = strdup(""); - - /* check CPU load */ - if (vars_to_check == LOAD1 || vars_to_check == LOAD5 || vars_to_check == LOAD15) { - - switch (vars_to_check) { - case LOAD1: - temp_buffer = strdup("1"); - break; - case LOAD5: - temp_buffer = strdup("5"); - break; - default: - temp_buffer = strdup("15"); - break; - } - - close(sd); - my_tcp_connect(server_address, server_port, &sd); - - xasprintf(&send_buffer, "UTIL%s\r\n", temp_buffer); - result = send_tcp_request(sd, send_buffer, recv_buffer, sizeof(recv_buffer)); - if (result != STATE_OK) - return result; - utilization = strtoul(recv_buffer, NULL, 10); - - close(sd); - my_tcp_connect(server_address, server_port, &sd); - - send_buffer = strdup("UPTIME\r\n"); - result = send_tcp_request(sd, send_buffer, recv_buffer, sizeof(recv_buffer)); - if (result != STATE_OK) - return result; - recv_buffer[strlen(recv_buffer) - 1] = 0; - sprintf(uptime, _("Up %s,"), recv_buffer); - - if (check_critical_value && utilization >= critical_value) - result = STATE_CRITICAL; - else if (check_warning_value && utilization >= warning_value) - result = STATE_WARNING; - - xasprintf(&output_message, _("Load %s - %s %s-min load average = %lu%%|load%s=%lu;%lu;%lu;0;100"), state_text(result), uptime, - temp_buffer, utilization, temp_buffer, utilization, warning_value, critical_value); - - /* check number of user connections */ - } else if (vars_to_check == CONNS) { - - close(sd); - my_tcp_connect(server_address, server_port, &sd); - - send_buffer = strdup("CONNECT\r\n"); - result = send_tcp_request(sd, send_buffer, recv_buffer, sizeof(recv_buffer)); - if (result != STATE_OK) - return result; - current_connections = strtoul(recv_buffer, NULL, 10); - - if (check_critical_value && current_connections >= critical_value) - result = STATE_CRITICAL; - else if (check_warning_value && current_connections >= warning_value) - result = STATE_WARNING; - - xasprintf(&output_message, _("Conns %s - %lu current connections|Conns=%lu;%lu;%lu;;"), state_text(result), current_connections, - current_connections, warning_value, critical_value); - - /* check % long term cache hits */ - } else if (vars_to_check == LTCH) { - - close(sd); - my_tcp_connect(server_address, server_port, &sd); - - send_buffer = strdup("S1\r\n"); - result = send_tcp_request(sd, send_buffer, recv_buffer, sizeof(recv_buffer)); - if (result != STATE_OK) - return result; - cache_hits = atoi(recv_buffer); - - if (check_critical_value && cache_hits <= critical_value) - result = STATE_CRITICAL; - else if (check_warning_value && cache_hits <= warning_value) - result = STATE_WARNING; - - xasprintf(&output_message, _("%s: Long term cache hits = %lu%%"), state_text(result), cache_hits); - - /* check cache buffers */ - } else if (vars_to_check == CBUFF) { - - close(sd); - my_tcp_connect(server_address, server_port, &sd); - - send_buffer = strdup("S2\r\n"); - result = send_tcp_request(sd, send_buffer, recv_buffer, sizeof(recv_buffer)); - if (result != STATE_OK) - return result; - cache_buffers = strtoul(recv_buffer, NULL, 10); - - if (check_critical_value && cache_buffers <= critical_value) - result = STATE_CRITICAL; - else if (check_warning_value && cache_buffers <= warning_value) - result = STATE_WARNING; - - xasprintf(&output_message, _("%s: Total cache buffers = %lu|Cachebuffers=%lu;%lu;%lu;;"), state_text(result), cache_buffers, - cache_buffers, warning_value, critical_value); - - /* check dirty cache buffers */ - } else if (vars_to_check == CDBUFF) { - - close(sd); - my_tcp_connect(server_address, server_port, &sd); - - send_buffer = strdup("S3\r\n"); - result = send_tcp_request(sd, send_buffer, recv_buffer, sizeof(recv_buffer)); - if (result != STATE_OK) - return result; - cache_buffers = strtoul(recv_buffer, NULL, 10); - - if (check_critical_value && cache_buffers >= critical_value) - result = STATE_CRITICAL; - else if (check_warning_value && cache_buffers >= warning_value) - result = STATE_WARNING; - - xasprintf(&output_message, _("%s: Dirty cache buffers = %lu|Dirty-Cache-Buffers=%lu;%lu;%lu;;"), state_text(result), cache_buffers, - cache_buffers, warning_value, critical_value); - - /* check LRU sitting time in minutes */ - } else if (vars_to_check == LRUM) { - - close(sd); - my_tcp_connect(server_address, server_port, &sd); - - send_buffer = strdup("S5\r\n"); - result = send_tcp_request(sd, send_buffer, recv_buffer, sizeof(recv_buffer)); - if (result != STATE_OK) - return result; - lru_time = strtoul(recv_buffer, NULL, 10); - - if (check_critical_value && lru_time <= critical_value) - result = STATE_CRITICAL; - else if (check_warning_value && lru_time <= warning_value) - result = STATE_WARNING; - - xasprintf(&output_message, _("%s: LRU sitting time = %lu minutes"), state_text(result), lru_time); - - /* check KB free space on volume */ - } else if (vars_to_check == VKF) { - - close(sd); - my_tcp_connect(server_address, server_port, &sd); - - xasprintf(&send_buffer, "VKF%s\r\n", volume_name); - result = send_tcp_request(sd, send_buffer, recv_buffer, sizeof(recv_buffer)); - if (result != STATE_OK) - return result; - - if (!strcmp(recv_buffer, "-1\n")) { - xasprintf(&output_message, _("CRITICAL - Volume '%s' does not exist!"), volume_name); - result = STATE_CRITICAL; - } else { - free_disk_space = strtoul(recv_buffer, NULL, 10); - if (check_critical_value && free_disk_space <= critical_value) - result = STATE_CRITICAL; - else if (check_warning_value && free_disk_space <= warning_value) - result = STATE_WARNING; - xasprintf(&output_message, _("%s%lu KB free on volume %s|KBFree%s=%lu;%lu;%lu;;"), (result == STATE_OK) ? "" : _("Only "), - free_disk_space, volume_name, volume_name, free_disk_space, warning_value, critical_value); - } - - /* check MB free space on volume */ - } else if (vars_to_check == VMF) { - - xasprintf(&send_buffer, "VMF%s\r\n", volume_name); - result = send_tcp_request(sd, send_buffer, recv_buffer, sizeof(recv_buffer)); - if (result != STATE_OK) - return result; - - if (!strcmp(recv_buffer, "-1\n")) { - xasprintf(&output_message, _("CRITICAL - Volume '%s' does not exist!"), volume_name); - result = STATE_CRITICAL; - } else { - free_disk_space = strtoul(recv_buffer, NULL, 10); - if (check_critical_value && free_disk_space <= critical_value) - result = STATE_CRITICAL; - else if (check_warning_value && free_disk_space <= warning_value) - result = STATE_WARNING; - xasprintf(&output_message, _("%s%lu MB free on volume %s|MBFree%s=%lu;%lu;%lu;;"), (result == STATE_OK) ? "" : _("Only "), - free_disk_space, volume_name, volume_name, free_disk_space, warning_value, critical_value); - } - /* check MB used space on volume */ - } else if (vars_to_check == VMU) { - - xasprintf(&send_buffer, "VMU%s\r\n", volume_name); - result = send_tcp_request(sd, send_buffer, recv_buffer, sizeof(recv_buffer)); - if (result != STATE_OK) - return result; - - if (!strcmp(recv_buffer, "-1\n")) { - xasprintf(&output_message, _("CRITICAL - Volume '%s' does not exist!"), volume_name); - result = STATE_CRITICAL; - } else { - free_disk_space = strtoul(recv_buffer, NULL, 10); - if (check_critical_value && free_disk_space <= critical_value) - result = STATE_CRITICAL; - else if (check_warning_value && free_disk_space <= warning_value) - result = STATE_WARNING; - xasprintf(&output_message, _("%s%lu MB used on volume %s|MBUsed%s=%lu;%lu;%lu;;"), (result == STATE_OK) ? "" : _("Only "), - free_disk_space, volume_name, volume_name, free_disk_space, warning_value, critical_value); - } - /* check % used space on volume */ - } else if (vars_to_check == VPU) { - close(sd); - my_tcp_connect(server_address, server_port, &sd); - - asprintf(&send_buffer, "VMU%s\r\n", volume_name); - result = send_tcp_request(sd, send_buffer, recv_buffer, sizeof(recv_buffer)); - - if (result != STATE_OK) - return result; - - if (!strcmp(recv_buffer, "-1\n")) { - asprintf(&output_message, _("CRITICAL - Volume '%s' does not exist!"), volume_name); - result = STATE_CRITICAL; - - } else { - used_disk_space = strtoul(recv_buffer, NULL, 10); - close(sd); - my_tcp_connect(server_address, server_port, &sd); - /* get total volume in MB */ - asprintf(&send_buffer, "VMS%s\r\n", volume_name); - result = send_tcp_request(sd, send_buffer, recv_buffer, sizeof(recv_buffer)); - if (result != STATE_OK) - return result; - total_disk_space = strtoul(recv_buffer, NULL, 10); - /* calculate percent used on volume */ - percent_used_disk_space = (unsigned long)(((double)used_disk_space / (double)total_disk_space) * 100.0); - - 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; - - asprintf(&output_message, _("%lu MB (%lu%%) used on volume %s - total %lu MB|Used space in percent on %s=%lu;%lu;%lu;0;100"), - used_disk_space, percent_used_disk_space, volume_name, total_disk_space, volume_name, percent_used_disk_space, - warning_value, critical_value); - } - - /* check % free space on volume */ - } else if (vars_to_check == VPF) { - - close(sd); - my_tcp_connect(server_address, server_port, &sd); - - xasprintf(&send_buffer, "VKF%s\r\n", volume_name); - result = send_tcp_request(sd, send_buffer, recv_buffer, sizeof(recv_buffer)); - if (result != STATE_OK) - return result; - - if (!strcmp(recv_buffer, "-1\n")) { - - xasprintf(&output_message, _("CRITICAL - Volume '%s' does not exist!"), volume_name); - result = STATE_CRITICAL; - - } else { - - free_disk_space = strtoul(recv_buffer, NULL, 10); - - close(sd); - my_tcp_connect(server_address, server_port, &sd); - - xasprintf(&send_buffer, "VKS%s\r\n", volume_name); - result = send_tcp_request(sd, send_buffer, recv_buffer, sizeof(recv_buffer)); - if (result != STATE_OK) - return result; - total_disk_space = strtoul(recv_buffer, NULL, 10); - - percent_free_space = (unsigned long)(((double)free_disk_space / (double)total_disk_space) * 100.0); - - if (check_critical_value && percent_free_space <= critical_value) - result = STATE_CRITICAL; - else if (check_warning_value && percent_free_space <= warning_value) - result = STATE_WARNING; - free_disk_space /= 1024; - total_disk_space /= 1024; - xasprintf(&output_message, _("%lu MB (%lu%%) free on volume %s - total %lu MB|FreeMB%s=%lu;%lu;%lu;0;100"), free_disk_space, - percent_free_space, volume_name, total_disk_space, volume_name, percent_free_space, warning_value, critical_value); - } - - /* check to see if DS Database is open or closed */ - } else if (vars_to_check == DSDB) { - - close(sd); - my_tcp_connect(server_address, server_port, &sd); - - send_buffer = strdup("S11\r\n"); - result = send_tcp_request(sd, send_buffer, recv_buffer, sizeof(recv_buffer)); - if (result != STATE_OK) - return result; - if (atoi(recv_buffer) == 1) - result = STATE_OK; - else - result = STATE_WARNING; - - close(sd); - my_tcp_connect(server_address, server_port, &sd); - - send_buffer = strdup("S13\r\n"); - result = send_tcp_request(sd, send_buffer, recv_buffer, sizeof(recv_buffer)); - temp_buffer = strtok(recv_buffer, "\r\n"); - - xasprintf(&output_message, _("Directory Services Database is %s (DS version %s)"), (result == STATE_OK) ? "open" : "closed", - temp_buffer); - - /* check to see if logins are enabled */ - } else if (vars_to_check == LOGINS) { - - close(sd); - my_tcp_connect(server_address, server_port, &sd); - - send_buffer = strdup("S12\r\n"); - result = send_tcp_request(sd, send_buffer, recv_buffer, sizeof(recv_buffer)); - if (result != STATE_OK) - return result; - if (atoi(recv_buffer) == 1) - result = STATE_OK; - else - result = STATE_WARNING; - - xasprintf(&output_message, _("Logins are %s"), (result == STATE_OK) ? _("enabled") : _("disabled")); - - /* check NRM Health Status Summary*/ - } else if (vars_to_check == NRMH) { - - xasprintf(&send_buffer, "NRMH\r\n"); - result = send_tcp_request(sd, send_buffer, recv_buffer, sizeof(recv_buffer)); - if (result != STATE_OK) - return result; - - nrm_health_status = atoi(recv_buffer); - - if (nrm_health_status == 2) { - result = STATE_OK; - xasprintf(&output_message, _("CRITICAL - NRM Status is bad!")); - } else { - if (nrm_health_status == 1) { - result = STATE_WARNING; - xasprintf(&output_message, _("Warning - NRM Status is suspect!")); - } - - xasprintf(&output_message, _("OK - NRM Status is good!")); - } - - /* check packet receive buffers */ - } else if (vars_to_check == UPRB || vars_to_check == PUPRB) { - - close(sd); - my_tcp_connect(server_address, server_port, &sd); - - xasprintf(&send_buffer, "S15\r\n"); - result = send_tcp_request(sd, send_buffer, recv_buffer, sizeof(recv_buffer)); - if (result != STATE_OK) - return result; - - used_packet_receive_buffers = atoi(recv_buffer); - - close(sd); - my_tcp_connect(server_address, server_port, &sd); - - xasprintf(&send_buffer, "S16\r\n"); - result = send_tcp_request(sd, send_buffer, recv_buffer, sizeof(recv_buffer)); - if (result != STATE_OK) - return result; - - max_packet_receive_buffers = atoi(recv_buffer); - - percent_used_packet_receive_buffers = - (unsigned long)(((double)used_packet_receive_buffers / (double)max_packet_receive_buffers) * 100.0); - - if (vars_to_check == UPRB) { - if (check_critical_value && used_packet_receive_buffers >= critical_value) - result = STATE_CRITICAL; - else if (check_warning_value && used_packet_receive_buffers >= warning_value) - result = STATE_WARNING; - } else { - if (check_critical_value && percent_used_packet_receive_buffers >= critical_value) - result = STATE_CRITICAL; - else if (check_warning_value && percent_used_packet_receive_buffers >= warning_value) - result = STATE_WARNING; - } - - xasprintf(&output_message, _("%lu of %lu (%lu%%) packet receive buffers used"), used_packet_receive_buffers, - max_packet_receive_buffers, percent_used_packet_receive_buffers); - - /* check SAP table entries */ - } else if (vars_to_check == SAPENTRIES) { - - close(sd); - my_tcp_connect(server_address, server_port, &sd); - - if (sap_number == -1) - xasprintf(&send_buffer, "S9\r\n"); - else - xasprintf(&send_buffer, "S9.%d\r\n", sap_number); - result = send_tcp_request(sd, send_buffer, recv_buffer, sizeof(recv_buffer)); - if (result != STATE_OK) - return result; - - sap_entries = atoi(recv_buffer); - - if (check_critical_value && sap_entries >= critical_value) - result = STATE_CRITICAL; - else if (check_warning_value && sap_entries >= warning_value) - result = STATE_WARNING; - - if (sap_number == -1) - xasprintf(&output_message, _("%lu entries in SAP table"), sap_entries); - else - xasprintf(&output_message, _("%lu entries in SAP table for SAP type %d"), sap_entries, sap_number); - - /* check KB purgeable space on volume */ - } else if (vars_to_check == VKP) { - - close(sd); - my_tcp_connect(server_address, server_port, &sd); - - xasprintf(&send_buffer, "VKP%s\r\n", volume_name); - result = send_tcp_request(sd, send_buffer, recv_buffer, sizeof(recv_buffer)); - if (result != STATE_OK) - return result; - - if (!strcmp(recv_buffer, "-1\n")) { - xasprintf(&output_message, _("CRITICAL - Volume '%s' does not exist!"), volume_name); - result = STATE_CRITICAL; - } else { - purgeable_disk_space = strtoul(recv_buffer, NULL, 10); - if (check_critical_value && purgeable_disk_space >= critical_value) - result = STATE_CRITICAL; - else if (check_warning_value && purgeable_disk_space >= warning_value) - result = STATE_WARNING; - xasprintf(&output_message, _("%s%lu KB purgeable on volume %s|Purge%s=%lu;%lu;%lu;;"), (result == STATE_OK) ? "" : _("Only "), - purgeable_disk_space, volume_name, volume_name, purgeable_disk_space, warning_value, critical_value); - } - /* check MB purgeable space on volume */ - } else if (vars_to_check == VMP) { - - xasprintf(&send_buffer, "VMP%s\r\n", volume_name); - result = send_tcp_request(sd, send_buffer, recv_buffer, sizeof(recv_buffer)); - if (result != STATE_OK) - return result; - - if (!strcmp(recv_buffer, "-1\n")) { - xasprintf(&output_message, _("CRITICAL - Volume '%s' does not exist!"), volume_name); - result = STATE_CRITICAL; - } else { - purgeable_disk_space = strtoul(recv_buffer, NULL, 10); - if (check_critical_value && purgeable_disk_space >= critical_value) - result = STATE_CRITICAL; - else if (check_warning_value && purgeable_disk_space >= warning_value) - result = STATE_WARNING; - xasprintf(&output_message, _("%s%lu MB purgeable on volume %s|Purge%s=%lu;%lu;%lu;;"), (result == STATE_OK) ? "" : _("Only "), - purgeable_disk_space, volume_name, volume_name, purgeable_disk_space, warning_value, critical_value); - } - - /* check % purgeable space on volume */ - } else if (vars_to_check == VPP) { - - close(sd); - my_tcp_connect(server_address, server_port, &sd); - - xasprintf(&send_buffer, "VKP%s\r\n", volume_name); - result = send_tcp_request(sd, send_buffer, recv_buffer, sizeof(recv_buffer)); - if (result != STATE_OK) - return result; - - if (!strcmp(recv_buffer, "-1\n")) { - - xasprintf(&output_message, _("CRITICAL - Volume '%s' does not exist!"), volume_name); - result = STATE_CRITICAL; - - } else { - - purgeable_disk_space = strtoul(recv_buffer, NULL, 10); - - close(sd); - my_tcp_connect(server_address, server_port, &sd); - - xasprintf(&send_buffer, "VKS%s\r\n", volume_name); - result = send_tcp_request(sd, send_buffer, recv_buffer, sizeof(recv_buffer)); - if (result != STATE_OK) - return result; - total_disk_space = strtoul(recv_buffer, NULL, 10); - - percent_purgeable_space = (unsigned long)(((double)purgeable_disk_space / (double)total_disk_space) * 100.0); - - if (check_critical_value && percent_purgeable_space >= critical_value) - result = STATE_CRITICAL; - else if (check_warning_value && percent_purgeable_space >= warning_value) - result = STATE_WARNING; - purgeable_disk_space /= 1024; - xasprintf(&output_message, _("%lu MB (%lu%%) purgeable on volume %s|Purgeable%s=%lu;%lu;%lu;0;100"), purgeable_disk_space, - percent_purgeable_space, volume_name, volume_name, percent_purgeable_space, warning_value, critical_value); - } - - /* check KB not yet purgeable space on volume */ - } else if (vars_to_check == VKNP) { - - close(sd); - my_tcp_connect(server_address, server_port, &sd); - - xasprintf(&send_buffer, "VKNP%s\r\n", volume_name); - result = send_tcp_request(sd, send_buffer, recv_buffer, sizeof(recv_buffer)); - if (result != STATE_OK) - return result; - - if (!strcmp(recv_buffer, "-1\n")) { - xasprintf(&output_message, _("CRITICAL - Volume '%s' does not exist!"), volume_name); - result = STATE_CRITICAL; - } else { - non_purgeable_disk_space = strtoul(recv_buffer, NULL, 10); - if (check_critical_value && non_purgeable_disk_space >= critical_value) - result = STATE_CRITICAL; - else if (check_warning_value && non_purgeable_disk_space >= warning_value) - result = STATE_WARNING; - xasprintf(&output_message, _("%s%lu KB not yet purgeable on volume %s"), (result == STATE_OK) ? "" : _("Only "), - non_purgeable_disk_space, volume_name); - } - - /* check % not yet purgeable space on volume */ - } else if (vars_to_check == VPNP) { - - close(sd); - my_tcp_connect(server_address, server_port, &sd); - - xasprintf(&send_buffer, "VKNP%s\r\n", volume_name); - result = send_tcp_request(sd, send_buffer, recv_buffer, sizeof(recv_buffer)); - if (result != STATE_OK) - return result; - - if (!strcmp(recv_buffer, "-1\n")) { - - xasprintf(&output_message, _("CRITICAL - Volume '%s' does not exist!"), volume_name); - result = STATE_CRITICAL; - - } else { - - non_purgeable_disk_space = strtoul(recv_buffer, NULL, 10); - - close(sd); - my_tcp_connect(server_address, server_port, &sd); - - xasprintf(&send_buffer, "VKS%s\r\n", volume_name); - result = send_tcp_request(sd, send_buffer, recv_buffer, sizeof(recv_buffer)); - if (result != STATE_OK) - return result; - total_disk_space = strtoul(recv_buffer, NULL, 10); - - percent_non_purgeable_space = (unsigned long)(((double)non_purgeable_disk_space / (double)total_disk_space) * 100.0); - - if (check_critical_value && percent_non_purgeable_space >= critical_value) - result = STATE_CRITICAL; - else if (check_warning_value && percent_non_purgeable_space >= warning_value) - result = STATE_WARNING; - purgeable_disk_space /= 1024; - xasprintf(&output_message, _("%lu MB (%lu%%) not yet purgeable on volume %s"), non_purgeable_disk_space, - percent_non_purgeable_space, volume_name); - } - - /* check # of open files */ - } else if (vars_to_check == OFILES) { - - close(sd); - my_tcp_connect(server_address, server_port, &sd); - - xasprintf(&send_buffer, "S18\r\n"); - result = send_tcp_request(sd, send_buffer, recv_buffer, sizeof(recv_buffer)); - if (result != STATE_OK) - return result; - - open_files = atoi(recv_buffer); - - if (check_critical_value && open_files >= critical_value) - result = STATE_CRITICAL; - else if (check_warning_value && open_files >= warning_value) - result = STATE_WARNING; - - xasprintf(&output_message, _("%lu open files|Openfiles=%lu;%lu;%lu;0,0"), open_files, open_files, warning_value, critical_value); - - /* check # of abended threads (Netware > 5.x only) */ - } else if (vars_to_check == ABENDS) { - - close(sd); - my_tcp_connect(server_address, server_port, &sd); - - xasprintf(&send_buffer, "S17\r\n"); - result = send_tcp_request(sd, send_buffer, recv_buffer, sizeof(recv_buffer)); - if (result != STATE_OK) - return result; - - abended_threads = atoi(recv_buffer); - - if (check_critical_value && abended_threads >= critical_value) - result = STATE_CRITICAL; - else if (check_warning_value && abended_threads >= warning_value) - result = STATE_WARNING; - - xasprintf(&output_message, _("%lu abended threads|Abends=%lu;%lu;%lu;;"), abended_threads, abended_threads, warning_value, - critical_value); - - /* check # of current service processes (Netware 5.x only) */ - } else if (vars_to_check == CSPROCS) { - - close(sd); - my_tcp_connect(server_address, server_port, &sd); - - xasprintf(&send_buffer, "S20\r\n"); - result = send_tcp_request(sd, send_buffer, recv_buffer, sizeof(recv_buffer)); - if (result != STATE_OK) - return result; - - max_service_processes = atoi(recv_buffer); - - close(sd); - my_tcp_connect(server_address, server_port, &sd); - - xasprintf(&send_buffer, "S21\r\n"); - result = send_tcp_request(sd, send_buffer, recv_buffer, sizeof(recv_buffer)); - if (result != STATE_OK) - return result; - - current_service_processes = atoi(recv_buffer); - - if (check_critical_value && current_service_processes >= critical_value) - result = STATE_CRITICAL; - else if (check_warning_value && current_service_processes >= warning_value) - result = STATE_WARNING; - - xasprintf(&output_message, _("%lu current service processes (%lu max)|Processes=%lu;%lu;%lu;0;%lu"), current_service_processes, - max_service_processes, current_service_processes, warning_value, critical_value, max_service_processes); - - /* check # Timesync Status */ - } else if (vars_to_check == TSYNC) { - - close(sd); - my_tcp_connect(server_address, server_port, &sd); - - xasprintf(&send_buffer, "S22\r\n"); - result = send_tcp_request(sd, send_buffer, recv_buffer, sizeof(recv_buffer)); - if (result != STATE_OK) - return result; - - time_sync_status = atoi(recv_buffer); - - if (time_sync_status == 0) { - result = STATE_CRITICAL; - xasprintf(&output_message, _("CRITICAL - Time not in sync with network!")); - } else { - xasprintf(&output_message, _("OK - Time in sync with network!")); - } - - /* check LRU sitting time in secondss */ - } else if (vars_to_check == LRUS) { - - close(sd); - my_tcp_connect(server_address, server_port, &sd); - - send_buffer = strdup("S4\r\n"); - result = send_tcp_request(sd, send_buffer, recv_buffer, sizeof(recv_buffer)); - if (result != STATE_OK) - return result; - lru_time = strtoul(recv_buffer, NULL, 10); - - if (check_critical_value && lru_time <= critical_value) - result = STATE_CRITICAL; - else if (check_warning_value && lru_time <= warning_value) - result = STATE_WARNING; - xasprintf(&output_message, _("LRU sitting time = %lu seconds"), lru_time); - - /* check % dirty cacheobuffers as a percentage of the total*/ - } else if (vars_to_check == DCB) { - - close(sd); - my_tcp_connect(server_address, server_port, &sd); - - send_buffer = strdup("S6\r\n"); - result = send_tcp_request(sd, send_buffer, recv_buffer, sizeof(recv_buffer)); - if (result != STATE_OK) - return result; - dirty_cache_buffers = atoi(recv_buffer); - - if (check_critical_value && dirty_cache_buffers <= critical_value) - result = STATE_CRITICAL; - else if (check_warning_value && dirty_cache_buffers <= warning_value) - result = STATE_WARNING; - xasprintf(&output_message, _("Dirty cache buffers = %lu%% of the total|DCB=%lu;%lu;%lu;0;100"), dirty_cache_buffers, - dirty_cache_buffers, warning_value, critical_value); - - /* check % total cache buffers as a percentage of the original*/ - } else if (vars_to_check == TCB) { - - close(sd); - my_tcp_connect(server_address, server_port, &sd); - - send_buffer = strdup("S7\r\n"); - result = send_tcp_request(sd, send_buffer, recv_buffer, sizeof(recv_buffer)); - if (result != STATE_OK) - return result; - total_cache_buffers = atoi(recv_buffer); - - if (check_critical_value && total_cache_buffers <= critical_value) - result = STATE_CRITICAL; - else if (check_warning_value && total_cache_buffers <= warning_value) - result = STATE_WARNING; - xasprintf(&output_message, _("Total cache buffers = %lu%% of the original|TCB=%lu;%lu;%lu;0;100"), total_cache_buffers, - total_cache_buffers, warning_value, critical_value); - - } else if (vars_to_check == DSVER) { - - close(sd); - my_tcp_connect(server_address, server_port, &sd); - - xasprintf(&send_buffer, "S13\r\n"); - result = send_tcp_request(sd, send_buffer, recv_buffer, sizeof(recv_buffer)); - if (result != STATE_OK) - return result; - - recv_buffer[strlen(recv_buffer) - 1] = 0; - - xasprintf(&output_message, _("NDS Version %s"), recv_buffer); - - } else if (vars_to_check == UPTIME) { - - close(sd); - my_tcp_connect(server_address, server_port, &sd); - - xasprintf(&send_buffer, "UPTIME\r\n"); - result = send_tcp_request(sd, send_buffer, recv_buffer, sizeof(recv_buffer)); - if (result != STATE_OK) - return result; - - recv_buffer[sizeof(recv_buffer) - 1] = 0; - recv_buffer[strlen(recv_buffer) - 1] = 0; - - xasprintf(&output_message, _("Up %s"), recv_buffer); - - } else if (vars_to_check == NLM) { - - close(sd); - my_tcp_connect(server_address, server_port, &sd); - - xasprintf(&send_buffer, "S24:%s\r\n", nlm_name); - result = send_tcp_request(sd, send_buffer, recv_buffer, sizeof(recv_buffer)); - if (result != STATE_OK) - return result; - - recv_buffer[strlen(recv_buffer) - 1] = 0; - if (strcmp(recv_buffer, "-1")) { - xasprintf(&output_message, _("Module %s version %s is loaded"), nlm_name, recv_buffer); - } else { - result = STATE_CRITICAL; - xasprintf(&output_message, _("Module %s is not loaded"), nlm_name); - } - } else if (vars_to_check == NRMP) { - - xasprintf(&send_buffer, "NRMP:%s\r\n", nrmp_name); - result = send_tcp_request(sd, send_buffer, recv_buffer, sizeof(recv_buffer)); - if (result != STATE_OK) - return result; - - if (!strcmp(recv_buffer, "-1\n")) { - xasprintf(&output_message, _("CRITICAL - Value '%s' does not exist!"), nrmp_name); - result = STATE_CRITICAL; - } else { - nrmp_value = strtoul(recv_buffer, NULL, 10); - if (check_critical_value && nrmp_value <= critical_value) - result = STATE_CRITICAL; - else if (check_warning_value && nrmp_value <= warning_value) - result = STATE_WARNING; - xasprintf(&output_message, _("%s is %lu|%s=%lu;%lu;%lu;;"), nrmp_name, nrmp_value, nrmp_name, nrmp_value, warning_value, - critical_value); - } - - } else if (vars_to_check == NRMM) { - - xasprintf(&send_buffer, "NRMM:%s\r\n", nrmm_name); - result = send_tcp_request(sd, send_buffer, recv_buffer, sizeof(recv_buffer)); - if (result != STATE_OK) - return result; - - if (!strcmp(recv_buffer, "-1\n")) { - xasprintf(&output_message, _("CRITICAL - Value '%s' does not exist!"), nrmm_name); - result = STATE_CRITICAL; - } else { - nrmm_value = strtoul(recv_buffer, NULL, 10); - if (check_critical_value && nrmm_value <= critical_value) - result = STATE_CRITICAL; - else if (check_warning_value && nrmm_value <= warning_value) - result = STATE_WARNING; - xasprintf(&output_message, _("%s is %lu|%s=%lu;%lu;%lu;;"), nrmm_name, nrmm_value, nrmm_name, nrmm_value, warning_value, - critical_value); - } - - } else if (vars_to_check == NRMS) { - - xasprintf(&send_buffer, "NRMS:%s\r\n", nrms_name); - result = send_tcp_request(sd, send_buffer, recv_buffer, sizeof(recv_buffer)); - if (result != STATE_OK) - return result; - - if (!strcmp(recv_buffer, "-1\n")) { - xasprintf(&output_message, _("CRITICAL - Value '%s' does not exist!"), nrms_name); - result = STATE_CRITICAL; - } else { - nrms_value = strtoul(recv_buffer, NULL, 10); - if (check_critical_value && nrms_value >= critical_value) - result = STATE_CRITICAL; - else if (check_warning_value && nrms_value >= warning_value) - result = STATE_WARNING; - xasprintf(&output_message, _("%s is %lu|%s=%lu;%lu;%lu;;"), nrms_name, nrms_value, nrms_name, nrms_value, warning_value, - critical_value); - } - - } else if (vars_to_check == NSS1) { - - xasprintf(&send_buffer, "NSS1:%s\r\n", nss1_name); - result = send_tcp_request(sd, send_buffer, recv_buffer, sizeof(recv_buffer)); - if (result != STATE_OK) - return result; - - if (!strcmp(recv_buffer, "-1\n")) { - xasprintf(&output_message, _("CRITICAL - Value '%s' does not exist!"), nss1_name); - result = STATE_CRITICAL; - } else { - nss1_value = strtoul(recv_buffer, NULL, 10); - if (check_critical_value && nss1_value >= critical_value) - result = STATE_CRITICAL; - else if (check_warning_value && nss1_value >= warning_value) - result = STATE_WARNING; - xasprintf(&output_message, _("%s is %lu|%s=%lu;%lu;%lu;;"), nss1_name, nss1_value, nss1_name, nss1_value, warning_value, - critical_value); - } - - } else if (vars_to_check == NSS2) { - - xasprintf(&send_buffer, "NSS2:%s\r\n", nss2_name); - result = send_tcp_request(sd, send_buffer, recv_buffer, sizeof(recv_buffer)); - if (result != STATE_OK) - return result; - - if (!strcmp(recv_buffer, "-1\n")) { - xasprintf(&output_message, _("CRITICAL - Value '%s' does not exist!"), nss2_name); - result = STATE_CRITICAL; - } else { - nss2_value = strtoul(recv_buffer, NULL, 10); - if (check_critical_value && nss2_value >= critical_value) - result = STATE_CRITICAL; - else if (check_warning_value && nss2_value >= warning_value) - result = STATE_WARNING; - xasprintf(&output_message, _("%s is %lu|%s=%lu;%lu;%lu;;"), nss2_name, nss2_value, nss2_name, nss2_value, warning_value, - critical_value); - } - - } else if (vars_to_check == NSS3) { - - xasprintf(&send_buffer, "NSS3:%s\r\n", nss3_name); - result = send_tcp_request(sd, send_buffer, recv_buffer, sizeof(recv_buffer)); - if (result != STATE_OK) - return result; - - if (!strcmp(recv_buffer, "-1\n")) { - xasprintf(&output_message, _("CRITICAL - Value '%s' does not exist!"), nss3_name); - result = STATE_CRITICAL; - } else { - nss3_value = strtoul(recv_buffer, NULL, 10); - if (check_critical_value && nss3_value >= critical_value) - result = STATE_CRITICAL; - else if (check_warning_value && nss3_value >= warning_value) - result = STATE_WARNING; - xasprintf(&output_message, _("%s is %lu|%s=%lu;%lu;%lu;;"), nss3_name, nss3_value, nss3_name, nss3_value, warning_value, - critical_value); - } - - } else if (vars_to_check == NSS4) { - - xasprintf(&send_buffer, "NSS4:%s\r\n", nss4_name); - result = send_tcp_request(sd, send_buffer, recv_buffer, sizeof(recv_buffer)); - if (result != STATE_OK) - return result; - - if (!strcmp(recv_buffer, "-1\n")) { - xasprintf(&output_message, _("CRITICAL - Value '%s' does not exist!"), nss4_name); - result = STATE_CRITICAL; - } else { - nss4_value = strtoul(recv_buffer, NULL, 10); - if (check_critical_value && nss4_value >= critical_value) - result = STATE_CRITICAL; - else if (check_warning_value && nss4_value >= warning_value) - result = STATE_WARNING; - xasprintf(&output_message, _("%s is %lu|%s=%lu;%lu;%lu;;"), nss4_name, nss4_value, nss4_name, nss4_value, warning_value, - critical_value); - } - - } else if (vars_to_check == NSS5) { - - xasprintf(&send_buffer, "NSS5:%s\r\n", nss5_name); - result = send_tcp_request(sd, send_buffer, recv_buffer, sizeof(recv_buffer)); - if (result != STATE_OK) - return result; - - if (!strcmp(recv_buffer, "-1\n")) { - xasprintf(&output_message, _("CRITICAL - Value '%s' does not exist!"), nss5_name); - result = STATE_CRITICAL; - } else { - nss5_value = strtoul(recv_buffer, NULL, 10); - if (check_critical_value && nss5_value >= critical_value) - result = STATE_CRITICAL; - else if (check_warning_value && nss5_value >= warning_value) - result = STATE_WARNING; - xasprintf(&output_message, _("%s is %lu|%s=%lu;%lu;%lu;;"), nss5_name, nss5_value, nss5_name, nss5_value, warning_value, - critical_value); - } - - } else if (vars_to_check == NSS6) { - - xasprintf(&send_buffer, "NSS6:%s\r\n", nss6_name); - result = send_tcp_request(sd, send_buffer, recv_buffer, sizeof(recv_buffer)); - if (result != STATE_OK) - return result; - - if (!strcmp(recv_buffer, "-1\n")) { - xasprintf(&output_message, _("CRITICAL - Value '%s' does not exist!"), nss6_name); - result = STATE_CRITICAL; - } else { - nss6_value = strtoul(recv_buffer, NULL, 10); - if (check_critical_value && nss6_value >= critical_value) - result = STATE_CRITICAL; - else if (check_warning_value && nss6_value >= warning_value) - result = STATE_WARNING; - xasprintf(&output_message, _("%s is %lu|%s=%lu;%lu;%lu;;"), nss6_name, nss6_value, nss6_name, nss6_value, warning_value, - critical_value); - } - - } else if (vars_to_check == NSS7) { - - xasprintf(&send_buffer, "NSS7:%s\r\n", nss7_name); - result = send_tcp_request(sd, send_buffer, recv_buffer, sizeof(recv_buffer)); - if (result != STATE_OK) - return result; - - if (!strcmp(recv_buffer, "-1\n")) { - xasprintf(&output_message, _("CRITICAL - Value '%s' does not exist!"), nss7_name); - result = STATE_CRITICAL; - } else { - nss7_value = strtoul(recv_buffer, NULL, 10); - if (check_critical_value && nss7_value >= critical_value) - result = STATE_CRITICAL; - else if (check_warning_value && nss7_value >= warning_value) - result = STATE_WARNING; - xasprintf(&output_message, _("%s is %lu|%s=%lu;%lu;%lu;;"), nss7_name, nss7_value, nss7_name, nss7_value, warning_value, - critical_value); - } - - } else { - - output_message = strdup(_("Nothing to check!\n")); - result = STATE_UNKNOWN; - } - - close(sd); - - /* reset timeout */ - alarm(0); - - printf("%s%s\n", netware_version, output_message); - - return result; -} - -/* 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'}, - {"osversion", no_argument, 0, 'o'}, {"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, "+hoVH: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 'o': /* display nos version */ - check_netware_version = true; - break; - case 'p': /* port */ - if (is_intnonneg(optarg)) - server_port = atoi(optarg); - else - die(STATE_UNKNOWN, _("Server port an integer\n")); - break; - case 'v': - if (strlen(optarg) < 3) - return ERROR; - if (!strcmp(optarg, "LOAD1")) - vars_to_check = LOAD1; - else if (!strcmp(optarg, "LOAD5")) - vars_to_check = LOAD5; - else if (!strcmp(optarg, "LOAD15")) - vars_to_check = LOAD15; - else if (!strcmp(optarg, "CONNS")) - vars_to_check = CONNS; - else if (!strcmp(optarg, "LTCH")) - vars_to_check = LTCH; - else if (!strcmp(optarg, "DCB")) - vars_to_check = DCB; - else if (!strcmp(optarg, "TCB")) - vars_to_check = TCB; - else if (!strcmp(optarg, "CBUFF")) - vars_to_check = CBUFF; - else if (!strcmp(optarg, "CDBUFF")) - vars_to_check = CDBUFF; - else if (!strcmp(optarg, "LRUM")) - vars_to_check = LRUM; - else if (!strcmp(optarg, "LRUS")) - vars_to_check = LRUS; - else if (strncmp(optarg, "VPF", 3) == 0) { - vars_to_check = VPF; - volume_name = strdup(optarg + 3); - if (!strcmp(volume_name, "")) - volume_name = strdup("SYS"); - } else if (strncmp(optarg, "VKF", 3) == 0) { - vars_to_check = VKF; - volume_name = strdup(optarg + 3); - if (!strcmp(volume_name, "")) - volume_name = strdup("SYS"); - } else if (strncmp(optarg, "VMF", 3) == 0) { - vars_to_check = VMF; - volume_name = strdup(optarg + 3); - if (!strcmp(volume_name, "")) - volume_name = strdup("SYS"); - } else if (!strcmp(optarg, "DSDB")) - vars_to_check = DSDB; - else if (!strcmp(optarg, "LOGINS")) - vars_to_check = LOGINS; - else if (!strcmp(optarg, "NRMH")) - vars_to_check = NRMH; - else if (!strcmp(optarg, "UPRB")) - vars_to_check = UPRB; - else if (!strcmp(optarg, "PUPRB")) - vars_to_check = PUPRB; - else if (!strncmp(optarg, "SAPENTRIES", 10)) { - vars_to_check = SAPENTRIES; - if (strlen(optarg) > 10) - sap_number = atoi(optarg + 10); - else - sap_number = -1; - } else if (!strcmp(optarg, "OFILES")) - vars_to_check = OFILES; - else if (strncmp(optarg, "VKP", 3) == 0) { - vars_to_check = VKP; - volume_name = strdup(optarg + 3); - if (!strcmp(volume_name, "")) - volume_name = strdup("SYS"); - } else if (strncmp(optarg, "VMP", 3) == 0) { - vars_to_check = VMP; - volume_name = strdup(optarg + 3); - if (!strcmp(volume_name, "")) - volume_name = strdup("SYS"); - } else if (strncmp(optarg, "VMU", 3) == 0) { - vars_to_check = VMU; - volume_name = strdup(optarg + 3); - if (!strcmp(volume_name, "")) - volume_name = strdup("SYS"); - } else if (strncmp(optarg, "VPU", 3) == 0) { - vars_to_check = VPU; - volume_name = strdup(optarg + 3); - if (!strcmp(volume_name, "")) - volume_name = strdup("SYS"); - } else if (strncmp(optarg, "VPP", 3) == 0) { - vars_to_check = VPP; - volume_name = strdup(optarg + 3); - if (!strcmp(volume_name, "")) - volume_name = strdup("SYS"); - } else if (strncmp(optarg, "VKNP", 4) == 0) { - vars_to_check = VKNP; - volume_name = strdup(optarg + 4); - if (!strcmp(volume_name, "")) - volume_name = strdup("SYS"); - } else if (strncmp(optarg, "VPNP", 4) == 0) { - vars_to_check = VPNP; - volume_name = strdup(optarg + 4); - if (!strcmp(volume_name, "")) - volume_name = strdup("SYS"); - } else if (!strcmp(optarg, "ABENDS")) - vars_to_check = ABENDS; - else if (!strcmp(optarg, "CSPROCS")) - vars_to_check = CSPROCS; - else if (!strcmp(optarg, "TSYNC")) - vars_to_check = TSYNC; - else if (!strcmp(optarg, "DSVER")) - vars_to_check = DSVER; - else if (!strcmp(optarg, "UPTIME")) { - vars_to_check = UPTIME; - } else if (strncmp(optarg, "NLM:", 4) == 0) { - vars_to_check = NLM; - nlm_name = strdup(optarg + 4); - } else if (strncmp(optarg, "NRMP", 4) == 0) { - vars_to_check = NRMP; - nrmp_name = strdup(optarg + 4); - if (!strcmp(nrmp_name, "")) - nrmp_name = strdup("AVAILABLE_MEMORY"); - } else if (strncmp(optarg, "NRMM", 4) == 0) { - vars_to_check = NRMM; - nrmm_name = strdup(optarg + 4); - if (!strcmp(nrmm_name, "")) - nrmm_name = strdup("AVAILABLE_CACHE_MEMORY"); - - } - - else if (strncmp(optarg, "NRMS", 4) == 0) { - vars_to_check = NRMS; - nrms_name = strdup(optarg + 4); - if (!strcmp(nrms_name, "")) - nrms_name = strdup("USED_SWAP_SPACE"); - - } - - else if (strncmp(optarg, "NSS1", 4) == 0) { - vars_to_check = NSS1; - nss1_name = strdup(optarg + 4); - if (!strcmp(nss1_name, "")) - nss1_name = strdup("CURRENTBUFFERCACHESIZE"); - - } - - else if (strncmp(optarg, "NSS2", 4) == 0) { - vars_to_check = NSS2; - nss2_name = strdup(optarg + 4); - if (!strcmp(nss2_name, "")) - nss2_name = strdup("CACHEHITS"); - - } - - else if (strncmp(optarg, "NSS3", 4) == 0) { - vars_to_check = NSS3; - nss3_name = strdup(optarg + 4); - if (!strcmp(nss3_name, "")) - nss3_name = strdup("CACHEGITPERCENT"); - - } - - else if (strncmp(optarg, "NSS4", 4) == 0) { - vars_to_check = NSS4; - nss4_name = strdup(optarg + 4); - if (!strcmp(nss4_name, "")) - nss4_name = strdup("CURRENTOPENCOUNT"); - - } - - else if (strncmp(optarg, "NSS5", 4) == 0) { - vars_to_check = NSS5; - nss5_name = strdup(optarg + 4); - if (!strcmp(nss5_name, "")) - nss5_name = strdup("CACHEMISSES"); - - } - - else if (strncmp(optarg, "NSS6", 4) == 0) { - vars_to_check = NSS6; - nss6_name = strdup(optarg + 4); - if (!strcmp(nss6_name, "")) - nss6_name = strdup("PENDINGWORKSCOUNT"); - - } - - else if (strncmp(optarg, "NSS7", 4) == 0) { - vars_to_check = NSS7; - nss7_name = strdup(optarg + 4); - if (!strcmp(nss7_name, "")) - nss7_name = strdup("CACHESIZE"); - - } - - 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 MRTGEXT NLM running on a")); - printf("%s\n", _("Novell server 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", "-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", _("CSPROCS = number of current service processes (NW 5.x only)")); - printf(" %s\n", _("ABENDS = number of abended threads (NW 5.x only)")); - printf(" %s\n", _("UPTIME = server uptime")); - printf(" %s\n", _("LTCH = percent long term cache hits")); - printf(" %s\n", _("CBUFF = current number of cache buffers")); - printf(" %s\n", _("CDBUFF = current number of dirty cache buffers")); - printf(" %s\n", _("DCB = dirty cache buffers as a percentage of the total")); - printf(" %s\n", _("TCB = dirty cache buffers as a percentage of the original")); - printf(" %s\n", _("OFILES = number of open files")); - printf(" %s\n", _(" VMF = MB of free space on Volume ")); - printf(" %s\n", _(" VMU = MB used space on Volume ")); - printf(" %s\n", _(" VPU = percent used space on Volume ")); - printf(" %s\n", _(" VMP = MB of purgeable space on Volume ")); - printf(" %s\n", _(" VPF = percent free space on volume ")); - printf(" %s\n", _(" VKF = KB of free space on volume ")); - printf(" %s\n", _(" VPP = percent purgeable space on volume ")); - printf(" %s\n", _(" VKP = KB of purgeable space on volume ")); - printf(" %s\n", _(" VPNP = percent not yet purgeable space on volume ")); - printf(" %s\n", _(" VKNP = KB of not yet purgeable space on volume ")); - printf(" %s\n", _(" LRUM = LRU sitting time in minutes")); - printf(" %s\n", _(" LRUS = LRU sitting time in seconds")); - printf(" %s\n", _(" DSDB = check to see if DS Database is open")); - printf(" %s\n", _(" DSVER = NDS version")); - printf(" %s\n", _(" UPRB = used packet receive buffers")); - printf(" %s\n", _(" PUPRB = percent (of max) used packet receive buffers")); - printf(" %s\n", _(" SAPENTRIES = number of entries in the SAP table")); - printf(" %s\n", _(" SAPENTRIES = number of entries in the SAP table for SAP type ")); - printf(" %s\n", _(" TSYNC = timesync status")); - printf(" %s\n", _(" LOGINS = check to see if logins are enabled")); - printf(" %s\n", _(" CONNS = number of currently licensed connections")); - printf(" %s\n", _(" NRMH = NRM Summary Status")); - printf(" %s\n", _(" NRMP = Returns the current value for a NRM health item")); - printf(" %s\n", _(" NRMM = Returns the current memory stats from NRM")); - printf(" %s\n", _(" NRMS = Returns the current Swapfile stats from NRM")); - printf(" %s\n", _(" NSS1 = Statistics from _Admin:Manage_NSS\\GeneralStats.xml")); - printf(" %s\n", _(" NSS3 = Statistics from _Admin:Manage_NSS\\NameCache.xml")); - printf(" %s\n", _(" NSS4 = Statistics from _Admin:Manage_NSS\\FileStats.xml")); - printf(" %s\n", _(" NSS5 = Statistics from _Admin:Manage_NSS\\ObjectCache.xml")); - printf(" %s\n", _(" NSS6 = Statistics from _Admin:Manage_NSS\\Thread.xml")); - printf(" %s\n", _(" NSS7 = Statistics from _Admin:Manage_NSS\\AuthorizationCache.xml")); - printf(" %s\n", _(" NLM: = check if NLM is loaded and report version")); - printf(" %s\n", _(" (e.g. NLM:TSANDS.NLM)")); - printf("\n"); - 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", "-o, --osversion"); - printf(" %s\n", _("Include server version string in results")); - - printf(UT_CONN_TIMEOUT, DEFAULT_SOCKET_TIMEOUT); - - printf("\n"); - printf("%s\n", _("Notes:")); - printf(" %s\n", _("- This plugin requires that the MRTGEXT.NLM file from James Drews' MRTG")); - printf(" %s\n", _(" extension for NetWare be loaded on the Novell servers you wish to check.")); - printf(" %s\n", _(" (available from http://www.engr.wisc.edu/~drews/mrtg/)")); - printf(" %s\n", _("- Values for critical thresholds should be lower than warning thresholds")); - printf(" %s\n", _(" when the following variables are checked: VPF, VKF, LTCH, CBUFF, DCB, ")); - printf(" %s\n", _(" TCB, LRUS and LRUM.")); - - 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 c71a2e414ff3716325a6f4ce715e4a3037d52c0e Mon Sep 17 00:00:00 2001 From: Lorenz Kästle <12514511+RincewindsHat@users.noreply.github.com> Date: Wed, 12 Mar 2025 13:54:00 +0100 Subject: check_procs: clang-format --- plugins/check_procs.c | 843 +++++++++++++++++++++++++------------------------- 1 file changed, 422 insertions(+), 421 deletions(-) (limited to 'plugins') diff --git a/plugins/check_procs.c b/plugins/check_procs.c index 1d78ccee..69b424dc 100644 --- a/plugins/check_procs.c +++ b/plugins/check_procs.c @@ -1,41 +1,41 @@ /***************************************************************************** -* -* Monitoring check_procs plugin -* -* License: GPL -* Copyright (c) 2000-2024 Monitoring Plugins Development Team -* -* Description: -* -* This file contains the check_procs plugin -* -* Checks all processes and generates WARNING or CRITICAL states if the -* specified metric is outside the required threshold ranges. The metric -* defaults to number of processes. Search filters can be applied to limit -* the processes to check. -* -* The parent process, check_procs itself and any child process of -* check_procs (ps) are excluded from any checks to prevent false positives. -* -* -* 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_procs plugin + * + * License: GPL + * Copyright (c) 2000-2024 Monitoring Plugins Development Team + * + * Description: + * + * This file contains the check_procs plugin + * + * Checks all processes and generates WARNING or CRITICAL states if the + * specified metric is outside the required threshold ranges. The metric + * defaults to number of processes. Search filters can be applied to limit + * the processes to check. + * + * The parent process, check_procs itself and any child process of + * check_procs (ps) are excluded from any checks to prevent false positives. + * + * + * 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_procs"; -const char *program_name = "check_procs"; /* Required for coreutils libs */ +const char *program_name = "check_procs"; /* Required for coreutils libs */ const char *copyright = "2000-2024"; const char *email = "devel@monitoring-plugins.org"; @@ -48,35 +48,36 @@ const char *email = "devel@monitoring-plugins.org"; #include #ifdef HAVE_SYS_STAT_H -#include +# include #endif -static int process_arguments (int /*argc*/, char ** /*argv*/); -static int validate_arguments (void); -static int convert_to_seconds (char * /*etime*/); -static void print_help (void); -void print_usage (void); +static int process_arguments(int /*argc*/, char ** /*argv*/); +static int validate_arguments(void); +static int convert_to_seconds(char * /*etime*/); +static void print_help(void); +void print_usage(void); static char *warning_range = NULL; static char *critical_range = NULL; static thresholds *procs_thresholds = NULL; static int options = 0; /* bitmask of filter criteria to test against */ -#define ALL 1 -#define STAT 2 -#define PPID 4 -#define USER 8 -#define PROG 16 -#define ARGS 32 -#define VSZ 64 -#define RSS 128 -#define PCPU 256 -#define ELAPSED 512 -#define EREG_ARGS 1024 +#define ALL 1 +#define STAT 2 +#define PPID 4 +#define USER 8 +#define PROG 16 +#define ARGS 32 +#define VSZ 64 +#define RSS 128 +#define PCPU 256 +#define ELAPSED 512 +#define EREG_ARGS 1024 #define EXCLUDE_PROGS 2048 -#define KTHREAD_PARENT "kthreadd" /* the parent process of kernel threads: - ppid of procs are compared to pid of this proc*/ +#define KTHREAD_PARENT \ + "kthreadd" /* the parent process of kernel threads: \ + ppid of procs are compared to pid of this proc*/ /* Different metrics */ char *metric_name; @@ -109,8 +110,7 @@ static char tmp[MAX_INPUT_BUFFER]; static int kthread_filter = 0; static int usepid = 0; /* whether to test for pid or /proc/pid/exe */ -static int -stat_exe (const pid_t pid, struct stat *buf) { +static int stat_exe(const pid_t pid, struct stat *buf) { char *path; int ret; xasprintf(&path, "/proc/%d/exe", pid); @@ -119,10 +119,7 @@ stat_exe (const pid_t pid, struct stat *buf) { return ret; } - -int -main (int argc, char **argv) -{ +int main(int argc, char **argv) { char *input_buffer; char *input_line; char *procprog; @@ -141,16 +138,16 @@ main (int argc, char **argv) int procseconds = 0; float procpcpu = 0; char procstat[8]; - char procetime[MAX_INPUT_BUFFER] = { '\0' }; + char procetime[MAX_INPUT_BUFFER] = {'\0'}; char *procargs; const char *zombie = "Z"; int resultsum = 0; /* bitmask of the filter criteria met by a process */ - int found = 0; /* counter for number of lines returned in `ps` output */ - int procs = 0; /* counter for number of processes meeting filter criteria */ - int pos; /* number of spaces before 'args' in `ps` output */ - int cols; /* number of columns in ps output */ + int found = 0; /* counter for number of lines returned in `ps` output */ + int procs = 0; /* counter for number of processes meeting filter criteria */ + int pos; /* number of spaces before 'args' in `ps` output */ + int cols; /* number of columns in ps output */ int expected_cols = PS_COLS - 1; int warn = 0; /* number of processes in warn state */ int crit = 0; /* number of processes in crit state */ @@ -159,22 +156,23 @@ main (int argc, char **argv) int ret = 0; output chld_out, chld_err; - setlocale (LC_ALL, ""); - bindtextdomain (PACKAGE, LOCALEDIR); - textdomain (PACKAGE); + setlocale(LC_ALL, ""); + bindtextdomain(PACKAGE, LOCALEDIR); + textdomain(PACKAGE); setlocale(LC_NUMERIC, "POSIX"); - input_buffer = malloc (MAX_INPUT_BUFFER); - procprog = malloc (MAX_INPUT_BUFFER); + input_buffer = malloc(MAX_INPUT_BUFFER); + procprog = malloc(MAX_INPUT_BUFFER); - xasprintf (&metric_name, "PROCS"); + xasprintf(&metric_name, "PROCS"); metric = METRIC_PROCS; /* 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")); + } /* find ourself */ mypid = getpid(); @@ -189,44 +187,46 @@ main (int argc, char **argv) } /* Set signal handling and alarm timeout */ - if (signal (SIGALRM, timeout_alarm_handler) == SIG_ERR) { - die (STATE_UNKNOWN, _("Cannot catch SIGALRM")); + if (signal(SIGALRM, timeout_alarm_handler) == SIG_ERR) { + die(STATE_UNKNOWN, _("Cannot catch SIGALRM")); } - (void) alarm ((unsigned) timeout_interval); + (void)alarm((unsigned)timeout_interval); - if (verbose >= 2) - printf (_("CMD: %s\n"), PS_COMMAND); + if (verbose >= 2) { + printf(_("CMD: %s\n"), PS_COMMAND); + } if (input_filename == NULL) { - result = cmd_run( PS_COMMAND, &chld_out, &chld_err, 0); + result = cmd_run(PS_COMMAND, &chld_out, &chld_err, 0); if (chld_err.lines > 0) { - printf ("%s: %s", _("System call sent warnings to stderr"), chld_err.line[0]); + printf("%s: %s", _("System call sent warnings to stderr"), chld_err.line[0]); exit(STATE_WARNING); } } else { - result = cmd_file_read( input_filename, &chld_out, 0); + result = cmd_file_read(input_filename, &chld_out, 0); } /* flush first line: j starts at 1 */ for (size_t j = 1; j < chld_out.lines; j++) { input_line = chld_out.line[j]; - if (verbose >= 3) - printf ("%s", input_line); + if (verbose >= 3) { + printf("%s", input_line); + } - strcpy (procprog, ""); - xasprintf (&procargs, "%s", ""); + strcpy(procprog, ""); + xasprintf(&procargs, "%s", ""); - cols = sscanf (input_line, PS_FORMAT, PS_VARLIST); + cols = sscanf(input_line, PS_FORMAT, PS_VARLIST); /* Zombie processes do not give a procprog command */ - if ( cols < expected_cols && strstr(procstat, zombie) ) { + if (cols < expected_cols && strstr(procstat, zombie)) { cols = expected_cols; } - if ( cols >= expected_cols ) { + if (cols >= expected_cols) { resultsum = 0; - xasprintf (&procargs, "%s", input_line + pos); - strip (procargs); + xasprintf(&procargs, "%s", input_line + pos); + strip(procargs); /* Some ps return full pathname for command. This removes path */ strcpy(procprog, base_name(procprog)); @@ -234,52 +234,53 @@ main (int argc, char **argv) /* we need to convert the elapsed time to seconds */ procseconds = convert_to_seconds(procetime); - if (verbose >= 3) - printf ("proc#=%d uid=%d vsz=%d rss=%d pid=%d ppid=%d pcpu=%.2f stat=%s etime=%s prog=%s args=%s\n", - procs, procuid, procvsz, procrss, - procpid, procppid, procpcpu, procstat, - procetime, procprog, procargs); + if (verbose >= 3) { + printf("proc#=%d uid=%d vsz=%d rss=%d pid=%d ppid=%d pcpu=%.2f stat=%s etime=%s prog=%s args=%s\n", procs, procuid, procvsz, + procrss, procpid, procppid, procpcpu, procstat, procetime, procprog, procargs); + } /* Ignore self */ if ((usepid && mypid == procpid) || - ( ((!usepid) && ((ret = stat_exe(procpid, &statbuf) != -1) && statbuf.st_dev == mydev && statbuf.st_ino == myino)) || - (ret == -1 && errno == ENOENT)) - ) { - if (verbose >= 3) - printf("not considering - is myself or gone\n"); + (((!usepid) && ((ret = stat_exe(procpid, &statbuf) != -1) && statbuf.st_dev == mydev && statbuf.st_ino == myino)) || + (ret == -1 && errno == ENOENT))) { + if (verbose >= 3) { + printf("not considering - is myself or gone\n"); + } continue; } /* Ignore parent*/ else if (myppid == procpid) { - if (verbose >= 3) - printf("not considering - is parent\n"); + if (verbose >= 3) { + printf("not considering - is parent\n"); + } continue; } /* Ignore our own children */ if (procppid == mypid) { - if (verbose >= 3) - printf("not considering - is our child\n"); + if (verbose >= 3) { + printf("not considering - is our child\n"); + } continue; } /* Ignore excluded processes by name */ - if(options & EXCLUDE_PROGS) { - int found = 0; - int i = 0; - - for(i=0; i < (exclude_progs_counter); i++) { - if(!strcmp(procprog, exclude_progs_arr[i])) { - found = 1; - } - } - if(found == 0) { - resultsum |= EXCLUDE_PROGS; - } else - { - if(verbose >= 3) - printf("excluding - by ignorelist\n"); - } + if (options & EXCLUDE_PROGS) { + int found = 0; + int i = 0; + + for (i = 0; i < (exclude_progs_counter); i++) { + if (!strcmp(procprog, exclude_progs_arr[i])) { + found = 1; + } + } + if (found == 0) { + resultsum |= EXCLUDE_PROGS; + } else { + if (verbose >= 3) { + printf("excluding - by ignorelist\n"); + } + } } /* filter kernel threads (children of KTHREAD_PARENT)*/ @@ -287,69 +288,81 @@ main (int argc, char **argv) sorry for not doing that, but I've no other OSes to test :-( */ if (kthread_filter == 1) { /* get pid KTHREAD_PARENT */ - if (kthread_ppid == 0 && !strcmp(procprog, KTHREAD_PARENT) ) + if (kthread_ppid == 0 && !strcmp(procprog, KTHREAD_PARENT)) { kthread_ppid = procpid; + } if (kthread_ppid == procppid) { - if (verbose >= 2) - printf ("Ignore kernel thread: pid=%d ppid=%d prog=%s args=%s\n", procpid, procppid, procprog, procargs); + if (verbose >= 2) { + printf("Ignore kernel thread: pid=%d ppid=%d prog=%s args=%s\n", procpid, procppid, procprog, procargs); + } continue; } } - if ((options & STAT) && (strstr (procstat, statopts))) + if ((options & STAT) && (strstr(procstat, statopts))) { resultsum |= STAT; - if ((options & ARGS) && procargs && (strstr (procargs, args) != NULL)) + } + if ((options & ARGS) && procargs && (strstr(procargs, args) != NULL)) { resultsum |= ARGS; - if ((options & EREG_ARGS) && procargs && (regexec(&re_args, procargs, (size_t) 0, NULL, 0) == 0)) + } + if ((options & EREG_ARGS) && procargs && (regexec(&re_args, procargs, (size_t)0, NULL, 0) == 0)) { resultsum |= EREG_ARGS; - if ((options & PROG) && procprog && (strcmp (prog, procprog) == 0)) + } + if ((options & PROG) && procprog && (strcmp(prog, procprog) == 0)) { resultsum |= PROG; - if ((options & PPID) && (procppid == ppid)) + } + if ((options & PPID) && (procppid == ppid)) { resultsum |= PPID; - if ((options & USER) && (procuid == uid)) + } + if ((options & USER) && (procuid == uid)) { resultsum |= USER; - if ((options & VSZ) && (procvsz >= vsz)) + } + if ((options & VSZ) && (procvsz >= vsz)) { resultsum |= VSZ; - if ((options & RSS) && (procrss >= rss)) + } + if ((options & RSS) && (procrss >= rss)) { resultsum |= RSS; - if ((options & PCPU) && (procpcpu >= pcpu)) + } + if ((options & PCPU) && (procpcpu >= pcpu)) { resultsum |= PCPU; + } found++; /* Next line if filters not matched */ - if (!(options == resultsum || options == ALL)) + if (!(options == resultsum || options == ALL)) { continue; + } procs++; if (verbose >= 2) { - printf ("Matched: uid=%d vsz=%d rss=%d pid=%d ppid=%d pcpu=%.2f stat=%s etime=%s prog=%s args=%s\n", - procuid, procvsz, procrss, - procpid, procppid, procpcpu, procstat, - procetime, procprog, procargs); + printf("Matched: uid=%d vsz=%d rss=%d pid=%d ppid=%d pcpu=%.2f stat=%s etime=%s prog=%s args=%s\n", procuid, procvsz, + procrss, procpid, procppid, procpcpu, procstat, procetime, procprog, procargs); } - if (metric == METRIC_VSZ) - i = get_status ((double)procvsz, procs_thresholds); - else if (metric == METRIC_RSS) - i = get_status ((double)procrss, procs_thresholds); + if (metric == METRIC_VSZ) { + i = get_status((double)procvsz, procs_thresholds); + } else if (metric == METRIC_RSS) { + i = get_status((double)procrss, procs_thresholds); + } /* TODO? float thresholds for --metric=CPU */ - else if (metric == METRIC_CPU) - i = get_status (procpcpu, procs_thresholds); - else if (metric == METRIC_ELAPSED) - i = get_status ((double)procseconds, procs_thresholds); + else if (metric == METRIC_CPU) { + i = get_status(procpcpu, procs_thresholds); + } else if (metric == METRIC_ELAPSED) { + i = get_status((double)procseconds, procs_thresholds); + } if (metric != METRIC_PROCS) { if (i == STATE_WARNING) { warn++; - xasprintf (&fails, "%s%s%s", fails, (strcmp(fails,"") ? ", " : ""), procprog); - result = max_state (result, i); + xasprintf(&fails, "%s%s%s", fails, (strcmp(fails, "") ? ", " : ""), procprog); + result = max_state(result, i); } if (i == STATE_CRITICAL) { crit++; - xasprintf (&fails, "%s%s%s", fails, (strcmp(fails,"") ? ", " : ""), procprog); - result = max_state (result, i); + xasprintf(&fails, "%s%s%s", fails, (strcmp(fails, "") ? ", " : ""), procprog); + result = max_state(result, i); } } } @@ -359,58 +372,55 @@ main (int argc, char **argv) } } - if (found == 0) { /* no process lines parsed so return STATE_UNKNOWN */ - printf (_("Unable to read output\n")); + if (found == 0) { /* no process lines parsed so return STATE_UNKNOWN */ + printf(_("Unable to read output\n")); return STATE_UNKNOWN; } - if ( result == STATE_UNKNOWN ) + if (result == STATE_UNKNOWN) { result = STATE_OK; + } /* Needed if procs found, but none match filter */ - if ( metric == METRIC_PROCS ) { - result = max_state (result, get_status ((double)procs, procs_thresholds) ); + if (metric == METRIC_PROCS) { + result = max_state(result, get_status((double)procs, procs_thresholds)); } - if ( result == STATE_OK ) { - printf ("%s %s: ", metric_name, _("OK")); + if (result == STATE_OK) { + printf("%s %s: ", metric_name, _("OK")); } else if (result == STATE_WARNING) { - printf ("%s %s: ", metric_name, _("WARNING")); - if ( metric != METRIC_PROCS ) { - printf (_("%d warn out of "), warn); + printf("%s %s: ", metric_name, _("WARNING")); + if (metric != METRIC_PROCS) { + printf(_("%d warn out of "), warn); } } else if (result == STATE_CRITICAL) { - printf ("%s %s: ", metric_name, _("CRITICAL")); + printf("%s %s: ", metric_name, _("CRITICAL")); if (metric != METRIC_PROCS) { - printf (_("%d crit, %d warn out of "), crit, warn); + printf(_("%d crit, %d warn out of "), crit, warn); } } - printf (ngettext ("%d process", "%d processes", (unsigned long) procs), procs); + printf(ngettext("%d process", "%d processes", (unsigned long)procs), procs); - if (strcmp(fmt,"") != 0) { - printf (_(" with %s"), fmt); + if (strcmp(fmt, "") != 0) { + printf(_(" with %s"), fmt); } - if ( verbose >= 1 && strcmp(fails,"") ) - printf (" [%s]", fails); + if (verbose >= 1 && strcmp(fails, "")) { + printf(" [%s]", fails); + } - if (metric == METRIC_PROCS) - printf (" | procs=%d;%s;%s;0;", procs, - warning_range ? warning_range : "", - critical_range ? critical_range : ""); - else - printf (" | procs=%d;;;0; procs_warn=%d;;;0; procs_crit=%d;;;0;", procs, warn, crit); + if (metric == METRIC_PROCS) { + printf(" | procs=%d;%s;%s;0;", procs, warning_range ? warning_range : "", critical_range ? critical_range : ""); + } else { + printf(" | procs=%d;;;0; procs_warn=%d;;;0; procs_crit=%d;;;0;", procs, warn, crit); + } - printf ("\n"); + printf("\n"); return result; } - - /* process command-line arguments */ -int -process_arguments (int argc, char **argv) -{ +int process_arguments(int argc, char **argv) { int c = 1; char *user; struct passwd *pw; @@ -419,260 +429,262 @@ process_arguments (int argc, char **argv) int cflags = REG_NOSUB | REG_EXTENDED; char errbuf[MAX_INPUT_BUFFER]; char *temp_string; - int i=0; - static struct option longopts[] = { - {"warning", required_argument, 0, 'w'}, - {"critical", required_argument, 0, 'c'}, - {"metric", required_argument, 0, 'm'}, - {"timeout", required_argument, 0, 't'}, - {"status", required_argument, 0, 's'}, - {"ppid", required_argument, 0, 'p'}, - {"user", required_argument, 0, 'u'}, - {"command", required_argument, 0, 'C'}, - {"vsz", required_argument, 0, 'z'}, - {"rss", required_argument, 0, 'r'}, - {"pcpu", required_argument, 0, 'P'}, - {"elapsed", required_argument, 0, 'e'}, - {"argument-array", required_argument, 0, 'a'}, - {"help", no_argument, 0, 'h'}, - {"version", no_argument, 0, 'V'}, - {"verbose", no_argument, 0, 'v'}, - {"ereg-argument-array", required_argument, 0, CHAR_MAX+1}, - {"input-file", required_argument, 0, CHAR_MAX+2}, - {"no-kthreads", required_argument, 0, 'k'}, - {"traditional-filter", no_argument, 0, 'T'}, - {"exclude-process", required_argument, 0, 'X'}, - {0, 0, 0, 0} - }; - - for (c = 1; c < argc; c++) - if (strcmp ("-to", argv[c]) == 0) - strcpy (argv[c], "-t"); + int i = 0; + static struct option longopts[] = {{"warning", required_argument, 0, 'w'}, + {"critical", required_argument, 0, 'c'}, + {"metric", required_argument, 0, 'm'}, + {"timeout", required_argument, 0, 't'}, + {"status", required_argument, 0, 's'}, + {"ppid", required_argument, 0, 'p'}, + {"user", required_argument, 0, 'u'}, + {"command", required_argument, 0, 'C'}, + {"vsz", required_argument, 0, 'z'}, + {"rss", required_argument, 0, 'r'}, + {"pcpu", required_argument, 0, 'P'}, + {"elapsed", required_argument, 0, 'e'}, + {"argument-array", required_argument, 0, 'a'}, + {"help", no_argument, 0, 'h'}, + {"version", no_argument, 0, 'V'}, + {"verbose", no_argument, 0, 'v'}, + {"ereg-argument-array", required_argument, 0, CHAR_MAX + 1}, + {"input-file", required_argument, 0, CHAR_MAX + 2}, + {"no-kthreads", required_argument, 0, 'k'}, + {"traditional-filter", no_argument, 0, 'T'}, + {"exclude-process", required_argument, 0, 'X'}, + {0, 0, 0, 0}}; + + for (c = 1; c < argc; c++) { + if (strcmp("-to", argv[c]) == 0) { + strcpy(argv[c], "-t"); + } + } while (1) { - c = getopt_long (argc, argv, "Vvhkt:c:w:p:s:u:C:a:z:r:m:P:T:X:", - longopts, &option); + c = getopt_long(argc, argv, "Vvhkt:c:w:p:s:u:C:a:z:r:m:P:T:X:", longopts, &option); - if (c == -1 || c == EOF) + if (c == -1 || c == EOF) { break; + } switch (c) { - case '?': /* help */ - usage5 (); - 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_integer (optarg)) - usage2 (_("Timeout interval must be a positive integer"), optarg); - else - timeout_interval = atoi (optarg); + case '?': /* help */ + usage5(); + 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_integer(optarg)) { + usage2(_("Timeout interval must be a positive integer"), optarg); + } else { + timeout_interval = atoi(optarg); + } break; - case 'c': /* critical threshold */ + case 'c': /* critical threshold */ critical_range = optarg; break; - case 'w': /* warning threshold */ + case 'w': /* warning threshold */ warning_range = optarg; break; - case 'p': /* process id */ - if (sscanf (optarg, "%d%[^0-9]", &ppid, tmp) == 1) { - xasprintf (&fmt, "%s%sPPID = %d", (fmt ? fmt : "") , (options ? ", " : ""), ppid); + case 'p': /* process id */ + if (sscanf(optarg, "%d%[^0-9]", &ppid, tmp) == 1) { + xasprintf(&fmt, "%s%sPPID = %d", (fmt ? fmt : ""), (options ? ", " : ""), ppid); options |= PPID; break; } - usage4 (_("Parent Process ID must be an integer!")); - case 's': /* status */ - if (statopts) + usage4(_("Parent Process ID must be an integer!")); + case 's': /* status */ + if (statopts) { break; - else + } else { statopts = optarg; - xasprintf (&fmt, _("%s%sSTATE = %s"), (fmt ? fmt : ""), (options ? ", " : ""), statopts); + } + xasprintf(&fmt, _("%s%sSTATE = %s"), (fmt ? fmt : ""), (options ? ", " : ""), statopts); options |= STAT; break; - case 'u': /* user or user id */ - if (is_integer (optarg)) { - uid = atoi (optarg); - pw = getpwuid ((uid_t) uid); + case 'u': /* user or user id */ + if (is_integer(optarg)) { + uid = atoi(optarg); + pw = getpwuid((uid_t)uid); /* check to be sure user exists */ - if (pw == NULL) - usage2 (_("UID was not found"), optarg); - } - else { - pw = getpwnam (optarg); + if (pw == NULL) { + usage2(_("UID was not found"), optarg); + } + } else { + pw = getpwnam(optarg); /* check to be sure user exists */ - if (pw == NULL) - usage2 (_("User name was not found"), optarg); + if (pw == NULL) { + usage2(_("User name was not found"), optarg); + } /* then get uid */ uid = pw->pw_uid; } user = pw->pw_name; - xasprintf (&fmt, "%s%sUID = %d (%s)", (fmt ? fmt : ""), (options ? ", " : ""), - uid, user); + xasprintf(&fmt, "%s%sUID = %d (%s)", (fmt ? fmt : ""), (options ? ", " : ""), uid, user); options |= USER; break; - case 'C': /* command */ + case 'C': /* command */ /* TODO: allow this to be passed in with --metric */ - if (prog) + if (prog) { break; - else + } else { prog = optarg; - xasprintf (&fmt, _("%s%scommand name '%s'"), (fmt ? fmt : ""), (options ? ", " : ""), - prog); + } + xasprintf(&fmt, _("%s%scommand name '%s'"), (fmt ? fmt : ""), (options ? ", " : ""), prog); options |= PROG; break; case 'X': - if(exclude_progs) - break; - else - exclude_progs = optarg; - xasprintf (&fmt, _("%s%sexclude progs '%s'"), (fmt ? fmt : ""), (options ? ", " : ""), - exclude_progs); + if (exclude_progs) { + break; + } else { + exclude_progs = optarg; + } + xasprintf(&fmt, _("%s%sexclude progs '%s'"), (fmt ? fmt : ""), (options ? ", " : ""), exclude_progs); char *p = strtok(exclude_progs, ","); - while(p){ - exclude_progs_arr = realloc(exclude_progs_arr, sizeof(char*) * ++exclude_progs_counter); - exclude_progs_arr[exclude_progs_counter-1] = p; - p = strtok(NULL, ","); + while (p) { + exclude_progs_arr = realloc(exclude_progs_arr, sizeof(char *) * ++exclude_progs_counter); + exclude_progs_arr[exclude_progs_counter - 1] = p; + p = strtok(NULL, ","); } options |= EXCLUDE_PROGS; break; - case 'a': /* args (full path name with args) */ + case 'a': /* args (full path name with args) */ /* TODO: allow this to be passed in with --metric */ - if (args) + if (args) { break; - else + } else { args = optarg; - xasprintf (&fmt, "%s%sargs '%s'", (fmt ? fmt : ""), (options ? ", " : ""), args); + } + xasprintf(&fmt, "%s%sargs '%s'", (fmt ? fmt : ""), (options ? ", " : ""), args); options |= ARGS; break; - case CHAR_MAX+1: + case CHAR_MAX + 1: err = regcomp(&re_args, optarg, cflags); if (err != 0) { - regerror (err, &re_args, errbuf, MAX_INPUT_BUFFER); - die (STATE_UNKNOWN, "PROCS %s: %s - %s\n", _("UNKNOWN"), _("Could not compile regular expression"), errbuf); + regerror(err, &re_args, errbuf, MAX_INPUT_BUFFER); + die(STATE_UNKNOWN, "PROCS %s: %s - %s\n", _("UNKNOWN"), _("Could not compile regular expression"), errbuf); } /* Strip off any | within the regex optarg */ temp_string = strdup(optarg); - while(temp_string[i]!='\0'){ - if(temp_string[i]=='|') - temp_string[i]=','; + while (temp_string[i] != '\0') { + if (temp_string[i] == '|') { + temp_string[i] = ','; + } i++; } - xasprintf (&fmt, "%s%sregex args '%s'", (fmt ? fmt : ""), (options ? ", " : ""), temp_string); + xasprintf(&fmt, "%s%sregex args '%s'", (fmt ? fmt : ""), (options ? ", " : ""), temp_string); options |= EREG_ARGS; break; - case 'r': /* RSS */ - if (sscanf (optarg, "%d%[^0-9]", &rss, tmp) == 1) { - xasprintf (&fmt, "%s%sRSS >= %d", (fmt ? fmt : ""), (options ? ", " : ""), rss); + case 'r': /* RSS */ + if (sscanf(optarg, "%d%[^0-9]", &rss, tmp) == 1) { + xasprintf(&fmt, "%s%sRSS >= %d", (fmt ? fmt : ""), (options ? ", " : ""), rss); options |= RSS; break; } - usage4 (_("RSS must be an integer!")); - case 'z': /* VSZ */ - if (sscanf (optarg, "%d%[^0-9]", &vsz, tmp) == 1) { - xasprintf (&fmt, "%s%sVSZ >= %d", (fmt ? fmt : ""), (options ? ", " : ""), vsz); + usage4(_("RSS must be an integer!")); + case 'z': /* VSZ */ + if (sscanf(optarg, "%d%[^0-9]", &vsz, tmp) == 1) { + xasprintf(&fmt, "%s%sVSZ >= %d", (fmt ? fmt : ""), (options ? ", " : ""), vsz); options |= VSZ; break; } - usage4 (_("VSZ must be an integer!")); - case 'P': /* PCPU */ + usage4(_("VSZ must be an integer!")); + case 'P': /* PCPU */ /* TODO: -P 1.5.5 is accepted */ - if (sscanf (optarg, "%f%[^0-9.]", &pcpu, tmp) == 1) { - xasprintf (&fmt, "%s%sPCPU >= %.2f", (fmt ? fmt : ""), (options ? ", " : ""), pcpu); + if (sscanf(optarg, "%f%[^0-9.]", &pcpu, tmp) == 1) { + xasprintf(&fmt, "%s%sPCPU >= %.2f", (fmt ? fmt : ""), (options ? ", " : ""), pcpu); options |= PCPU; break; } - usage4 (_("PCPU must be a float!")); + usage4(_("PCPU must be a float!")); case 'm': - xasprintf (&metric_name, "%s", optarg); - if ( strcmp(optarg, "PROCS") == 0) { + xasprintf(&metric_name, "%s", optarg); + if (strcmp(optarg, "PROCS") == 0) { metric = METRIC_PROCS; break; - } - else if ( strcmp(optarg, "VSZ") == 0) { + } else if (strcmp(optarg, "VSZ") == 0) { metric = METRIC_VSZ; break; - } - else if ( strcmp(optarg, "RSS") == 0 ) { + } else if (strcmp(optarg, "RSS") == 0) { metric = METRIC_RSS; break; - } - else if ( strcmp(optarg, "CPU") == 0 ) { + } else if (strcmp(optarg, "CPU") == 0) { metric = METRIC_CPU; break; - } - else if ( strcmp(optarg, "ELAPSED") == 0) { + } else if (strcmp(optarg, "ELAPSED") == 0) { metric = METRIC_ELAPSED; break; } - usage4 (_("Metric must be one of PROCS, VSZ, RSS, CPU, ELAPSED!")); - case 'k': /* linux kernel thread filter */ + usage4(_("Metric must be one of PROCS, VSZ, RSS, CPU, ELAPSED!")); + case 'k': /* linux kernel thread filter */ kthread_filter = 1; break; - case 'v': /* command */ + case 'v': /* command */ verbose++; break; case 'T': usepid = 1; break; - case CHAR_MAX+2: + case CHAR_MAX + 2: input_filename = optarg; break; } } c = optind; - if ((! warning_range) && argv[c]) + if ((!warning_range) && argv[c]) { warning_range = argv[c++]; - if ((! critical_range) && argv[c]) + } + if ((!critical_range) && argv[c]) { critical_range = argv[c++]; + } if (statopts == NULL && argv[c]) { - xasprintf (&statopts, "%s", argv[c++]); - xasprintf (&fmt, _("%s%sSTATE = %s"), (fmt ? fmt : ""), (options ? ", " : ""), statopts); + xasprintf(&statopts, "%s", argv[c++]); + xasprintf(&fmt, _("%s%sSTATE = %s"), (fmt ? fmt : ""), (options ? ", " : ""), statopts); options |= STAT; } /* this will abort in case of invalid ranges */ - set_thresholds (&procs_thresholds, warning_range, critical_range); + set_thresholds(&procs_thresholds, warning_range, critical_range); - return validate_arguments (); + return validate_arguments(); } - - -int -validate_arguments () -{ - if (options == 0) +int validate_arguments() { + if (options == 0) { options = ALL; + } - if (statopts==NULL) + if (statopts == NULL) { statopts = strdup(""); + } - if (prog==NULL) + if (prog == NULL) { prog = strdup(""); + } - if (args==NULL) + if (args == NULL) { args = strdup(""); + } - if (fmt==NULL) + if (fmt == NULL) { fmt = strdup(""); + } - if (fails==NULL) + if (fails == NULL) { fails = strdup(""); + } return options; } - /* convert the elapsed time to seconds */ -int -convert_to_seconds(char *etime) { +int convert_to_seconds(char *etime) { char *ptr; int total; @@ -704,8 +716,7 @@ convert_to_seconds(char *etime) { } if (hyphcnt > 0) { - sscanf(etime, "%d-%d:%d:%d", - &days, &hours, &minutes, &seconds); + sscanf(etime, "%d-%d:%d:%d", &days, &hours, &minutes, &seconds); /* linux 2.6.5/2.6.6 reporting some processes with infinite * elapsed times for some reason */ if (days == 49710) { @@ -713,135 +724,125 @@ convert_to_seconds(char *etime) { } } else { if (coloncnt == 2) { - sscanf(etime, "%d:%d:%d", - &hours, &minutes, &seconds); + sscanf(etime, "%d:%d:%d", &hours, &minutes, &seconds); } else if (coloncnt == 1) { - sscanf(etime, "%d:%d", - &minutes, &seconds); + sscanf(etime, "%d:%d", &minutes, &seconds); } } - total = (days * 86400) + - (hours * 3600) + - (minutes * 60) + - seconds; + total = (days * 86400) + (hours * 3600) + (minutes * 60) + seconds; if (verbose >= 3 && metric == METRIC_ELAPSED) { - printf("seconds: %d\n", total); + printf("seconds: %d\n", total); } return total; } +void print_help(void) { + print_revision(progname, NP_VERSION); -void -print_help (void) -{ - print_revision (progname, NP_VERSION); - - printf ("Copyright (c) 1999 Ethan Galstad \n"); - printf (COPYRIGHT, copyright, email); + printf("Copyright (c) 1999 Ethan Galstad \n"); + printf(COPYRIGHT, copyright, email); - printf ("%s\n", _("Checks all processes and generates WARNING or CRITICAL states if the specified")); - printf ("%s\n", _("metric is outside the required threshold ranges. The metric defaults to number")); - printf ("%s\n", _("of processes. Search filters can be applied to limit the processes to check.")); + printf("%s\n", _("Checks all processes and generates WARNING or CRITICAL states if the specified")); + printf("%s\n", _("metric is outside the required threshold ranges. The metric defaults to number")); + printf("%s\n", _("of processes. Search filters can be applied to limit the processes to check.")); - printf ("\n\n"); + printf("\n\n"); - printf ("%s\n", _("The parent process, check_procs itself and any child process of check_procs (ps)")); - printf ("%s\n", _("are excluded from any checks to prevent false positives.")); + printf("%s\n", _("The parent process, check_procs itself and any child process of check_procs (ps)")); + printf("%s\n", _("are excluded from any checks to prevent false positives.")); - printf ("\n\n"); + printf("\n\n"); - print_usage (); + print_usage(); - printf (UT_HELP_VRSN); - printf (UT_EXTRA_OPTS); - printf (" %s\n", "-w, --warning=RANGE"); - printf (" %s\n", _("Generate warning state if metric is outside this range")); - printf (" %s\n", "-c, --critical=RANGE"); - printf (" %s\n", _("Generate critical state if metric is outside this range")); - printf (" %s\n", "-m, --metric=TYPE"); - printf (" %s\n", _("Check thresholds against metric. Valid types:")); - printf (" %s\n", _("PROCS - number of processes (default)")); - printf (" %s\n", _("VSZ - virtual memory size")); - printf (" %s\n", _("RSS - resident set memory size")); - printf (" %s\n", _("CPU - percentage CPU")); + printf(UT_HELP_VRSN); + printf(UT_EXTRA_OPTS); + printf(" %s\n", "-w, --warning=RANGE"); + printf(" %s\n", _("Generate warning state if metric is outside this range")); + printf(" %s\n", "-c, --critical=RANGE"); + printf(" %s\n", _("Generate critical state if metric is outside this range")); + printf(" %s\n", "-m, --metric=TYPE"); + printf(" %s\n", _("Check thresholds against metric. Valid types:")); + printf(" %s\n", _("PROCS - number of processes (default)")); + printf(" %s\n", _("VSZ - virtual memory size")); + printf(" %s\n", _("RSS - resident set memory size")); + printf(" %s\n", _("CPU - percentage CPU")); /* only linux etime is support currently */ -#if defined( __linux__ ) - printf (" %s\n", _("ELAPSED - time elapsed in seconds")); +#if defined(__linux__) + printf(" %s\n", _("ELAPSED - time elapsed in seconds")); #endif /* defined(__linux__) */ - printf (UT_PLUG_TIMEOUT, DEFAULT_SOCKET_TIMEOUT); - - printf (" %s\n", "-v, --verbose"); - printf (" %s\n", _("Extra information. Up to 3 verbosity levels")); - - printf (" %s\n", "-T, --traditional"); - printf (" %s\n", _("Filter own process the traditional way by PID instead of /proc/pid/exe")); - - printf ("\n"); - printf ("%s\n", "Filters:"); - printf (" %s\n", "-s, --state=STATUSFLAGS"); - printf (" %s\n", _("Only scan for processes that have, in the output of `ps`, one or")); - printf (" %s\n", _("more of the status flags you specify (for example R, Z, S, RS,")); - printf (" %s\n", _("RSZDT, plus others based on the output of your 'ps' command).")); - printf (" %s\n", "-p, --ppid=PPID"); - printf (" %s\n", _("Only scan for children of the parent process ID indicated.")); - printf (" %s\n", "-z, --vsz=VSZ"); - printf (" %s\n", _("Only scan for processes with VSZ higher than indicated.")); - printf (" %s\n", "-r, --rss=RSS"); - printf (" %s\n", _("Only scan for processes with RSS higher than indicated.")); - printf (" %s\n", "-P, --pcpu=PCPU"); - printf (" %s\n", _("Only scan for processes with PCPU higher than indicated.")); - printf (" %s\n", "-u, --user=USER"); - printf (" %s\n", _("Only scan for processes with user name or ID indicated.")); - printf (" %s\n", "-a, --argument-array=STRING"); - printf (" %s\n", _("Only scan for processes with args that contain STRING.")); - printf (" %s\n", "--ereg-argument-array=STRING"); - printf (" %s\n", _("Only scan for processes with args that contain the regex STRING.")); - printf (" %s\n", "-C, --command=COMMAND"); - printf (" %s\n", _("Only scan for exact matches of COMMAND (without path).")); - printf (" %s\n", "-X, --exclude-process"); - printf (" %s\n", _("Exclude processes which match this comma separated list")); - printf (" %s\n", "-k, --no-kthreads"); - printf (" %s\n", _("Only scan for non kernel threads (works on Linux only).")); - - printf(_("\n\ + printf(UT_PLUG_TIMEOUT, DEFAULT_SOCKET_TIMEOUT); + + printf(" %s\n", "-v, --verbose"); + printf(" %s\n", _("Extra information. Up to 3 verbosity levels")); + + printf(" %s\n", "-T, --traditional"); + printf(" %s\n", _("Filter own process the traditional way by PID instead of /proc/pid/exe")); + + printf("\n"); + printf("%s\n", "Filters:"); + printf(" %s\n", "-s, --state=STATUSFLAGS"); + printf(" %s\n", _("Only scan for processes that have, in the output of `ps`, one or")); + printf(" %s\n", _("more of the status flags you specify (for example R, Z, S, RS,")); + printf(" %s\n", _("RSZDT, plus others based on the output of your 'ps' command).")); + printf(" %s\n", "-p, --ppid=PPID"); + printf(" %s\n", _("Only scan for children of the parent process ID indicated.")); + printf(" %s\n", "-z, --vsz=VSZ"); + printf(" %s\n", _("Only scan for processes with VSZ higher than indicated.")); + printf(" %s\n", "-r, --rss=RSS"); + printf(" %s\n", _("Only scan for processes with RSS higher than indicated.")); + printf(" %s\n", "-P, --pcpu=PCPU"); + printf(" %s\n", _("Only scan for processes with PCPU higher than indicated.")); + printf(" %s\n", "-u, --user=USER"); + printf(" %s\n", _("Only scan for processes with user name or ID indicated.")); + printf(" %s\n", "-a, --argument-array=STRING"); + printf(" %s\n", _("Only scan for processes with args that contain STRING.")); + printf(" %s\n", "--ereg-argument-array=STRING"); + printf(" %s\n", _("Only scan for processes with args that contain the regex STRING.")); + printf(" %s\n", "-C, --command=COMMAND"); + printf(" %s\n", _("Only scan for exact matches of COMMAND (without path).")); + printf(" %s\n", "-X, --exclude-process"); + printf(" %s\n", _("Exclude processes which match this comma separated list")); + printf(" %s\n", "-k, --no-kthreads"); + printf(" %s\n", _("Only scan for non kernel threads (works on Linux only).")); + + printf(_("\n\ RANGEs are specified 'min:max' or 'min:' or ':max' (or 'max'). If\n\ specified 'max:min', a warning status will be generated if the\n\ count is inside the specified range\n\n")); - printf(_("\ + printf(_("\ This plugin checks the number of currently running processes and\n\ generates WARNING or CRITICAL states if the process count is outside\n\ the specified threshold ranges. The process count can be filtered by\n\ process owner, parent process PID, current state (e.g., 'Z'), or may\n\ be the total number of running processes\n\n")); - printf ("%s\n", _("Examples:")); - printf (" %s\n", "check_procs -w 2:2 -c 2:1024 -C portsentry"); - printf (" %s\n", _("Warning if not two processes with command name portsentry.")); - printf (" %s\n\n", _("Critical if < 2 or > 1024 processes")); - printf (" %s\n", "check_procs -c 1: -C sshd"); - printf (" %s\n", _("Critical if not at least 1 process with command sshd")); - printf (" %s\n", "check_procs -w 1024 -c 1: -C sshd"); - printf (" %s\n", _("Warning if > 1024 processes with command name sshd.")); - printf (" %s\n\n", _("Critical if < 1 processes with command name sshd.")); - printf (" %s\n", "check_procs -w 10 -a '/usr/local/bin/perl' -u root"); - printf (" %s\n", _("Warning alert if > 10 processes with command arguments containing")); - printf (" %s\n\n", _("'/usr/local/bin/perl' and owned by root")); - printf (" %s\n", "check_procs -w 50000 -c 100000 --metric=VSZ"); - printf (" %s\n\n", _("Alert if VSZ of any processes over 50K or 100K")); - printf (" %s\n", "check_procs -w 10 -c 20 --metric=CPU"); - printf (" %s\n", _("Alert if CPU of any processes over 10%% or 20%%")); - - printf (UT_SUPPORT); + printf("%s\n", _("Examples:")); + printf(" %s\n", "check_procs -w 2:2 -c 2:1024 -C portsentry"); + printf(" %s\n", _("Warning if not two processes with command name portsentry.")); + printf(" %s\n\n", _("Critical if < 2 or > 1024 processes")); + printf(" %s\n", "check_procs -c 1: -C sshd"); + printf(" %s\n", _("Critical if not at least 1 process with command sshd")); + printf(" %s\n", "check_procs -w 1024 -c 1: -C sshd"); + printf(" %s\n", _("Warning if > 1024 processes with command name sshd.")); + printf(" %s\n\n", _("Critical if < 1 processes with command name sshd.")); + printf(" %s\n", "check_procs -w 10 -a '/usr/local/bin/perl' -u root"); + printf(" %s\n", _("Warning alert if > 10 processes with command arguments containing")); + printf(" %s\n\n", _("'/usr/local/bin/perl' and owned by root")); + printf(" %s\n", "check_procs -w 50000 -c 100000 --metric=VSZ"); + printf(" %s\n\n", _("Alert if VSZ of any processes over 50K or 100K")); + printf(" %s\n", "check_procs -w 10 -c 20 --metric=CPU"); + printf(" %s\n", _("Alert if CPU of any processes over 10%% or 20%%")); + + printf(UT_SUPPORT); } -void -print_usage (void) -{ - printf ("%s\n", _("Usage:")); - printf ("%s -w -c [-m metric] [-s state] [-p ppid]\n", progname); - printf (" [-u user] [-r rss] [-z vsz] [-P %%cpu] [-a argument-array]\n"); - printf (" [-C command] [-X process_to_exclude] [-k] [-t timeout] [-v]\n"); +void print_usage(void) { + printf("%s\n", _("Usage:")); + printf("%s -w -c [-m metric] [-s state] [-p ppid]\n", progname); + printf(" [-u user] [-r rss] [-z vsz] [-P %%cpu] [-a argument-array]\n"); + printf(" [-C command] [-X process_to_exclude] [-k] [-t timeout] [-v]\n"); } -- cgit v1.2.3-74-g34f1 From 16c3e2499309af654bcf92a4cc516521122e8d66 Mon Sep 17 00:00:00 2001 From: Lorenz Kästle <12514511+RincewindsHat@users.noreply.github.com> Date: Wed, 12 Mar 2025 14:53:54 +0100 Subject: check_procs: general refactoring --- configure.ac | 2 +- plugins/check_procs.c | 247 +++++++++++++++++++++++--------------------------- 2 files changed, 114 insertions(+), 135 deletions(-) (limited to 'plugins') diff --git a/configure.ac b/configure.ac index 204fc6e3..c66f9b2f 100644 --- a/configure.ac +++ b/configure.ac @@ -796,7 +796,7 @@ elif ps axwo 'stat comm vsz rss user uid pid ppid etime args' 2>/dev/null | \ then ac_cv_ps_varlist="[procstat,&procuid,&procpid,&procppid,&procvsz,&procrss,&procpcpu,procetime,procprog,&pos]" ac_cv_ps_command="$PATH_TO_PS axwo 'stat uid pid ppid vsz rss pcpu etime comm args'" - ac_cv_ps_format="%s %d %d %d %d %d %f %s %s %n" + ac_cv_ps_format="%s %u %d %d %d %d %f %s %s %n" ac_cv_ps_cols=10 AC_MSG_RESULT([$ac_cv_ps_command]) diff --git a/plugins/check_procs.c b/plugins/check_procs.c index 69b424dc..da2198a7 100644 --- a/plugins/check_procs.c +++ b/plugins/check_procs.c @@ -43,6 +43,7 @@ const char *email = "devel@monitoring-plugins.org"; #include "utils.h" #include "utils_cmd.h" #include "regex.h" +#include "states.h" #include #include @@ -91,7 +92,7 @@ enum metric { enum metric metric = METRIC_PROCS; static int verbose = 0; -static int uid; +static uid_t uid; static pid_t ppid; static int vsz; static int rss; @@ -107,62 +108,22 @@ static regex_t re_args; static char *fmt; static char *fails; static char tmp[MAX_INPUT_BUFFER]; -static int kthread_filter = 0; -static int usepid = 0; /* whether to test for pid or /proc/pid/exe */ +static bool kthread_filter = false; +static bool usepid = false; /* whether to test for pid or /proc/pid/exe */ static int stat_exe(const pid_t pid, struct stat *buf) { char *path; - int ret; xasprintf(&path, "/proc/%d/exe", pid); - ret = stat(path, buf); + int ret = stat(path, buf); free(path); return ret; } int main(int argc, char **argv) { - char *input_buffer; - char *input_line; - char *procprog; - - pid_t mypid = 0; - pid_t myppid = 0; - struct stat statbuf; - dev_t mydev = 0; - ino_t myino = 0; - int procuid = 0; - pid_t procpid = 0; - pid_t procppid = 0; - pid_t kthread_ppid = 0; - int procvsz = 0; - int procrss = 0; - int procseconds = 0; - float procpcpu = 0; - char procstat[8]; - char procetime[MAX_INPUT_BUFFER] = {'\0'}; - char *procargs; - - const char *zombie = "Z"; - - int resultsum = 0; /* bitmask of the filter criteria met by a process */ - int found = 0; /* counter for number of lines returned in `ps` output */ - int procs = 0; /* counter for number of processes meeting filter criteria */ - int pos; /* number of spaces before 'args' in `ps` output */ - int cols; /* number of columns in ps output */ - int expected_cols = PS_COLS - 1; - int warn = 0; /* number of processes in warn state */ - int crit = 0; /* number of processes in crit state */ - int i = 0; - int result = STATE_UNKNOWN; - int ret = 0; - output chld_out, chld_err; - setlocale(LC_ALL, ""); + setlocale(LC_NUMERIC, "POSIX"); bindtextdomain(PACKAGE, LOCALEDIR); textdomain(PACKAGE); - setlocale(LC_NUMERIC, "POSIX"); - - input_buffer = malloc(MAX_INPUT_BUFFER); - procprog = malloc(MAX_INPUT_BUFFER); xasprintf(&metric_name, "PROCS"); metric = METRIC_PROCS; @@ -175,13 +136,16 @@ int main(int argc, char **argv) { } /* find ourself */ - mypid = getpid(); - myppid = getppid(); + pid_t mypid = getpid(); + pid_t myppid = getppid(); + dev_t mydev = 0; + ino_t myino = 0; + struct stat statbuf; if (usepid || stat_exe(mypid, &statbuf) == -1) { /* usepid might have been set by -T */ - usepid = 1; + usepid = true; } else { - usepid = 0; + usepid = false; mydev = statbuf.st_dev; myino = statbuf.st_ino; } @@ -190,12 +154,15 @@ int main(int argc, char **argv) { if (signal(SIGALRM, timeout_alarm_handler) == SIG_ERR) { die(STATE_UNKNOWN, _("Cannot catch SIGALRM")); } - (void)alarm((unsigned)timeout_interval); + (void)alarm(timeout_interval); if (verbose >= 2) { printf(_("CMD: %s\n"), PS_COMMAND); } + output chld_out; + output chld_err; + mp_state_enum result = STATE_UNKNOWN; if (input_filename == NULL) { result = cmd_run(PS_COMMAND, &chld_out, &chld_err, 0); if (chld_err.lines > 0) { @@ -206,20 +173,43 @@ int main(int argc, char **argv) { result = cmd_file_read(input_filename, &chld_out, 0); } + int pos; /* number of spaces before 'args' in `ps` output */ + uid_t procuid = 0; + pid_t procpid = 0; + pid_t procppid = 0; + pid_t kthread_ppid = 0; + int warn = 0; /* number of processes in warn state */ + int crit = 0; /* number of processes in crit state */ + int procvsz = 0; + int procrss = 0; + int procseconds = 0; + float procpcpu = 0; + char procstat[8]; + char procetime[MAX_INPUT_BUFFER] = {'\0'}; + int resultsum = 0; /* bitmask of the filter criteria met by a process */ + int found = 0; /* counter for number of lines returned in `ps` output */ + int procs = 0; /* counter for number of processes meeting filter criteria */ + char *input_buffer = malloc(MAX_INPUT_BUFFER); + char *procprog = malloc(MAX_INPUT_BUFFER); + const int expected_cols = PS_COLS - 1; + /* flush first line: j starts at 1 */ for (size_t j = 1; j < chld_out.lines; j++) { - input_line = chld_out.line[j]; + char *input_line = chld_out.line[j]; if (verbose >= 3) { printf("%s", input_line); } strcpy(procprog, ""); + char *procargs; xasprintf(&procargs, "%s", ""); - cols = sscanf(input_line, PS_FORMAT, PS_VARLIST); + /* number of columns in ps output */ + int cols = sscanf(input_line, PS_FORMAT, PS_VARLIST); /* Zombie processes do not give a procprog command */ + const char *zombie = "Z"; if (cols < expected_cols && strstr(procstat, zombie)) { cols = expected_cols; } @@ -240,6 +230,7 @@ int main(int argc, char **argv) { } /* Ignore self */ + int ret = 0; if ((usepid && mypid == procpid) || (((!usepid) && ((ret = stat_exe(procpid, &statbuf) != -1) && statbuf.st_dev == mydev && statbuf.st_ino == myino)) || (ret == -1 && errno == ENOENT))) { @@ -249,7 +240,7 @@ int main(int argc, char **argv) { continue; } /* Ignore parent*/ - else if (myppid == procpid) { + if (myppid == procpid) { if (verbose >= 3) { printf("not considering - is parent\n"); } @@ -266,15 +257,13 @@ int main(int argc, char **argv) { /* Ignore excluded processes by name */ if (options & EXCLUDE_PROGS) { - int found = 0; - int i = 0; - - for (i = 0; i < (exclude_progs_counter); i++) { + bool found = false; + for (int i = 0; i < (exclude_progs_counter); i++) { if (!strcmp(procprog, exclude_progs_arr[i])) { - found = 1; + found = true; } } - if (found == 0) { + if (!found) { resultsum |= EXCLUDE_PROGS; } else { if (verbose >= 3) { @@ -286,7 +275,7 @@ int main(int argc, char **argv) { /* filter kernel threads (children of KTHREAD_PARENT)*/ /* TODO adapt for other OSes than GNU/Linux sorry for not doing that, but I've no other OSes to test :-( */ - if (kthread_filter == 1) { + if (kthread_filter) { /* get pid KTHREAD_PARENT */ if (kthread_ppid == 0 && !strcmp(procprog, KTHREAD_PARENT)) { kthread_ppid = procpid; @@ -341,28 +330,29 @@ int main(int argc, char **argv) { procrss, procpid, procppid, procpcpu, procstat, procetime, procprog, procargs); } + mp_state_enum temporary_result = STATE_OK; if (metric == METRIC_VSZ) { - i = get_status((double)procvsz, procs_thresholds); + temporary_result = get_status((double)procvsz, procs_thresholds); } else if (metric == METRIC_RSS) { - i = get_status((double)procrss, procs_thresholds); + temporary_result = get_status((double)procrss, procs_thresholds); } /* TODO? float thresholds for --metric=CPU */ else if (metric == METRIC_CPU) { - i = get_status(procpcpu, procs_thresholds); + temporary_result = get_status(procpcpu, procs_thresholds); } else if (metric == METRIC_ELAPSED) { - i = get_status((double)procseconds, procs_thresholds); + temporary_result = get_status((double)procseconds, procs_thresholds); } if (metric != METRIC_PROCS) { - if (i == STATE_WARNING) { + if (temporary_result == STATE_WARNING) { warn++; xasprintf(&fails, "%s%s%s", fails, (strcmp(fails, "") ? ", " : ""), procprog); - result = max_state(result, i); + result = max_state(result, temporary_result); } - if (i == STATE_CRITICAL) { + if (temporary_result == STATE_CRITICAL) { crit++; xasprintf(&fails, "%s%s%s", fails, (strcmp(fails, "") ? ", " : ""), procprog); - result = max_state(result, i); + result = max_state(result, temporary_result); } } } @@ -416,20 +406,11 @@ int main(int argc, char **argv) { } printf("\n"); - return result; + exit(result); } /* process command-line arguments */ int process_arguments(int argc, char **argv) { - int c = 1; - char *user; - struct passwd *pw; - int option = 0; - int err; - int cflags = REG_NOSUB | REG_EXTENDED; - char errbuf[MAX_INPUT_BUFFER]; - char *temp_string; - int i = 0; static struct option longopts[] = {{"warning", required_argument, 0, 'w'}, {"critical", required_argument, 0, 'c'}, {"metric", required_argument, 0, 'm'}, @@ -453,20 +434,21 @@ int process_arguments(int argc, char **argv) { {"exclude-process", required_argument, 0, 'X'}, {0, 0, 0, 0}}; - 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, "Vvhkt:c:w:p:s:u:C:a:z:r:m:P:T:X:", longopts, &option); + while (true) { + int option = 0; + int option_index = getopt_long(argc, argv, "Vvhkt:c:w:p:s:u:C:a:z:r:m:P:T:X:", longopts, &option); - if (c == -1 || c == EOF) { + if (option_index == -1 || option_index == EOF) { break; } - switch (c) { + switch (option_index) { case '?': /* help */ usage5(); case 'h': /* help */ @@ -504,10 +486,11 @@ int process_arguments(int argc, char **argv) { xasprintf(&fmt, _("%s%sSTATE = %s"), (fmt ? fmt : ""), (options ? ", " : ""), statopts); options |= STAT; break; - case 'u': /* user or user id */ + case 'u': /* user or user id */ { + struct passwd *pw; if (is_integer(optarg)) { uid = atoi(optarg); - pw = getpwuid((uid_t)uid); + pw = getpwuid(uid); /* check to be sure user exists */ if (pw == NULL) { usage2(_("UID was not found"), optarg); @@ -521,10 +504,11 @@ int process_arguments(int argc, char **argv) { /* then get uid */ uid = pw->pw_uid; } - user = pw->pw_name; + + char *user = pw->pw_name; xasprintf(&fmt, "%s%sUID = %d (%s)", (fmt ? fmt : ""), (options ? ", " : ""), uid, user); options |= USER; - break; + } break; case 'C': /* command */ /* TODO: allow this to be passed in with --metric */ if (prog) { @@ -542,12 +526,12 @@ int process_arguments(int argc, char **argv) { exclude_progs = optarg; } xasprintf(&fmt, _("%s%sexclude progs '%s'"), (fmt ? fmt : ""), (options ? ", " : ""), exclude_progs); - char *p = strtok(exclude_progs, ","); + char *tmp_pointer = strtok(exclude_progs, ","); - while (p) { + while (tmp_pointer) { exclude_progs_arr = realloc(exclude_progs_arr, sizeof(char *) * ++exclude_progs_counter); - exclude_progs_arr[exclude_progs_counter - 1] = p; - p = strtok(NULL, ","); + exclude_progs_arr[exclude_progs_counter - 1] = tmp_pointer; + tmp_pointer = strtok(NULL, ","); } options |= EXCLUDE_PROGS; @@ -562,23 +546,26 @@ int process_arguments(int argc, char **argv) { xasprintf(&fmt, "%s%sargs '%s'", (fmt ? fmt : ""), (options ? ", " : ""), args); options |= ARGS; break; - case CHAR_MAX + 1: - err = regcomp(&re_args, optarg, cflags); + case CHAR_MAX + 1: { + int cflags = REG_NOSUB | REG_EXTENDED; + int err = regcomp(&re_args, optarg, cflags); if (err != 0) { + char errbuf[MAX_INPUT_BUFFER]; regerror(err, &re_args, errbuf, MAX_INPUT_BUFFER); die(STATE_UNKNOWN, "PROCS %s: %s - %s\n", _("UNKNOWN"), _("Could not compile regular expression"), errbuf); } /* Strip off any | within the regex optarg */ - temp_string = strdup(optarg); - while (temp_string[i] != '\0') { - if (temp_string[i] == '|') { - temp_string[i] = ','; + char *temp_string = strdup(optarg); + int index = 0; + while (temp_string[index] != '\0') { + if (temp_string[index] == '|') { + temp_string[index] = ','; } - i++; + index++; } xasprintf(&fmt, "%s%sregex args '%s'", (fmt ? fmt : ""), (options ? ", " : ""), temp_string); options |= EREG_ARGS; - break; + } break; case 'r': /* RSS */ if (sscanf(optarg, "%d%[^0-9]", &rss, tmp) == 1) { xasprintf(&fmt, "%s%sRSS >= %d", (fmt ? fmt : ""), (options ? ", " : ""), rss); @@ -606,29 +593,33 @@ int process_arguments(int argc, char **argv) { if (strcmp(optarg, "PROCS") == 0) { metric = METRIC_PROCS; break; - } else if (strcmp(optarg, "VSZ") == 0) { + } + if (strcmp(optarg, "VSZ") == 0) { metric = METRIC_VSZ; break; - } else if (strcmp(optarg, "RSS") == 0) { + } + if (strcmp(optarg, "RSS") == 0) { metric = METRIC_RSS; break; - } else if (strcmp(optarg, "CPU") == 0) { + } + if (strcmp(optarg, "CPU") == 0) { metric = METRIC_CPU; break; - } else if (strcmp(optarg, "ELAPSED") == 0) { + } + if (strcmp(optarg, "ELAPSED") == 0) { metric = METRIC_ELAPSED; break; } usage4(_("Metric must be one of PROCS, VSZ, RSS, CPU, ELAPSED!")); case 'k': /* linux kernel thread filter */ - kthread_filter = 1; + kthread_filter = true; break; case 'v': /* command */ verbose++; break; case 'T': - usepid = 1; + usepid = true; break; case CHAR_MAX + 2: input_filename = optarg; @@ -636,15 +627,15 @@ int process_arguments(int argc, char **argv) { } } - c = optind; - if ((!warning_range) && argv[c]) { - warning_range = argv[c++]; + int index = optind; + if ((!warning_range) && argv[index]) { + warning_range = argv[index++]; } - if ((!critical_range) && argv[c]) { - critical_range = argv[c++]; + if ((!critical_range) && argv[index]) { + critical_range = argv[index++]; } - if (statopts == NULL && argv[c]) { - xasprintf(&statopts, "%s", argv[c++]); + if (statopts == NULL && argv[index]) { + xasprintf(&statopts, "%s", argv[index++]); xasprintf(&fmt, _("%s%sSTATE = %s"), (fmt ? fmt : ""), (options ? ", " : ""), statopts); options |= STAT; } @@ -685,25 +676,9 @@ int validate_arguments() { /* convert the elapsed time to seconds */ int convert_to_seconds(char *etime) { - - char *ptr; - int total; - - int hyphcnt; - int coloncnt; - int days; - int hours; - int minutes; - int seconds; - - hyphcnt = 0; - coloncnt = 0; - days = 0; - hours = 0; - minutes = 0; - seconds = 0; - - for (ptr = etime; *ptr != '\0'; ptr++) { + int hyphcnt = 0; + int coloncnt = 0; + for (char *ptr = etime; *ptr != '\0'; ptr++) { if (*ptr == '-') { hyphcnt++; @@ -715,6 +690,10 @@ int convert_to_seconds(char *etime) { } } + int days = 0; + int hours = 0; + int minutes = 0; + int seconds = 0; if (hyphcnt > 0) { sscanf(etime, "%d-%d:%d:%d", &days, &hours, &minutes, &seconds); /* linux 2.6.5/2.6.6 reporting some processes with infinite @@ -730,7 +709,7 @@ int convert_to_seconds(char *etime) { } } - total = (days * 86400) + (hours * 3600) + (minutes * 60) + seconds; + int total = (days * 86400) + (hours * 3600) + (minutes * 60) + seconds; if (verbose >= 3 && metric == METRIC_ELAPSED) { printf("seconds: %d\n", total); -- cgit v1.2.3-74-g34f1 From a14b2b35776c7550123ce58af571913eb9d7819f Mon Sep 17 00:00:00 2001 From: Lorenz Kästle <12514511+RincewindsHat@users.noreply.github.com> Date: Wed, 12 Mar 2025 15:29:36 +0100 Subject: Refactor check_procs --- plugins/Makefile.am | 1 + plugins/check_procs.c | 335 ++++++++++++++++++++--------------------- plugins/check_procs.d/config.h | 75 +++++++++ 3 files changed, 243 insertions(+), 168 deletions(-) create mode 100644 plugins/check_procs.d/config.h (limited to 'plugins') diff --git a/plugins/Makefile.am b/plugins/Makefile.am index 6c582a15..0920adce 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_procs.d \ check_by_ssh.d \ check_smtp.d \ check_mysql.d \ diff --git a/plugins/check_procs.c b/plugins/check_procs.c index da2198a7..83e6864e 100644 --- a/plugins/check_procs.c +++ b/plugins/check_procs.c @@ -44,6 +44,7 @@ const char *email = "devel@monitoring-plugins.org"; #include "utils_cmd.h" #include "regex.h" #include "states.h" +#include "check_procs.d/config.h" #include #include @@ -52,17 +53,17 @@ const char *email = "devel@monitoring-plugins.org"; # include #endif -static int process_arguments(int /*argc*/, char ** /*argv*/); -static int validate_arguments(void); -static int convert_to_seconds(char * /*etime*/); +typedef struct { + int errorcode; + check_procs_config config; +} check_procs_config_wrapper; +static check_procs_config_wrapper process_arguments(int /*argc*/, char ** /*argv*/); +static check_procs_config_wrapper validate_arguments(check_procs_config_wrapper /*config_wrapper*/); + +static int convert_to_seconds(char * /*etime*/, enum metric /*metric*/); static void print_help(void); void print_usage(void); -static char *warning_range = NULL; -static char *critical_range = NULL; -static thresholds *procs_thresholds = NULL; - -static int options = 0; /* bitmask of filter criteria to test against */ #define ALL 1 #define STAT 2 #define PPID 4 @@ -80,36 +81,7 @@ static int options = 0; /* bitmask of filter criteria to test against */ "kthreadd" /* the parent process of kernel threads: \ ppid of procs are compared to pid of this proc*/ -/* Different metrics */ -char *metric_name; -enum metric { - METRIC_PROCS, - METRIC_VSZ, - METRIC_RSS, - METRIC_CPU, - METRIC_ELAPSED -}; -enum metric metric = METRIC_PROCS; - static int verbose = 0; -static uid_t uid; -static pid_t ppid; -static int vsz; -static int rss; -static float pcpu; -static char *statopts; -static char *prog; -static char *exclude_progs; -static char **exclude_progs_arr = NULL; -static char exclude_progs_counter = 0; -static char *args; -static char *input_filename = NULL; -static regex_t re_args; -static char *fmt; -static char *fails; -static char tmp[MAX_INPUT_BUFFER]; -static bool kthread_filter = false; -static bool usepid = false; /* whether to test for pid or /proc/pid/exe */ static int stat_exe(const pid_t pid, struct stat *buf) { char *path; @@ -125,27 +97,27 @@ int main(int argc, char **argv) { bindtextdomain(PACKAGE, LOCALEDIR); textdomain(PACKAGE); - xasprintf(&metric_name, "PROCS"); - metric = METRIC_PROCS; - /* Parse extra opts if any */ argv = np_extra_opts(&argc, argv, progname); - if (process_arguments(argc, argv) == ERROR) { + check_procs_config_wrapper tmp_config = process_arguments(argc, argv); + if (tmp_config.errorcode == ERROR) { usage4(_("Could not parse arguments")); } + check_procs_config config = tmp_config.config; + /* find ourself */ pid_t mypid = getpid(); pid_t myppid = getppid(); dev_t mydev = 0; ino_t myino = 0; struct stat statbuf; - if (usepid || stat_exe(mypid, &statbuf) == -1) { + if (config.usepid || stat_exe(mypid, &statbuf) == -1) { /* usepid might have been set by -T */ - usepid = true; + config.usepid = true; } else { - usepid = false; + config.usepid = false; mydev = statbuf.st_dev; myino = statbuf.st_ino; } @@ -163,14 +135,14 @@ int main(int argc, char **argv) { output chld_out; output chld_err; mp_state_enum result = STATE_UNKNOWN; - if (input_filename == NULL) { + if (config.input_filename == NULL) { result = cmd_run(PS_COMMAND, &chld_out, &chld_err, 0); if (chld_err.lines > 0) { printf("%s: %s", _("System call sent warnings to stderr"), chld_err.line[0]); exit(STATE_WARNING); } } else { - result = cmd_file_read(input_filename, &chld_out, 0); + result = cmd_file_read(config.input_filename, &chld_out, 0); } int pos; /* number of spaces before 'args' in `ps` output */ @@ -222,7 +194,7 @@ int main(int argc, char **argv) { strcpy(procprog, base_name(procprog)); /* we need to convert the elapsed time to seconds */ - procseconds = convert_to_seconds(procetime); + procseconds = convert_to_seconds(procetime, config.metric); if (verbose >= 3) { printf("proc#=%d uid=%d vsz=%d rss=%d pid=%d ppid=%d pcpu=%.2f stat=%s etime=%s prog=%s args=%s\n", procs, procuid, procvsz, @@ -231,8 +203,8 @@ int main(int argc, char **argv) { /* Ignore self */ int ret = 0; - if ((usepid && mypid == procpid) || - (((!usepid) && ((ret = stat_exe(procpid, &statbuf) != -1) && statbuf.st_dev == mydev && statbuf.st_ino == myino)) || + if ((config.usepid && mypid == procpid) || + (((!config.usepid) && ((ret = stat_exe(procpid, &statbuf) != -1) && statbuf.st_dev == mydev && statbuf.st_ino == myino)) || (ret == -1 && errno == ENOENT))) { if (verbose >= 3) { printf("not considering - is myself or gone\n"); @@ -256,10 +228,10 @@ int main(int argc, char **argv) { } /* Ignore excluded processes by name */ - if (options & EXCLUDE_PROGS) { + if (config.options & EXCLUDE_PROGS) { bool found = false; - for (int i = 0; i < (exclude_progs_counter); i++) { - if (!strcmp(procprog, exclude_progs_arr[i])) { + for (int i = 0; i < (config.exclude_progs_counter); i++) { + if (!strcmp(procprog, config.exclude_progs_arr[i])) { found = true; } } @@ -275,7 +247,7 @@ int main(int argc, char **argv) { /* filter kernel threads (children of KTHREAD_PARENT)*/ /* TODO adapt for other OSes than GNU/Linux sorry for not doing that, but I've no other OSes to test :-( */ - if (kthread_filter) { + if (config.kthread_filter) { /* get pid KTHREAD_PARENT */ if (kthread_ppid == 0 && !strcmp(procprog, KTHREAD_PARENT)) { kthread_ppid = procpid; @@ -289,38 +261,38 @@ int main(int argc, char **argv) { } } - if ((options & STAT) && (strstr(procstat, statopts))) { + if ((config.options & STAT) && (strstr(procstat, config.statopts))) { resultsum |= STAT; } - if ((options & ARGS) && procargs && (strstr(procargs, args) != NULL)) { + if ((config.options & ARGS) && procargs && (strstr(procargs, config.args) != NULL)) { resultsum |= ARGS; } - if ((options & EREG_ARGS) && procargs && (regexec(&re_args, procargs, (size_t)0, NULL, 0) == 0)) { + if ((config.options & EREG_ARGS) && procargs && (regexec(&config.re_args, procargs, (size_t)0, NULL, 0) == 0)) { resultsum |= EREG_ARGS; } - if ((options & PROG) && procprog && (strcmp(prog, procprog) == 0)) { + if ((config.options & PROG) && procprog && (strcmp(config.prog, procprog) == 0)) { resultsum |= PROG; } - if ((options & PPID) && (procppid == ppid)) { + if ((config.options & PPID) && (procppid == config.ppid)) { resultsum |= PPID; } - if ((options & USER) && (procuid == uid)) { + if ((config.options & USER) && (procuid == config.uid)) { resultsum |= USER; } - if ((options & VSZ) && (procvsz >= vsz)) { + if ((config.options & VSZ) && (procvsz >= config.vsz)) { resultsum |= VSZ; } - if ((options & RSS) && (procrss >= rss)) { + if ((config.options & RSS) && (procrss >= config.rss)) { resultsum |= RSS; } - if ((options & PCPU) && (procpcpu >= pcpu)) { + if ((config.options & PCPU) && (procpcpu >= config.pcpu)) { resultsum |= PCPU; } found++; /* Next line if filters not matched */ - if (!(options == resultsum || options == ALL)) { + if (!(config.options == resultsum || config.options == ALL)) { continue; } @@ -331,27 +303,27 @@ int main(int argc, char **argv) { } mp_state_enum temporary_result = STATE_OK; - if (metric == METRIC_VSZ) { - temporary_result = get_status((double)procvsz, procs_thresholds); - } else if (metric == METRIC_RSS) { - temporary_result = get_status((double)procrss, procs_thresholds); + if (config.metric == METRIC_VSZ) { + temporary_result = get_status((double)procvsz, config.procs_thresholds); + } else if (config.metric == METRIC_RSS) { + temporary_result = get_status((double)procrss, config.procs_thresholds); } /* TODO? float thresholds for --metric=CPU */ - else if (metric == METRIC_CPU) { - temporary_result = get_status(procpcpu, procs_thresholds); - } else if (metric == METRIC_ELAPSED) { - temporary_result = get_status((double)procseconds, procs_thresholds); + else if (config.metric == METRIC_CPU) { + temporary_result = get_status(procpcpu, config.procs_thresholds); + } else if (config.metric == METRIC_ELAPSED) { + temporary_result = get_status((double)procseconds, config.procs_thresholds); } - if (metric != METRIC_PROCS) { + if (config.metric != METRIC_PROCS) { if (temporary_result == STATE_WARNING) { warn++; - xasprintf(&fails, "%s%s%s", fails, (strcmp(fails, "") ? ", " : ""), procprog); + xasprintf(&config.fails, "%s%s%s", config.fails, (strcmp(config.fails, "") ? ", " : ""), procprog); result = max_state(result, temporary_result); } if (temporary_result == STATE_CRITICAL) { crit++; - xasprintf(&fails, "%s%s%s", fails, (strcmp(fails, "") ? ", " : ""), procprog); + xasprintf(&config.fails, "%s%s%s", config.fails, (strcmp(config.fails, "") ? ", " : ""), procprog); result = max_state(result, temporary_result); } } @@ -372,35 +344,36 @@ int main(int argc, char **argv) { } /* Needed if procs found, but none match filter */ - if (metric == METRIC_PROCS) { - result = max_state(result, get_status((double)procs, procs_thresholds)); + if (config.metric == METRIC_PROCS) { + result = max_state(result, get_status((double)procs, config.procs_thresholds)); } if (result == STATE_OK) { - printf("%s %s: ", metric_name, _("OK")); + printf("%s %s: ", config.metric_name, _("OK")); } else if (result == STATE_WARNING) { - printf("%s %s: ", metric_name, _("WARNING")); - if (metric != METRIC_PROCS) { + printf("%s %s: ", config.metric_name, _("WARNING")); + if (config.metric != METRIC_PROCS) { printf(_("%d warn out of "), warn); } } else if (result == STATE_CRITICAL) { - printf("%s %s: ", metric_name, _("CRITICAL")); - if (metric != METRIC_PROCS) { + printf("%s %s: ", config.metric_name, _("CRITICAL")); + if (config.metric != METRIC_PROCS) { printf(_("%d crit, %d warn out of "), crit, warn); } } printf(ngettext("%d process", "%d processes", (unsigned long)procs), procs); - if (strcmp(fmt, "") != 0) { - printf(_(" with %s"), fmt); + if (strcmp(config.fmt, "") != 0) { + printf(_(" with %s"), config.fmt); } - if (verbose >= 1 && strcmp(fails, "")) { - printf(" [%s]", fails); + if (verbose >= 1 && strcmp(config.fails, "")) { + printf(" [%s]", config.fails); } - if (metric == METRIC_PROCS) { - printf(" | procs=%d;%s;%s;0;", procs, warning_range ? warning_range : "", critical_range ? critical_range : ""); + if (config.metric == METRIC_PROCS) { + printf(" | procs=%d;%s;%s;0;", procs, config.warning_range ? config.warning_range : "", + config.critical_range ? config.critical_range : ""); } else { printf(" | procs=%d;;;0; procs_warn=%d;;;0; procs_crit=%d;;;0;", procs, warn, crit); } @@ -410,7 +383,7 @@ int main(int argc, char **argv) { } /* process command-line arguments */ -int process_arguments(int argc, char **argv) { +check_procs_config_wrapper process_arguments(int argc, char **argv) { static struct option longopts[] = {{"warning", required_argument, 0, 'w'}, {"critical", required_argument, 0, 'c'}, {"metric", required_argument, 0, 'm'}, @@ -440,6 +413,11 @@ int process_arguments(int argc, char **argv) { } } + check_procs_config_wrapper result = { + .errorcode = OK, + .config = check_procs_config_init(), + }; + while (true) { int option = 0; int option_index = getopt_long(argc, argv, "Vvhkt:c:w:p:s:u:C:a:z:r:m:P:T:X:", longopts, &option); @@ -465,32 +443,36 @@ int process_arguments(int argc, char **argv) { } break; case 'c': /* critical threshold */ - critical_range = optarg; + result.config.critical_range = optarg; break; case 'w': /* warning threshold */ - warning_range = optarg; + result.config.warning_range = optarg; break; - case 'p': /* process id */ - if (sscanf(optarg, "%d%[^0-9]", &ppid, tmp) == 1) { - xasprintf(&fmt, "%s%sPPID = %d", (fmt ? fmt : ""), (options ? ", " : ""), ppid); - options |= PPID; + case 'p': { /* process id */ + static char tmp[MAX_INPUT_BUFFER]; + if (sscanf(optarg, "%d%[^0-9]", &result.config.ppid, tmp) == 1) { + xasprintf(&result.config.fmt, "%s%sPPID = %d", (result.config.fmt ? result.config.fmt : ""), + (result.config.options ? ", " : ""), result.config.ppid); + result.config.options |= PPID; break; } usage4(_("Parent Process ID must be an integer!")); + } case 's': /* status */ - if (statopts) { + if (result.config.statopts) { break; } else { - statopts = optarg; + result.config.statopts = optarg; } - xasprintf(&fmt, _("%s%sSTATE = %s"), (fmt ? fmt : ""), (options ? ", " : ""), statopts); - options |= STAT; + xasprintf(&result.config.fmt, _("%s%sSTATE = %s"), (result.config.fmt ? result.config.fmt : ""), + (result.config.options ? ", " : ""), result.config.statopts); + result.config.options |= STAT; break; case 'u': /* user or user id */ { struct passwd *pw; if (is_integer(optarg)) { - uid = atoi(optarg); - pw = getpwuid(uid); + result.config.uid = atoi(optarg); + pw = getpwuid(result.config.uid); /* check to be sure user exists */ if (pw == NULL) { usage2(_("UID was not found"), optarg); @@ -502,56 +484,61 @@ int process_arguments(int argc, char **argv) { usage2(_("User name was not found"), optarg); } /* then get uid */ - uid = pw->pw_uid; + result.config.uid = pw->pw_uid; } char *user = pw->pw_name; - xasprintf(&fmt, "%s%sUID = %d (%s)", (fmt ? fmt : ""), (options ? ", " : ""), uid, user); - options |= USER; + xasprintf(&result.config.fmt, "%s%sUID = %d (%s)", (result.config.fmt ? result.config.fmt : ""), + (result.config.options ? ", " : ""), result.config.uid, user); + result.config.options |= USER; } break; case 'C': /* command */ /* TODO: allow this to be passed in with --metric */ - if (prog) { + if (result.config.prog) { break; } else { - prog = optarg; + result.config.prog = optarg; } - xasprintf(&fmt, _("%s%scommand name '%s'"), (fmt ? fmt : ""), (options ? ", " : ""), prog); - options |= PROG; + xasprintf(&result.config.fmt, _("%s%scommand name '%s'"), (result.config.fmt ? result.config.fmt : ""), + (result.config.options ? ", " : ""), result.config.prog); + result.config.options |= PROG; break; case 'X': - if (exclude_progs) { + if (result.config.exclude_progs) { break; } else { - exclude_progs = optarg; + result.config.exclude_progs = optarg; } - xasprintf(&fmt, _("%s%sexclude progs '%s'"), (fmt ? fmt : ""), (options ? ", " : ""), exclude_progs); - char *tmp_pointer = strtok(exclude_progs, ","); + xasprintf(&result.config.fmt, _("%s%sexclude progs '%s'"), (result.config.fmt ? result.config.fmt : ""), + (result.config.options ? ", " : ""), result.config.exclude_progs); + char *tmp_pointer = strtok(result.config.exclude_progs, ","); while (tmp_pointer) { - exclude_progs_arr = realloc(exclude_progs_arr, sizeof(char *) * ++exclude_progs_counter); - exclude_progs_arr[exclude_progs_counter - 1] = tmp_pointer; + result.config.exclude_progs_arr = + realloc(result.config.exclude_progs_arr, sizeof(char *) * ++result.config.exclude_progs_counter); + result.config.exclude_progs_arr[result.config.exclude_progs_counter - 1] = tmp_pointer; tmp_pointer = strtok(NULL, ","); } - options |= EXCLUDE_PROGS; + result.config.options |= EXCLUDE_PROGS; break; case 'a': /* args (full path name with args) */ /* TODO: allow this to be passed in with --metric */ - if (args) { + if (result.config.args) { break; } else { - args = optarg; + result.config.args = optarg; } - xasprintf(&fmt, "%s%sargs '%s'", (fmt ? fmt : ""), (options ? ", " : ""), args); - options |= ARGS; + xasprintf(&result.config.fmt, "%s%sargs '%s'", (result.config.fmt ? result.config.fmt : ""), + (result.config.options ? ", " : ""), result.config.args); + result.config.options |= ARGS; break; case CHAR_MAX + 1: { int cflags = REG_NOSUB | REG_EXTENDED; - int err = regcomp(&re_args, optarg, cflags); + int err = regcomp(&result.config.re_args, optarg, cflags); if (err != 0) { char errbuf[MAX_INPUT_BUFFER]; - regerror(err, &re_args, errbuf, MAX_INPUT_BUFFER); + regerror(err, &result.config.re_args, errbuf, MAX_INPUT_BUFFER); die(STATE_UNKNOWN, "PROCS %s: %s - %s\n", _("UNKNOWN"), _("Could not compile regular expression"), errbuf); } /* Strip off any | within the regex optarg */ @@ -563,119 +550,131 @@ int process_arguments(int argc, char **argv) { } index++; } - xasprintf(&fmt, "%s%sregex args '%s'", (fmt ? fmt : ""), (options ? ", " : ""), temp_string); - options |= EREG_ARGS; + xasprintf(&result.config.fmt, "%s%sregex args '%s'", (result.config.fmt ? result.config.fmt : ""), + (result.config.options ? ", " : ""), temp_string); + result.config.options |= EREG_ARGS; } break; - case 'r': /* RSS */ - if (sscanf(optarg, "%d%[^0-9]", &rss, tmp) == 1) { - xasprintf(&fmt, "%s%sRSS >= %d", (fmt ? fmt : ""), (options ? ", " : ""), rss); - options |= RSS; + case 'r': { /* RSS */ + static char tmp[MAX_INPUT_BUFFER]; + if (sscanf(optarg, "%d%[^0-9]", &result.config.rss, tmp) == 1) { + xasprintf(&result.config.fmt, "%s%sRSS >= %d", (result.config.fmt ? result.config.fmt : ""), + (result.config.options ? ", " : ""), result.config.rss); + result.config.options |= RSS; break; } usage4(_("RSS must be an integer!")); - case 'z': /* VSZ */ - if (sscanf(optarg, "%d%[^0-9]", &vsz, tmp) == 1) { - xasprintf(&fmt, "%s%sVSZ >= %d", (fmt ? fmt : ""), (options ? ", " : ""), vsz); - options |= VSZ; + } + case 'z': { /* VSZ */ + static char tmp[MAX_INPUT_BUFFER]; + if (sscanf(optarg, "%d%[^0-9]", &result.config.vsz, tmp) == 1) { + xasprintf(&result.config.fmt, "%s%sVSZ >= %d", (result.config.fmt ? result.config.fmt : ""), + (result.config.options ? ", " : ""), result.config.vsz); + result.config.options |= VSZ; break; } usage4(_("VSZ must be an integer!")); - case 'P': /* PCPU */ + } + case 'P': { /* PCPU */ /* TODO: -P 1.5.5 is accepted */ - if (sscanf(optarg, "%f%[^0-9.]", &pcpu, tmp) == 1) { - xasprintf(&fmt, "%s%sPCPU >= %.2f", (fmt ? fmt : ""), (options ? ", " : ""), pcpu); - options |= PCPU; + static char tmp[MAX_INPUT_BUFFER]; + if (sscanf(optarg, "%f%[^0-9.]", &result.config.pcpu, tmp) == 1) { + xasprintf(&result.config.fmt, "%s%sPCPU >= %.2f", (result.config.fmt ? result.config.fmt : ""), + (result.config.options ? ", " : ""), result.config.pcpu); + result.config.options |= PCPU; break; } usage4(_("PCPU must be a float!")); + } case 'm': - xasprintf(&metric_name, "%s", optarg); + xasprintf(&result.config.metric_name, "%s", optarg); if (strcmp(optarg, "PROCS") == 0) { - metric = METRIC_PROCS; + result.config.metric = METRIC_PROCS; break; } if (strcmp(optarg, "VSZ") == 0) { - metric = METRIC_VSZ; + result.config.metric = METRIC_VSZ; break; } if (strcmp(optarg, "RSS") == 0) { - metric = METRIC_RSS; + result.config.metric = METRIC_RSS; break; } if (strcmp(optarg, "CPU") == 0) { - metric = METRIC_CPU; + result.config.metric = METRIC_CPU; break; } if (strcmp(optarg, "ELAPSED") == 0) { - metric = METRIC_ELAPSED; + result.config.metric = METRIC_ELAPSED; break; } usage4(_("Metric must be one of PROCS, VSZ, RSS, CPU, ELAPSED!")); case 'k': /* linux kernel thread filter */ - kthread_filter = true; + result.config.kthread_filter = true; break; case 'v': /* command */ verbose++; break; case 'T': - usepid = true; + result.config.usepid = true; break; case CHAR_MAX + 2: - input_filename = optarg; + result.config.input_filename = optarg; break; } } int index = optind; - if ((!warning_range) && argv[index]) { - warning_range = argv[index++]; + if ((!result.config.warning_range) && argv[index]) { + result.config.warning_range = argv[index++]; } - if ((!critical_range) && argv[index]) { - critical_range = argv[index++]; + if ((!result.config.critical_range) && argv[index]) { + result.config.critical_range = argv[index++]; } - if (statopts == NULL && argv[index]) { - xasprintf(&statopts, "%s", argv[index++]); - xasprintf(&fmt, _("%s%sSTATE = %s"), (fmt ? fmt : ""), (options ? ", " : ""), statopts); - options |= STAT; + if (result.config.statopts == NULL && argv[index]) { + xasprintf(&result.config.statopts, "%s", argv[index++]); + xasprintf(&result.config.fmt, _("%s%sSTATE = %s"), (result.config.fmt ? result.config.fmt : ""), + (result.config.options ? ", " : ""), result.config.statopts); + result.config.options |= STAT; } /* this will abort in case of invalid ranges */ - set_thresholds(&procs_thresholds, warning_range, critical_range); + set_thresholds(&result.config.procs_thresholds, result.config.warning_range, result.config.critical_range); - return validate_arguments(); + return validate_arguments(result); } -int validate_arguments() { - if (options == 0) { - options = ALL; +check_procs_config_wrapper validate_arguments(check_procs_config_wrapper config_wrapper) { + if (config_wrapper.config.options == 0) { + config_wrapper.config.options = ALL; } - if (statopts == NULL) { - statopts = strdup(""); + if (config_wrapper.config.statopts == NULL) { + config_wrapper.config.statopts = strdup(""); } - if (prog == NULL) { - prog = strdup(""); + if (config_wrapper.config.prog == NULL) { + config_wrapper.config.prog = strdup(""); } - if (args == NULL) { - args = strdup(""); + if (config_wrapper.config.args == NULL) { + config_wrapper.config.args = strdup(""); } - if (fmt == NULL) { - fmt = strdup(""); + if (config_wrapper.config.fmt == NULL) { + config_wrapper.config.fmt = strdup(""); } - if (fails == NULL) { - fails = strdup(""); + if (config_wrapper.config.fails == NULL) { + config_wrapper.config.fails = strdup(""); } - return options; + // return options; + return config_wrapper; } /* convert the elapsed time to seconds */ -int convert_to_seconds(char *etime) { +int convert_to_seconds(char *etime, enum metric metric) { int hyphcnt = 0; int coloncnt = 0; for (char *ptr = etime; *ptr != '\0'; ptr++) { diff --git a/plugins/check_procs.d/config.h b/plugins/check_procs.d/config.h new file mode 100644 index 00000000..815809d4 --- /dev/null +++ b/plugins/check_procs.d/config.h @@ -0,0 +1,75 @@ +#pragma once + +#include "../../config.h" +#include "regex.h" +#include "thresholds.h" +#include +#include +#include + +enum metric { + METRIC_PROCS, + METRIC_VSZ, + METRIC_RSS, + METRIC_CPU, + METRIC_ELAPSED +}; + +typedef struct { + int options; /* bitmask of filter criteria to test against */ + enum metric metric; + char *metric_name; + char *input_filename; + char *prog; + char *args; + char *fmt; + char *fails; + char *exclude_progs; + char **exclude_progs_arr; + char exclude_progs_counter; + regex_t re_args; + + bool kthread_filter; + bool usepid; /* whether to test for pid or /proc/pid/exe */ + uid_t uid; + pid_t ppid; + int vsz; + int rss; + float pcpu; + char *statopts; + + char *warning_range; + char *critical_range; + thresholds *procs_thresholds; +} check_procs_config; + +check_procs_config check_procs_config_init() { + check_procs_config tmp = { + .options = 0, + .metric = METRIC_PROCS, + .metric_name = strdup("PROCS"), + .input_filename = NULL, + .prog = NULL, + .args = NULL, + .fmt = NULL, + .fails = NULL, + .exclude_progs = NULL, + .exclude_progs_arr = NULL, + .exclude_progs_counter = 0, + .re_args = {}, + + .kthread_filter = false, + .usepid = false, + .uid = {}, + .ppid = {}, + .vsz = 0, + .rss = 0, + .pcpu = 0, + .statopts = NULL, + + .warning_range = NULL, + .critical_range = NULL, + .procs_thresholds = NULL, + }; + return tmp; +} -- cgit v1.2.3-74-g34f1 From a746576b8cb72a3233caf5ac852b2679cc98d80c Mon Sep 17 00:00:00 2001 From: Lorenz Kästle <12514511+RincewindsHat@users.noreply.github.com> Date: Wed, 12 Mar 2025 15:50:50 +0100 Subject: Fix initialisers for old compilers --- plugins/check_procs.d/config.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'plugins') diff --git a/plugins/check_procs.d/config.h b/plugins/check_procs.d/config.h index 815809d4..e32ca066 100644 --- a/plugins/check_procs.d/config.h +++ b/plugins/check_procs.d/config.h @@ -56,12 +56,12 @@ check_procs_config check_procs_config_init() { .exclude_progs = NULL, .exclude_progs_arr = NULL, .exclude_progs_counter = 0, - .re_args = {}, + .re_args = {0}, .kthread_filter = false, .usepid = false, - .uid = {}, - .ppid = {}, + .uid = 0, + .ppid = 0, .vsz = 0, .rss = 0, .pcpu = 0, -- 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(-) (limited to 'plugins') 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(-) (limited to 'plugins') 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 (limited to 'plugins') 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(-) (limited to 'plugins') 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(-) (limited to 'plugins') 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 (limited to 'plugins') 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(-) (limited to 'plugins') 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(-) (limited to 'plugins') 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(-) (limited to 'plugins') 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 (limited to 'plugins') 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 (limited to 'plugins') 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(-) (limited to 'plugins') 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 (limited to 'plugins') 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(-) (limited to 'plugins') 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 From d5ed6a2d8f3f3f388e5d1f2f7a8fc3ee2c9b6007 Mon Sep 17 00:00:00 2001 From: Lorenz Kästle <12514511+RincewindsHat@users.noreply.github.com> Date: Thu, 13 Mar 2025 00:43:22 +0100 Subject: check_tcp: small improvement + output format picker --- plugins/check_tcp.c | 46 +++++++++++++++++++++++++++++--------------- plugins/check_tcp.d/config.h | 9 +++++++-- 2 files changed, 38 insertions(+), 17 deletions(-) (limited to 'plugins') diff --git a/plugins/check_tcp.c b/plugins/check_tcp.c index f93152e5..793cfe7e 100644 --- a/plugins/check_tcp.c +++ b/plugins/check_tcp.c @@ -28,7 +28,6 @@ *****************************************************************************/ /* progname "check_tcp" changes depending on symlink called */ -#include "states.h" char *progname; const char *copyright = "1999-2025"; const char *email = "devel@monitoring-plugins.org"; @@ -37,6 +36,7 @@ const char *email = "devel@monitoring-plugins.org"; #include "./netutils.h" #include "./utils.h" #include "./check_tcp.d/config.h" +#include "states.h" #include #include @@ -61,10 +61,10 @@ ssize_t my_send(char *buf, size_t len) { typedef struct process_arguments_wrapper { int errorcode; check_tcp_config config; -} process_arguments_wrapper; +} check_tcp_config_wrapper; /* int my_recv(char *, size_t); */ -static process_arguments_wrapper process_arguments(int /*argc*/, char ** /*argv*/, check_tcp_config /*config*/); +static check_tcp_config_wrapper process_arguments(int /*argc*/, char ** /*argv*/, check_tcp_config /*config*/); void print_help(const char *service); void print_usage(void); @@ -207,7 +207,7 @@ int main(int argc, char **argv) { /* Parse extra opts if any */ argv = np_extra_opts(&argc, argv, progname); - process_arguments_wrapper paw = process_arguments(argc, argv, config); + check_tcp_config_wrapper paw = process_arguments(argc, argv, config); if (paw.errorcode == ERROR) { usage4(_("Could not parse arguments")); } @@ -229,6 +229,9 @@ int main(int argc, char **argv) { // Initialize check stuff before setting timers mp_check overall = mp_check_init(); + if (config.output_format_set) { + overall.format = config.output_format; + } /* set up the timer */ signal(SIGALRM, socket_timeout_alarm_handler); @@ -452,12 +455,12 @@ int main(int argc, char **argv) { } /* process command-line arguments */ -static process_arguments_wrapper process_arguments(int argc, char **argv, check_tcp_config config) { +static check_tcp_config_wrapper process_arguments(int argc, char **argv, check_tcp_config config) { enum { - SNI_OPTION = CHAR_MAX + 1 + SNI_OPTION = CHAR_MAX + 1, + output_format_index, }; - int option = 0; static struct option longopts[] = {{"hostname", required_argument, 0, 'H'}, {"critical", required_argument, 0, 'c'}, {"warning", required_argument, 0, 'w'}, @@ -484,6 +487,7 @@ static process_arguments_wrapper process_arguments(int argc, char **argv, check_ {"ssl", no_argument, 0, 'S'}, {"sni", required_argument, 0, SNI_OPTION}, {"certificate", required_argument, 0, 'D'}, + {"output-format", required_argument, 0, output_format_index}, {0, 0, 0, 0}}; if (argc < 2) { @@ -497,17 +501,17 @@ static process_arguments_wrapper process_arguments(int argc, char **argv, check_ argc--; } - int c; bool escape = false; while (true) { - c = getopt_long(argc, argv, "+hVv46EAH:s:e:q:m:c:w:t:p:C:W:d:Sr:jD:M:", longopts, &option); + int option = 0; + int option_index = getopt_long(argc, argv, "+hVv46EAH:s:e:q:m:c:w:t:p:C:W:d:Sr:jD:M:", 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 */ @@ -674,12 +678,24 @@ static process_arguments_wrapper process_arguments(int argc, char **argv, check_ case 'A': config.match_flags |= NP_MATCH_ALL; break; + 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_set = true; + config.output_format = parser.output_format; + break; + } } } - c = optind; - if (!config.host_specified && c < argc) { - config.server_address = strdup(argv[c++]); + int index = optind; + if (!config.host_specified && index < argc) { + config.server_address = strdup(argv[index++]); } if (config.server_address == NULL) { @@ -689,7 +705,7 @@ static process_arguments_wrapper process_arguments(int argc, char **argv, check_ config.server_address); } - process_arguments_wrapper result = { + check_tcp_config_wrapper result = { .config = config, .errorcode = OK, }; diff --git a/plugins/check_tcp.d/config.h b/plugins/check_tcp.d/config.h index 7ecf51a6..41db7224 100644 --- a/plugins/check_tcp.d/config.h +++ b/plugins/check_tcp.d/config.h @@ -1,10 +1,10 @@ #pragma once -#include "../common.h" #include "../../lib/utils_tcp.h" +#include "output.h" #include -typedef struct check_tcp_config { +typedef struct { char *server_address; bool host_specified; int server_port; // TODO can this be a uint16? @@ -37,6 +37,9 @@ typedef struct check_tcp_config { ssize_t maxbytes; bool hide_output; + + bool output_format_set; + mp_output_format output_format; } check_tcp_config; check_tcp_config check_tcp_config_init() { @@ -73,6 +76,8 @@ check_tcp_config check_tcp_config_init() { .maxbytes = 0, .hide_output = false, + + .output_format_set = false, }; return result; } -- cgit v1.2.3-74-g34f1 From 44e4e467c678d481dfc74ade1beb47e199ea67dd Mon Sep 17 00:00:00 2001 From: Lorenz Kästle <12514511+RincewindsHat@users.noreply.github.com> Date: Thu, 13 Mar 2025 00:43:46 +0100 Subject: Do not print on failed network connections --- plugins/netutils.c | 22 ++++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-) (limited to 'plugins') diff --git a/plugins/netutils.c b/plugins/netutils.c index ee81912a..5f118a9e 100644 --- a/plugins/netutils.c +++ b/plugins/netutils.c @@ -177,7 +177,7 @@ int np_net_connect(const char *host_name, int port, int *sd, int proto) { 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 +187,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; } @@ -237,10 +237,11 @@ int np_net_connect(const char *host_name, int port, int *sd, int proto) { 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 +249,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; } } -- cgit v1.2.3-74-g34f1 From 89df16e7503539c2b0da7e95375b470559bb94ec Mon Sep 17 00:00:00 2001 From: Lorenz Kästle <12514511+RincewindsHat@users.noreply.github.com> Date: Thu, 13 Mar 2025 00:44:35 +0100 Subject: Adapt tests --- plugins/t/check_tcp.t | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'plugins') diff --git a/plugins/t/check_tcp.t b/plugins/t/check_tcp.t index cb4de53d..b47caab3 100644 --- a/plugins/t/check_tcp.t +++ b/plugins/t/check_tcp.t @@ -21,19 +21,19 @@ my $host_nonresponsive = getTestParameter("NP_HOST_NONRESPONSIVE", "The hostname my $hostname_invalid = getTestParameter("NP_HOSTNAME_INVALID", "An invalid (not known to DNS) hostname", "nosuchhost"); my $internet_access = getTestParameter("NP_INTERNET_ACCESS", "Is this system directly connected to the internet?", "yes"); -my $successOutput = '/^TCP OK\s-\s+[0-9]?\.?[0-9]+ second response time on port [0-9]+/'; +my $successOutput = '/Connection time\s+[0-9]?\.?[0-9]+s is within thresholds+/'; -my $failedExpect = '/^TCP WARNING\s-\sUnexpected response from host/socket on port [0-9]+/'; +my $failedExpect = '/\sUnexpected response from host/socket on port [0-9]+/'; my $t; $tests = $tests - 4 if $internet_access eq "no"; plan tests => $tests; -$t += checkCmd( "./check_tcp $host_tcp_http -p 80 -wt 300 -ct 600", 0, $successOutput ); -$t += checkCmd( "./check_tcp $host_tcp_http -p 81 -wt 0 -ct 0 -to 1", 2 ); # use invalid port for this test -$t += checkCmd( "./check_tcp $host_nonresponsive -p 80 -wt 0 -ct 0 -to 1", 2 ); -$t += checkCmd( "./check_tcp $hostname_invalid -p 80 -wt 0 -ct 0 -to 1", 2 ); +$t += checkCmd( "./check_tcp $host_tcp_http -p 80 -w 300 -c 600", 0, $successOutput ); +$t += checkCmd( "./check_tcp $host_tcp_http -p 81 -w 0 -c 0 -t 1", 2 ); # use invalid port for this test +$t += checkCmd( "./check_tcp $host_nonresponsive -p 80 -w 0 -c 0 -t 1", 2 ); +$t += checkCmd( "./check_tcp $hostname_invalid -p 80 -w 0 -c 0 -t 1", 2 ); if($internet_access ne "no") { $t += checkCmd( "./check_tcp -S -D 1 -H $host_tls_http -p 443", 0 ); $t += checkCmd( "./check_tcp -S -D 9000,1 -H $host_tls_http -p 443", 1 ); -- cgit v1.2.3-74-g34f1 From fa4a03e1a80d3de8c85172834326d51b936f316a Mon Sep 17 00:00:00 2001 From: Lorenz Kästle <12514511+RincewindsHat@users.noreply.github.com> Date: Thu, 13 Mar 2025 00:49:16 +0100 Subject: use new output picker --- plugins/check_tcp.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'plugins') diff --git a/plugins/check_tcp.c b/plugins/check_tcp.c index 793cfe7e..2cc6c398 100644 --- a/plugins/check_tcp.c +++ b/plugins/check_tcp.c @@ -28,6 +28,7 @@ *****************************************************************************/ /* progname "check_tcp" changes depending on symlink called */ +#include "output.h" char *progname; const char *copyright = "1999-2025"; const char *email = "devel@monitoring-plugins.org"; @@ -230,7 +231,7 @@ int main(int argc, char **argv) { // Initialize check stuff before setting timers mp_check overall = mp_check_init(); if (config.output_format_set) { - overall.format = config.output_format; + mp_set_format(config.output_format); } /* set up the timer */ -- cgit v1.2.3-74-g34f1 From a2e9ade442bb93d632d7ef5b734103b4e1e4b07a Mon Sep 17 00:00:00 2001 From: Lorenz Kästle <12514511+RincewindsHat@users.noreply.github.com> Date: Thu, 13 Mar 2025 00:50:51 +0100 Subject: Fix typo --- plugins/check_tcp.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'plugins') diff --git a/plugins/check_tcp.c b/plugins/check_tcp.c index 2cc6c398..2878fd60 100644 --- a/plugins/check_tcp.c +++ b/plugins/check_tcp.c @@ -265,7 +265,7 @@ int main(int argc, char **argv) { tls_connection_result = mp_set_subcheck_state(tls_connection_result, result); if (result == STATE_OK) { - xasprintf(&tls_connection_result.output, "TLS connection succeded"); + xasprintf(&tls_connection_result.output, "TLS connection succeeded"); if (config.check_cert) { result = np_net_ssl_check_cert(config.days_till_exp_warn, config.days_till_exp_crit); -- cgit v1.2.3-74-g34f1 From 4dd024388e1f8be894e50dd0eb74d5c9f86b4233 Mon Sep 17 00:00:00 2001 From: Lorenz Kästle <12514511+RincewindsHat@users.noreply.github.com> Date: Thu, 13 Mar 2025 11:37:20 +0100 Subject: check_tcp: small cleanup --- plugins/check_tcp.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) (limited to 'plugins') diff --git a/plugins/check_tcp.c b/plugins/check_tcp.c index 2878fd60..833cdc0c 100644 --- a/plugins/check_tcp.c +++ b/plugins/check_tcp.c @@ -28,7 +28,6 @@ *****************************************************************************/ /* progname "check_tcp" changes depending on symlink called */ -#include "output.h" char *progname; const char *copyright = "1999-2025"; const char *email = "devel@monitoring-plugins.org"; @@ -37,6 +36,7 @@ const char *email = "devel@monitoring-plugins.org"; #include "./netutils.h" #include "./utils.h" #include "./check_tcp.d/config.h" +#include "output.h" #include "states.h" #include @@ -59,12 +59,10 @@ ssize_t my_send(char *buf, size_t len) { #endif // HAVE_SSL } -typedef struct process_arguments_wrapper { +typedef struct { int errorcode; check_tcp_config config; } check_tcp_config_wrapper; - -/* int my_recv(char *, size_t); */ static check_tcp_config_wrapper process_arguments(int /*argc*/, char ** /*argv*/, check_tcp_config /*config*/); void print_help(const char *service); void print_usage(void); -- cgit v1.2.3-74-g34f1 From be4618bf6429bddbd9208a88f460c028074fe8c0 Mon Sep 17 00:00:00 2001 From: Lorenz Kästle <12514511+RincewindsHat@users.noreply.github.com> Date: Thu, 13 Mar 2025 11:37:52 +0100 Subject: check_tcp: patch backwards compatibility in again --- plugins/check_tcp.c | 11 +++++++++++ 1 file changed, 11 insertions(+) (limited to 'plugins') diff --git a/plugins/check_tcp.c b/plugins/check_tcp.c index 833cdc0c..d2ebc16d 100644 --- a/plugins/check_tcp.c +++ b/plugins/check_tcp.c @@ -493,6 +493,17 @@ static check_tcp_config_wrapper process_arguments(int argc, char **argv, check_t usage4(_("No arguments found")); } + /* backwards compatibility */ + for (int i = 1; i < argc; i++) { + if (strcmp("-to", argv[i]) == 0) { + strcpy(argv[i], "-t"); + } else if (strcmp("-wt", argv[i]) == 0) { + strcpy(argv[i], "-w"); + } else if (strcmp("-ct", argv[i]) == 0) { + strcpy(argv[i], "-c"); + } + } + if (!is_option(argv[1])) { config.server_address = argv[1]; argv[1] = argv[0]; -- cgit v1.2.3-74-g34f1 From a693cc0aa3d79f85115be48bcd81c0ec371e78a0 Mon Sep 17 00:00:00 2001 From: Lorenz Kästle <12514511+RincewindsHat@users.noreply.github.com> Date: Thu, 13 Mar 2025 12:24:45 +0100 Subject: Fix TLS/non-TLS send/recv logic --- plugins/check_tcp.c | 45 ++++++++++++++++++++++++--------------------- 1 file changed, 24 insertions(+), 21 deletions(-) (limited to 'plugins') diff --git a/plugins/check_tcp.c b/plugins/check_tcp.c index d2ebc16d..8cd86460 100644 --- a/plugins/check_tcp.c +++ b/plugins/check_tcp.c @@ -43,20 +43,22 @@ const char *email = "devel@monitoring-plugins.org"; #include #include -ssize_t my_recv(char *buf, size_t len) { +ssize_t my_recv(int socket_descriptor, char *buf, size_t len, bool use_tls) { #ifdef HAVE_SSL - return np_net_ssl_read(buf, (int)len); -#else + if (use_tls) { + return np_net_ssl_read(buf, (int)len); + } +#endif return read(socket_descriptor, buf, len); -#endif // HAVE_SSL } -ssize_t my_send(char *buf, size_t len) { +ssize_t my_send(int socket_descriptor, char *buf, size_t len, bool use_tls) { #ifdef HAVE_SSL - return np_net_ssl_write(buf, (int)len); -#else + if (use_tls) { + return np_net_ssl_write(buf, (int)len); + } +#endif return write(socket_descriptor, buf, len); -#endif // HAVE_SSL } typedef struct { @@ -302,7 +304,7 @@ int main(int argc, char **argv) { #endif /* HAVE_SSL */ if (config.send != NULL) { /* Something to send? */ - my_send(config.send, strlen(config.send)); + my_send(socket_descriptor, config.send, strlen(config.send), config.use_tls); } if (config.delay > 0) { @@ -325,8 +327,8 @@ int main(int argc, char **argv) { /* if(len) later on, we know we have a non-NULL response */ ssize_t len = 0; - char *status = NULL; - int match = -1; + char *received_buffer = NULL; + enum np_match_result match = NP_MATCH_NONE; mp_subcheck expected_data_result = mp_subcheck_init(); if (config.server_expect_count) { @@ -334,23 +336,24 @@ int main(int argc, char **argv) { char buffer[MAXBUF]; /* watch for the expect string */ - while ((received = my_recv(buffer, sizeof(buffer))) > 0) { - status = realloc(status, len + received + 1); + while ((received = my_recv(socket_descriptor, buffer, sizeof(buffer), config.use_tls)) > 0) { + received_buffer = realloc(received_buffer, len + received + 1); - if (status == NULL) { + if (received_buffer == NULL) { die(STATE_UNKNOWN, _("Allocation failed")); } - memcpy(&status[len], buffer, received); + memcpy(&received_buffer[len], buffer, received); len += received; - status[len] = '\0'; + received_buffer[len] = '\0'; /* stop reading if user-forced */ if (config.maxbytes && len >= config.maxbytes) { break; } - if ((match = np_expect_match(status, config.server_expect, config.server_expect_count, config.match_flags)) != NP_MATCH_RETRY) { + if ((match = np_expect_match(received_buffer, config.server_expect, config.server_expect_count, config.match_flags)) != + NP_MATCH_RETRY) { break; } @@ -382,16 +385,16 @@ int main(int argc, char **argv) { /* print raw output if we're debugging */ if (verbosity > 0) { - printf("received %d bytes from host\n#-raw-recv-------#\n%s\n#-raw-recv-------#\n", (int)len + 1, status); + printf("received %d bytes from host\n#-raw-recv-------#\n%s\n#-raw-recv-------#\n", (int)len + 1, received_buffer); } /* strip whitespace from end of output */ - while (--len > 0 && isspace(status[len])) { - status[len] = '\0'; + while (--len > 0 && isspace(received_buffer[len])) { + received_buffer[len] = '\0'; } } if (config.quit != NULL) { - my_send(config.quit, strlen(config.quit)); + my_send(socket_descriptor, config.quit, strlen(config.quit), config.use_tls); } if (socket_descriptor) { -- cgit v1.2.3-74-g34f1 From c8014631de0f7927d8c75ff87225b5a24e9b9942 Mon Sep 17 00:00:00 2001 From: Lorenz Kästle <12514511+RincewindsHat@users.noreply.github.com> Date: Thu, 13 Mar 2025 12:25:29 +0100 Subject: check_tcp: add output if answer matches expectations --- plugins/check_tcp.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'plugins') diff --git a/plugins/check_tcp.c b/plugins/check_tcp.c index 8cd86460..d1f6b84f 100644 --- a/plugins/check_tcp.c +++ b/plugins/check_tcp.c @@ -261,7 +261,7 @@ int main(int argc, char **argv) { #ifdef HAVE_SSL if (config.use_tls) { mp_subcheck tls_connection_result = mp_subcheck_init(); - int result = np_net_ssl_init_with_hostname(socket_descriptor, (config.sni_specified ? config.sni : NULL)); + mp_state_enum result = np_net_ssl_init_with_hostname(socket_descriptor, (config.sni_specified ? config.sni : NULL)); tls_connection_result = mp_set_subcheck_state(tls_connection_result, result); if (result == STATE_OK) { @@ -448,6 +448,10 @@ int main(int argc, char **argv) { expected_data_result = mp_set_subcheck_state(expected_data_result, config.expect_mismatch_state); xasprintf(&expected_data_result.output, "Answer failed to match expectation"); mp_add_subcheck_to_check(&overall, expected_data_result); + } else if (match == NP_MATCH_SUCCESS) { + expected_data_result = mp_set_subcheck_state(expected_data_result, STATE_OK); + xasprintf(&expected_data_result.output, "The answer of the server matched the expectation"); + mp_add_subcheck_to_check(&overall, expected_data_result); } /* reset the alarm */ -- cgit v1.2.3-74-g34f1 From 44211a672959494849476c45ff761181e62762ff Mon Sep 17 00:00:00 2001 From: Lorenz Kästle <12514511+RincewindsHat@users.noreply.github.com> Date: Thu, 13 Mar 2025 12:59:40 +0100 Subject: Adapt tests more --- plugins/t/check_ftp.t | 2 +- plugins/t/check_jabber.t | 4 ++-- plugins/t/check_udp.t | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) (limited to 'plugins') diff --git a/plugins/t/check_ftp.t b/plugins/t/check_ftp.t index 93a7d7c3..a2f79dca 100644 --- a/plugins/t/check_ftp.t +++ b/plugins/t/check_ftp.t @@ -15,7 +15,7 @@ my $host_tcp_ftp = getTestParameter("NP_HOST_TCP_FTP", "A host providing t my $host_nonresponsive = getTestParameter("NP_HOST_NONRESPONSIVE", "The hostname of system not responsive to network requests", "10.0.0.1"); my $hostname_invalid = getTestParameter("NP_HOSTNAME_INVALID", "An invalid (not known to DNS) hostname", "nosuchhost"); -my $successOutput = '/FTP OK -\s+[0-9]?\.?[0-9]+ second response time/'; +my $successOutput = '/Connection time\s+[0-9]?\.?[0-9]+/'; my $t; diff --git a/plugins/t/check_jabber.t b/plugins/t/check_jabber.t index 08cadcbd..dc46f4c3 100644 --- a/plugins/t/check_jabber.t +++ b/plugins/t/check_jabber.t @@ -15,11 +15,11 @@ my $host_nonresponsive = getTestParameter("NP_HOST_NONRESPONSIVE", "The hostname my $hostname_invalid = getTestParameter("NP_HOSTNAME_INVALID", "An invalid (not known to DNS) hostname", "nosuchhost"); -my $jabberOK = '/JABBER OK\s-\s\d+\.\d+\ssecond response time on '.$host_tcp_jabber.' port 5222/'; +my $jabberOK = '/Connection to '.$host_tcp_jabber.' on port 5222/'; my $jabberUnresponsive = '/Socket timeout after\s\d+\sseconds/'; -my $jabberInvalid = '/JABBER CRITICAL - Invalid hostname, address or socket:\s.+/'; +my $jabberInvalid = '/Invalid hostname, address or socket:\s.+/'; my $r; diff --git a/plugins/t/check_udp.t b/plugins/t/check_udp.t index 6c47d095..5cb9e6dc 100644 --- a/plugins/t/check_udp.t +++ b/plugins/t/check_udp.t @@ -28,7 +28,7 @@ like ( $res->output, '/With UDP checks, a send/expect string must be specified. $res = NPTest->testCmd( "./check_udp -H localhost -p 3333 -s foo -e bar" ); cmp_ok( $res->return_code, '==', 2, "Errors correctly because no udp service running" ); -like ( $res->output, '/No data received from host/', "Output OK"); +like ( $res->output, '/Received no data /', "Output OK"); my $nc; if(system("which nc.traditional >/dev/null 2>&1") == 0) { @@ -48,7 +48,7 @@ SKIP: { sleep 1; $res = NPTest->testCmd( "./check_udp -H localhost -p 3333 -s '' -e barbar -4" ); cmp_ok( $res->return_code, '==', 0, "Got barbar response back" ); - like ( $res->output, '/\[barbar\]/', "Output OK"); + like ( $res->output, '/answer of the server matched/', "Output OK"); close NC; # Start up a udp server listening on port 3333, quit after 3 seconds -- cgit v1.2.3-74-g34f1 From 285000a2ad1198046275f5bd5b47227f1cd66471 Mon Sep 17 00:00:00 2001 From: Lorenz Kästle <12514511+RincewindsHat@users.noreply.github.com> Date: Thu, 13 Mar 2025 13:00:05 +0100 Subject: small fixes to check_tcp config --- plugins/check_tcp.d/config.h | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) (limited to 'plugins') diff --git a/plugins/check_tcp.d/config.h b/plugins/check_tcp.d/config.h index 41db7224..dc25d79e 100644 --- a/plugins/check_tcp.d/config.h +++ b/plugins/check_tcp.d/config.h @@ -2,6 +2,7 @@ #include "../../lib/utils_tcp.h" #include "output.h" +#include "states.h" #include typedef struct { @@ -15,8 +16,8 @@ typedef struct { char *quit; char **server_expect; size_t server_expect_count; -#ifdef HAVE_SSL bool use_tls; +#ifdef HAVE_SSL char *sni; bool sni_specified; bool check_cert; @@ -24,7 +25,7 @@ typedef struct { int days_till_exp_crit; #endif // HAVE_SSL int match_flags; - int expect_mismatch_state; + mp_state_enum expect_mismatch_state; unsigned int delay; bool warning_time_set; @@ -32,7 +33,7 @@ typedef struct { bool critical_time_set; double critical_time; - int econn_refuse_state; + mp_state_enum econn_refuse_state; ssize_t maxbytes; @@ -54,8 +55,8 @@ check_tcp_config check_tcp_config_init() { .quit = NULL, .server_expect = NULL, .server_expect_count = 0, -#ifdef HAVE_SSL .use_tls = false, +#ifdef HAVE_SSL .sni = NULL, .sni_specified = false, .check_cert = false, -- cgit v1.2.3-74-g34f1 From c61b5ef06a83b5fa2d48b256532f30ec5def3658 Mon Sep 17 00:00:00 2001 From: Lorenz Kästle <12514511+RincewindsHat@users.noreply.github.com> Date: Thu, 13 Mar 2025 13:21:10 +0100 Subject: Update more tests to current output --- plugins/t/check_tcp.t | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'plugins') diff --git a/plugins/t/check_tcp.t b/plugins/t/check_tcp.t index b47caab3..5c8fd0be 100644 --- a/plugins/t/check_tcp.t +++ b/plugins/t/check_tcp.t @@ -23,7 +23,7 @@ my $internet_access = getTestParameter("NP_INTERNET_ACCESS", "Is this system my $successOutput = '/Connection time\s+[0-9]?\.?[0-9]+s is within thresholds+/'; -my $failedExpect = '/\sUnexpected response from host/socket on port [0-9]+/'; +my $failedExpect = '/Answer failed to match/'; my $t; -- cgit v1.2.3-74-g34f1 From 0111359c72e2fc13049b5c33a7e1449cd0cdf666 Mon Sep 17 00:00:00 2001 From: Lorenz Kästle <12514511+RincewindsHat@users.noreply.github.com> Date: Thu, 13 Mar 2025 14:48:20 +0100 Subject: check_tcp: Actually account for certificate lifetime checks --- plugins/check_tcp.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'plugins') diff --git a/plugins/check_tcp.c b/plugins/check_tcp.c index d1f6b84f..22dcc74e 100644 --- a/plugins/check_tcp.c +++ b/plugins/check_tcp.c @@ -262,7 +262,7 @@ int main(int argc, char **argv) { if (config.use_tls) { mp_subcheck tls_connection_result = mp_subcheck_init(); mp_state_enum result = np_net_ssl_init_with_hostname(socket_descriptor, (config.sni_specified ? config.sni : NULL)); - tls_connection_result = mp_set_subcheck_state(tls_connection_result, result); + tls_connection_result = mp_set_subcheck_default_state(tls_connection_result, result); if (result == STATE_OK) { xasprintf(&tls_connection_result.output, "TLS connection succeeded"); -- cgit v1.2.3-74-g34f1 From d2596feaa090c73353412d252cfb7938a9141f9b Mon Sep 17 00:00:00 2001 From: Lorenz Kästle <12514511+RincewindsHat@users.noreply.github.com> Date: Thu, 13 Mar 2025 14:59:35 +0100 Subject: Add forgotten Makefile change --- plugins/Makefile.am | 1 + 1 file changed, 1 insertion(+) (limited to 'plugins') diff --git a/plugins/Makefile.am b/plugins/Makefile.am index 9e4924c3..30ca63d1 100644 --- a/plugins/Makefile.am +++ b/plugins/Makefile.am @@ -58,6 +58,7 @@ EXTRA_DIST = t \ check_time.d \ check_nagios.d \ check_dbi.d \ + check_tcp.d \ check_real.d \ check_ssh.d \ check_nt.d \ -- cgit v1.2.3-74-g34f1 From f2900e0ccf18f321857e4072681ad9c10a0cb67f Mon Sep 17 00:00:00 2001 From: Lorenz Kästle <12514511+RincewindsHat@users.noreply.github.com> Date: Thu, 13 Mar 2025 15:36:36 +0100 Subject: check_load: clang-format --- plugins/check_load.c | 330 +++++++++++++++++++++++++-------------------------- 1 file changed, 162 insertions(+), 168 deletions(-) (limited to 'plugins') diff --git a/plugins/check_load.c b/plugins/check_load.c index 1431d130..e3a45f58 100644 --- a/plugins/check_load.c +++ b/plugins/check_load.c @@ -1,32 +1,32 @@ /***************************************************************************** -* -* Monitoring check_load plugin -* -* License: GPL -* Copyright (c) 1999-2007 Monitoring Plugins Development Team -* -* Description: -* -* This file contains the check_load plugin -* -* This plugin tests the current system load average. -* -* -* 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_load plugin + * + * License: GPL + * Copyright (c) 1999-2007 Monitoring Plugins Development Team + * + * Description: + * + * This file contains the check_load plugin + * + * This plugin tests the current system load average. + * + * + * 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_load"; const char *copyright = "1999-2022"; @@ -40,127 +40,129 @@ const char *email = "devel@monitoring-plugins.org"; #include #ifdef HAVE_SYS_LOADAVG_H -#include +# include #endif /* needed for compilation under NetBSD, as suggested by Andy Doran */ #ifndef LOADAVG_1MIN -#define LOADAVG_1MIN 0 -#define LOADAVG_5MIN 1 -#define LOADAVG_15MIN 2 +# define LOADAVG_1MIN 0 +# define LOADAVG_5MIN 1 +# define LOADAVG_15MIN 2 #endif /* !defined LOADAVG_1MIN */ - -static int process_arguments (int argc, char **argv); -static int validate_arguments (void); -void print_help (void); -void print_usage (void); +static int process_arguments(int argc, char **argv); +static int validate_arguments(void); +void print_help(void); +void print_usage(void); static int print_top_consuming_processes(); static int n_procs_to_show = 0; /* strictly for pretty-print usage in loops */ -static const int nums[3] = { 1, 5, 15 }; +static const int nums[3] = {1, 5, 15}; /* provide some fairly sane defaults */ -double wload[3] = { 0.0, 0.0, 0.0 }; -double cload[3] = { 0.0, 0.0, 0.0 }; -#define la1 la[0] -#define la5 la[1] +double wload[3] = {0.0, 0.0, 0.0}; +double cload[3] = {0.0, 0.0, 0.0}; +#define la1 la[0] +#define la5 la[1] #define la15 la[2] char *status_line; bool take_into_account_cpus = false; -static void -get_threshold(char *arg, double *th) -{ +static void get_threshold(char *arg, double *th) { size_t i, n; int valid = 0; char *str = arg, *p; n = strlen(arg); - for(i = 0; i < 3; i++) { + for (i = 0; i < 3; i++) { th[i] = strtod(str, &p); - if(p == str) break; + if (p == str) { + break; + } valid = 1; str = p + 1; - if(n <= (size_t)(str - arg)) break; + if (n <= (size_t)(str - arg)) { + break; + } } /* empty argument or non-floatish, so warn about it and die */ - if(!i && !valid) usage (_("Warning threshold must be float or float triplet!\n")); + if (!i && !valid) { + usage(_("Warning threshold must be float or float triplet!\n")); + } - if(i != 2) { + if (i != 2) { /* one or more numbers were given, so fill array with last * we got (most likely to NOT produce the least expected result) */ - for(n = i; n < 3; n++) th[n] = th[i]; + for (n = i; n < 3; n++) { + th[n] = th[i]; + } } } - -int -main (int argc, char **argv) -{ +int main(int argc, char **argv) { int result = -1; int i; long numcpus; - double la[3] = { 0.0, 0.0, 0.0 }; /* NetBSD complains about uninitialized arrays */ + double la[3] = {0.0, 0.0, 0.0}; /* NetBSD complains about uninitialized arrays */ #ifndef HAVE_GETLOADAVG char input_buffer[MAX_INPUT_BUFFER]; #endif - setlocale (LC_ALL, ""); - bindtextdomain (PACKAGE, LOCALEDIR); - textdomain (PACKAGE); + setlocale(LC_ALL, ""); + bindtextdomain(PACKAGE, LOCALEDIR); + textdomain(PACKAGE); setlocale(LC_NUMERIC, "POSIX"); /* 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")); + } #ifdef HAVE_GETLOADAVG - result = getloadavg (la, 3); - if (result != 3) + result = getloadavg(la, 3); + if (result != 3) { return STATE_UNKNOWN; + } #else - child_process = spopen (PATH_TO_UPTIME); + child_process = spopen(PATH_TO_UPTIME); if (child_process == NULL) { - printf (_("Error opening %s\n"), PATH_TO_UPTIME); + printf(_("Error opening %s\n"), PATH_TO_UPTIME); return STATE_UNKNOWN; } - child_stderr = fdopen (child_stderr_array[fileno (child_process)], "r"); + child_stderr = fdopen(child_stderr_array[fileno(child_process)], "r"); if (child_stderr == NULL) { - printf (_("Could not open stderr for %s\n"), PATH_TO_UPTIME); + printf(_("Could not open stderr for %s\n"), PATH_TO_UPTIME); } - fgets (input_buffer, MAX_INPUT_BUFFER - 1, child_process); - if(strstr(input_buffer, "load average:")) { - sscanf (input_buffer, "%*[^l]load average: %lf, %lf, %lf", &la1, &la5, &la15); - } - else if(strstr(input_buffer, "load averages:")) { - sscanf (input_buffer, "%*[^l]load averages: %lf, %lf, %lf", &la1, &la5, &la15); - } - else { - printf (_("could not parse load from uptime %s: %d\n"), PATH_TO_UPTIME, result); + fgets(input_buffer, MAX_INPUT_BUFFER - 1, child_process); + if (strstr(input_buffer, "load average:")) { + sscanf(input_buffer, "%*[^l]load average: %lf, %lf, %lf", &la1, &la5, &la15); + } else if (strstr(input_buffer, "load averages:")) { + sscanf(input_buffer, "%*[^l]load averages: %lf, %lf, %lf", &la1, &la5, &la15); + } else { + printf(_("could not parse load from uptime %s: %d\n"), PATH_TO_UPTIME, result); return STATE_UNKNOWN; - } + } - result = spclose (child_process); + result = spclose(child_process); if (result) { - printf (_("Error code %d returned in %s\n"), result, PATH_TO_UPTIME); + printf(_("Error code %d returned in %s\n"), result, PATH_TO_UPTIME); return STATE_UNKNOWN; } #endif if ((la[0] < 0.0) || (la[1] < 0.0) || (la[2] < 0.0)) { #ifdef HAVE_GETLOADAVG - printf (_("Error in getloadavg()\n")); + printf(_("Error in getloadavg()\n")); #else - printf (_("Error processing %s\n"), PATH_TO_UPTIME); + printf(_("Error processing %s\n"), PATH_TO_UPTIME); #endif return STATE_UNKNOWN; } @@ -171,8 +173,7 @@ main (int argc, char **argv) xasprintf(&status_line, _("load average: %.2f, %.2f, %.2f"), la1, la5, la15); xasprintf(&status_line, ("total %s"), status_line); - - double scaled_la[3] = { 0.0, 0.0, 0.0 }; + double scaled_la[3] = {0.0, 0.0, 0.0}; bool is_using_scaled_load_values = false; if (take_into_account_cpus == true && (numcpus = GET_NUMBER_OF_CPUS()) > 0) { @@ -187,24 +188,26 @@ main (int argc, char **argv) xasprintf(&status_line, "scaled %s - %s", tmp, status_line); } - for(i = 0; i < 3; i++) { + for (i = 0; i < 3; i++) { if (is_using_scaled_load_values) { - if(scaled_la[i] > cload[i]) { + if (scaled_la[i] > cload[i]) { result = STATE_CRITICAL; break; + } else if (scaled_la[i] > wload[i]) { + result = STATE_WARNING; } - else if(scaled_la[i] > wload[i]) result = STATE_WARNING; } else { - if(la[i] > cload[i]) { + if (la[i] > cload[i]) { result = STATE_CRITICAL; break; + } else if (la[i] > wload[i]) { + result = STATE_WARNING; } - else if(la[i] > wload[i]) result = STATE_WARNING; } } printf("LOAD %s - %s|", state_text(result), status_line); - for(i = 0; i < 3; i++) { + for (i = 0; i < 3; i++) { if (is_using_scaled_load_values) { printf("load%d=%.3f;;;0; ", nums[i], la[i]); printf("scaled_load%d=%.3f;%.3f;%.3f;0; ", nums[i], scaled_la[i], wload[i], cload[i]); @@ -220,32 +223,29 @@ main (int argc, char **argv) return result; } - /* process command-line arguments */ -static int -process_arguments (int argc, char **argv) -{ +static int process_arguments(int argc, char **argv) { int c = 0; int option = 0; - static struct option longopts[] = { - {"warning", required_argument, 0, 'w'}, - {"critical", required_argument, 0, 'c'}, - {"percpu", no_argument, 0, 'r'}, - {"version", no_argument, 0, 'V'}, - {"help", no_argument, 0, 'h'}, - {"procs-to-show", required_argument, 0, 'n'}, - {0, 0, 0, 0} - }; - - if (argc < 2) + static struct option longopts[] = {{"warning", required_argument, 0, 'w'}, + {"critical", required_argument, 0, 'c'}, + {"percpu", no_argument, 0, 'r'}, + {"version", no_argument, 0, 'V'}, + {"help", no_argument, 0, 'h'}, + {"procs-to-show", required_argument, 0, 'n'}, + {0, 0, 0, 0}}; + + if (argc < 2) { return ERROR; + } while (1) { - c = getopt_long (argc, argv, "Vhrc:w:n:", longopts, &option); + c = getopt_long(argc, argv, "Vhrc:w:n:", longopts, &option); - if (c == -1 || c == EOF) + if (c == -1 || c == EOF) { break; + } switch (c) { case 'w': /* warning time threshold */ @@ -257,94 +257,89 @@ process_arguments (int argc, char **argv) case 'r': /* Divide load average by number of CPUs */ take_into_account_cpus = true; 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 'n': n_procs_to_show = atoi(optarg); break; - case '?': /* help */ - usage5 (); + case '?': /* help */ + usage5(); } } c = optind; - if (c == argc) - return validate_arguments (); + if (c == argc) { + return validate_arguments(); + } /* handle the case if both arguments are missing, * but not if only one is given without -c or -w flag */ - if(c - argc == 2) { + if (c - argc == 2) { get_threshold(argv[c++], wload); get_threshold(argv[c++], cload); - } - else if(c - argc == 1) { + } else if (c - argc == 1) { get_threshold(argv[c++], cload); } - return validate_arguments (); + return validate_arguments(); } - -static int -validate_arguments (void) -{ +static int validate_arguments(void) { int i = 0; /* match cload first, as it will give the most friendly error message * if user hasn't given the -c switch properly */ - for(i = 0; i < 3; i++) { - if(cload[i] < 0) - die (STATE_UNKNOWN, _("Critical threshold for %d-minute load average is not specified\n"), nums[i]); - if(wload[i] < 0) - die (STATE_UNKNOWN, _("Warning threshold for %d-minute load average is not specified\n"), nums[i]); - if(wload[i] > cload[i]) - die (STATE_UNKNOWN, _("Parameter inconsistency: %d-minute \"warning load\" is greater than \"critical load\"\n"), nums[i]); + for (i = 0; i < 3; i++) { + if (cload[i] < 0) { + die(STATE_UNKNOWN, _("Critical threshold for %d-minute load average is not specified\n"), nums[i]); + } + if (wload[i] < 0) { + die(STATE_UNKNOWN, _("Warning threshold for %d-minute load average is not specified\n"), nums[i]); + } + if (wload[i] > cload[i]) { + die(STATE_UNKNOWN, _("Parameter inconsistency: %d-minute \"warning load\" is greater than \"critical load\"\n"), nums[i]); + } } return OK; } +void print_help(void) { + print_revision(progname, NP_VERSION); -void -print_help (void) -{ - print_revision (progname, NP_VERSION); - - printf ("Copyright (c) 1999 Felipe Gustavo de Almeida \n"); - printf (COPYRIGHT, copyright, email); + printf("Copyright (c) 1999 Felipe Gustavo de Almeida \n"); + printf(COPYRIGHT, copyright, email); - printf (_("This plugin tests the current system load average.")); + printf(_("This plugin tests the current system load average.")); - 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 (" %s\n", "-w, --warning=WLOAD1,WLOAD5,WLOAD15"); - printf (" %s\n", _("Exit with WARNING status if load average exceeds WLOADn")); - printf (" %s\n", "-c, --critical=CLOAD1,CLOAD5,CLOAD15"); - printf (" %s\n", _("Exit with CRITICAL status if load average exceed CLOADn")); - printf (" %s\n", _("the load average format is the same used by \"uptime\" and \"w\"")); - printf (" %s\n", "-r, --percpu"); - printf (" %s\n", _("Divide the load averages by the number of CPUs (when possible)")); - printf (" %s\n", "-n, --procs-to-show=NUMBER_OF_PROCS"); - printf (" %s\n", _("Number of processes to show when printing the top consuming processes.")); - printf (" %s\n", _("NUMBER_OF_PROCS=0 disables this feature. Default value is 0")); + printf(" %s\n", "-w, --warning=WLOAD1,WLOAD5,WLOAD15"); + printf(" %s\n", _("Exit with WARNING status if load average exceeds WLOADn")); + printf(" %s\n", "-c, --critical=CLOAD1,CLOAD5,CLOAD15"); + printf(" %s\n", _("Exit with CRITICAL status if load average exceed CLOADn")); + printf(" %s\n", _("the load average format is the same used by \"uptime\" and \"w\"")); + printf(" %s\n", "-r, --percpu"); + printf(" %s\n", _("Divide the load averages by the number of CPUs (when possible)")); + printf(" %s\n", "-n, --procs-to-show=NUMBER_OF_PROCS"); + printf(" %s\n", _("Number of processes to show when printing the top consuming processes.")); + printf(" %s\n", _("NUMBER_OF_PROCS=0 disables this feature. Default value is 0")); - printf (UT_SUPPORT); + printf(UT_SUPPORT); } -void -print_usage (void) -{ - printf ("%s\n", _("Usage:")); - printf ("%s [-r] -w WLOAD1,WLOAD5,WLOAD15 -c CLOAD1,CLOAD5,CLOAD15 [-n NUMBER_OF_PROCS]\n", progname); +void print_usage(void) { + printf("%s\n", _("Usage:")); + printf("%s [-r] -w WLOAD1,WLOAD5,WLOAD15 -c CLOAD1,CLOAD5,CLOAD15 [-n NUMBER_OF_PROCS]\n", progname); } #ifdef PS_USES_PROCPCPU @@ -356,14 +351,14 @@ int cmpstringp(const void *p1, const void *p2) { int procrss = 0; float procpcpu = 0; char procstat[8]; -#ifdef PS_USES_PROCETIME +# ifdef PS_USES_PROCETIME char procetime[MAX_INPUT_BUFFER]; -#endif /* PS_USES_PROCETIME */ +# endif /* PS_USES_PROCETIME */ char procprog[MAX_INPUT_BUFFER]; int pos; - sscanf (* (char * const *) p1, PS_FORMAT, PS_VARLIST); + sscanf(*(char *const *)p1, PS_FORMAT, PS_VARLIST); float procpcpu1 = procpcpu; - sscanf (* (char * const *) p2, PS_FORMAT, PS_VARLIST); + sscanf(*(char *const *)p2, PS_FORMAT, PS_VARLIST); return procpcpu1 < procpcpu; } #endif /* PS_USES_PROCPCPU */ @@ -371,7 +366,7 @@ int cmpstringp(const void *p1, const void *p2) { static int print_top_consuming_processes() { int i = 0; struct output chld_out, chld_err; - if(np_runcmd(PS_COMMAND, &chld_out, &chld_err, 0) != 0){ + if (np_runcmd(PS_COMMAND, &chld_out, &chld_err, 0) != 0) { fprintf(stderr, _("'%s' exited with non-zero status.\n"), PS_COMMAND); return STATE_UNKNOWN; } @@ -380,10 +375,9 @@ static int print_top_consuming_processes() { return STATE_UNKNOWN; } #ifdef PS_USES_PROCPCPU - qsort(chld_out.line + 1, chld_out.lines - 1, sizeof(char*), cmpstringp); + qsort(chld_out.line + 1, chld_out.lines - 1, sizeof(char *), cmpstringp); #endif /* PS_USES_PROCPCPU */ - int lines_to_show = chld_out.lines < (size_t)(n_procs_to_show + 1) - ? (int)chld_out.lines : n_procs_to_show + 1; + int lines_to_show = chld_out.lines < (size_t)(n_procs_to_show + 1) ? (int)chld_out.lines : n_procs_to_show + 1; for (i = 0; i < lines_to_show; i += 1) { printf("%s\n", chld_out.line[i]); } -- cgit v1.2.3-74-g34f1 From 08a475a14fff2d0eee2e49f4765cb286cac8d2e2 Mon Sep 17 00:00:00 2001 From: Lorenz Kästle <12514511+RincewindsHat@users.noreply.github.com> Date: Thu, 13 Mar 2025 23:41:12 +0100 Subject: Refactor check_load + new ouput --- plugins/Makefile.am | 1 + plugins/check_load.c | 420 ++++++++++++++++++++++++------------------ plugins/check_load.d/config.h | 30 +++ 3 files changed, 274 insertions(+), 177 deletions(-) create mode 100644 plugins/check_load.d/config.h (limited to 'plugins') diff --git a/plugins/Makefile.am b/plugins/Makefile.am index 30ca63d1..f395e594 100644 --- a/plugins/Makefile.am +++ b/plugins/Makefile.am @@ -56,6 +56,7 @@ EXTRA_DIST = t \ check_game.d \ check_radius.d \ check_time.d \ + check_load.d \ check_nagios.d \ check_dbi.d \ check_tcp.d \ diff --git a/plugins/check_load.c b/plugins/check_load.c index e3a45f58..57be8c69 100644 --- a/plugins/check_load.c +++ b/plugins/check_load.c @@ -28,6 +28,9 @@ * *****************************************************************************/ +#include "output.h" +#include "perfdata.h" +#include "thresholds.h" const char *progname = "check_load"; const char *copyright = "1999-2022"; const char *email = "devel@monitoring-plugins.org"; @@ -36,6 +39,10 @@ const char *email = "devel@monitoring-plugins.org"; #include "./runcmd.h" #include "./utils.h" #include "./popen.h" +#include "states.h" +#include "check_load.d/config.h" + +#include "../gl/stdlib.h" #include @@ -50,70 +57,68 @@ const char *email = "devel@monitoring-plugins.org"; # define LOADAVG_15MIN 2 #endif /* !defined LOADAVG_1MIN */ -static int process_arguments(int argc, char **argv); -static int validate_arguments(void); +typedef struct { + int errorcode; + check_load_config config; +} check_load_config_wrapper; +static check_load_config_wrapper process_arguments(int argc, char **argv); +static check_load_config_wrapper validate_arguments(check_load_config_wrapper /*config_wrapper*/); + void print_help(void); void print_usage(void); -static int print_top_consuming_processes(); - -static int n_procs_to_show = 0; - -/* strictly for pretty-print usage in loops */ -static const int nums[3] = {1, 5, 15}; - -/* provide some fairly sane defaults */ -double wload[3] = {0.0, 0.0, 0.0}; -double cload[3] = {0.0, 0.0, 0.0}; -#define la1 la[0] -#define la5 la[1] -#define la15 la[2] - -char *status_line; -bool take_into_account_cpus = false; - -static void get_threshold(char *arg, double *th) { - size_t i, n; - int valid = 0; - char *str = arg, *p; - - n = strlen(arg); - for (i = 0; i < 3; i++) { - th[i] = strtod(str, &p); - if (p == str) { +typedef struct { + int errorcode; + char **top_processes; +} top_processes_result; +static top_processes_result print_top_consuming_processes(int /*n_procs_to_show*/); + +typedef struct { + mp_range load[3]; +} parsed_thresholds; +static parsed_thresholds get_threshold(char *arg) { + size_t index; + char *str = arg; + char *tmp_pointer; + bool valid = false; + + parsed_thresholds result = { + .load[0] = mp_range_init(), + .load[1] = mp_range_init(), + .load[2] = mp_range_init(), + }; + + size_t arg_length = strlen(arg); + for (index = 0; index < 3; index++) { + double tmp = strtod(str, &tmp_pointer); + if (tmp_pointer == str) { break; } - valid = 1; - str = p + 1; - if (n <= (size_t)(str - arg)) { + result.load[index] = mp_range_set_end(result.load[index], mp_create_pd_value(tmp)); + + valid = true; + str = tmp_pointer + 1; + if (arg_length <= (size_t)(str - arg)) { break; } } /* empty argument or non-floatish, so warn about it and die */ - if (!i && !valid) { + if (!index && !valid) { usage(_("Warning threshold must be float or float triplet!\n")); } - if (i != 2) { + if (index != 2) { /* one or more numbers were given, so fill array with last * we got (most likely to NOT produce the least expected result) */ - for (n = i; n < 3; n++) { - th[n] = th[i]; + for (size_t tmp_index = index; tmp_index < 3; tmp_index++) { + result.load[tmp_index] = result.load[index]; } } + return result; } int main(int argc, char **argv) { - int result = -1; - int i; - long numcpus; - - double la[3] = {0.0, 0.0, 0.0}; /* NetBSD complains about uninitialized arrays */ -#ifndef HAVE_GETLOADAVG - char input_buffer[MAX_INPUT_BUFFER]; -#endif - setlocale(LC_ALL, ""); bindtextdomain(PACKAGE, LOCALEDIR); textdomain(PACKAGE); @@ -122,112 +127,138 @@ 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_load_config_wrapper tmp_config = process_arguments(argc, argv); + if (tmp_config.errorcode == ERROR) { usage4(_("Could not parse arguments")); } -#ifdef HAVE_GETLOADAVG - result = getloadavg(la, 3); - if (result != 3) { - return STATE_UNKNOWN; - } -#else - child_process = spopen(PATH_TO_UPTIME); - if (child_process == NULL) { - printf(_("Error opening %s\n"), PATH_TO_UPTIME); - 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"), PATH_TO_UPTIME); - } - fgets(input_buffer, MAX_INPUT_BUFFER - 1, child_process); - if (strstr(input_buffer, "load average:")) { - sscanf(input_buffer, "%*[^l]load average: %lf, %lf, %lf", &la1, &la5, &la15); - } else if (strstr(input_buffer, "load averages:")) { - sscanf(input_buffer, "%*[^l]load averages: %lf, %lf, %lf", &la1, &la5, &la15); - } else { - printf(_("could not parse load from uptime %s: %d\n"), PATH_TO_UPTIME, result); - return STATE_UNKNOWN; - } + const check_load_config config = tmp_config.config; - result = spclose(child_process); - if (result) { - printf(_("Error code %d returned in %s\n"), result, PATH_TO_UPTIME); - return STATE_UNKNOWN; - } -#endif + double load_values[3] = {0, 0, 0}; - if ((la[0] < 0.0) || (la[1] < 0.0) || (la[2] < 0.0)) { -#ifdef HAVE_GETLOADAVG - printf(_("Error in getloadavg()\n")); -#else - printf(_("Error processing %s\n"), PATH_TO_UPTIME); -#endif - return STATE_UNKNOWN; + int error = getloadavg(load_values, 3); + if (error != 3) { + die(STATE_UNKNOWN, _("Failed to retrieve load values")); } - /* we got this far, so assume OK until we've measured */ - result = STATE_OK; - - xasprintf(&status_line, _("load average: %.2f, %.2f, %.2f"), la1, la5, la15); - xasprintf(&status_line, ("total %s"), status_line); + mp_check overall = mp_check_init(); + if (config.output_format_set) { + mp_set_format(config.output_format); + } - double scaled_la[3] = {0.0, 0.0, 0.0}; bool is_using_scaled_load_values = false; - - if (take_into_account_cpus == true && (numcpus = GET_NUMBER_OF_CPUS()) > 0) { + long numcpus; + if (config.take_into_account_cpus && ((numcpus = GET_NUMBER_OF_CPUS()) > 0)) { is_using_scaled_load_values = true; - scaled_la[0] = la[0] / numcpus; - scaled_la[1] = la[1] / numcpus; - scaled_la[2] = la[2] / numcpus; + double scaled_la[3] = {0.0, 0.0, 0.0}; + scaled_la[0] = load_values[0] / numcpus; + scaled_la[1] = load_values[1] / numcpus; + scaled_la[2] = load_values[2] / numcpus; + + mp_subcheck scaled_load_sc = mp_subcheck_init(); + scaled_load_sc = mp_set_subcheck_default_state(scaled_load_sc, STATE_OK); + scaled_load_sc.output = "Scaled Load (divided by number of CPUs"; + + mp_perfdata pd_scaled_load1 = perfdata_init(); + pd_scaled_load1.label = "scaled_load1"; + pd_scaled_load1 = mp_set_pd_value(pd_scaled_load1, scaled_la[0]); + pd_scaled_load1 = mp_pd_set_thresholds(pd_scaled_load1, config.th_load[0]); + + mp_subcheck scaled_load_sc1 = mp_subcheck_init(); + scaled_load_sc1 = mp_set_subcheck_state(scaled_load_sc1, mp_get_pd_status(pd_scaled_load1)); + mp_add_perfdata_to_subcheck(&scaled_load_sc1, pd_scaled_load1); + xasprintf(&scaled_load_sc1.output, "1 Minute: %s", pd_value_to_string(pd_scaled_load1.value)); + mp_add_subcheck_to_subcheck(&scaled_load_sc, scaled_load_sc1); + + mp_perfdata pd_scaled_load5 = perfdata_init(); + pd_scaled_load5.label = "scaled_load5"; + pd_scaled_load5 = mp_set_pd_value(pd_scaled_load5, scaled_la[1]); + pd_scaled_load5 = mp_pd_set_thresholds(pd_scaled_load5, config.th_load[1]); + + mp_subcheck scaled_load_sc5 = mp_subcheck_init(); + scaled_load_sc5 = mp_set_subcheck_state(scaled_load_sc5, mp_get_pd_status(pd_scaled_load5)); + mp_add_perfdata_to_subcheck(&scaled_load_sc5, pd_scaled_load5); + xasprintf(&scaled_load_sc5.output, "5 Minutes: %s", pd_value_to_string(pd_scaled_load5.value)); + mp_add_subcheck_to_subcheck(&scaled_load_sc, scaled_load_sc5); + + mp_perfdata pd_scaled_load15 = perfdata_init(); + pd_scaled_load15.label = "scaled_load15"; + pd_scaled_load15 = mp_set_pd_value(pd_scaled_load15, scaled_la[2]); + pd_scaled_load15 = mp_pd_set_thresholds(pd_scaled_load15, config.th_load[2]); + + mp_subcheck scaled_load_sc15 = mp_subcheck_init(); + scaled_load_sc15 = mp_set_subcheck_state(scaled_load_sc15, mp_get_pd_status(pd_scaled_load15)); + mp_add_perfdata_to_subcheck(&scaled_load_sc15, pd_scaled_load15); + xasprintf(&scaled_load_sc15.output, "15 Minutes: %s", pd_value_to_string(pd_scaled_load15.value)); + mp_add_subcheck_to_subcheck(&scaled_load_sc, scaled_load_sc15); + + mp_add_subcheck_to_check(&overall, scaled_load_sc); + } + + mp_subcheck load_sc = mp_subcheck_init(); + load_sc = mp_set_subcheck_default_state(load_sc, STATE_OK); + load_sc.output = "Total Load"; - char *tmp = NULL; - xasprintf(&tmp, _("load average: %.2f, %.2f, %.2f"), scaled_la[0], scaled_la[1], scaled_la[2]); - xasprintf(&status_line, "scaled %s - %s", tmp, status_line); + mp_perfdata pd_load1 = perfdata_init(); + pd_load1.label = "load1"; + pd_load1 = mp_set_pd_value(pd_load1, load_values[0]); + if (!is_using_scaled_load_values) { + pd_load1 = mp_pd_set_thresholds(pd_load1, config.th_load[0]); } - for (i = 0; i < 3; i++) { - if (is_using_scaled_load_values) { - if (scaled_la[i] > cload[i]) { - result = STATE_CRITICAL; - break; - } else if (scaled_la[i] > wload[i]) { - result = STATE_WARNING; - } - } else { - if (la[i] > cload[i]) { - result = STATE_CRITICAL; - break; - } else if (la[i] > wload[i]) { - result = STATE_WARNING; - } - } + mp_subcheck load_sc1 = mp_subcheck_init(); + load_sc1 = mp_set_subcheck_state(load_sc1, mp_get_pd_status(pd_load1)); + mp_add_perfdata_to_subcheck(&load_sc1, pd_load1); + xasprintf(&load_sc1.output, "1 Minute: %s", pd_value_to_string(pd_load1.value)); + mp_add_subcheck_to_subcheck(&load_sc, load_sc1); + + mp_perfdata pd_load5 = perfdata_init(); + pd_load5.label = "load5"; + pd_load5 = mp_set_pd_value(pd_load5, load_values[1]); + if (!is_using_scaled_load_values) { + pd_load5 = mp_pd_set_thresholds(pd_load5, config.th_load[1]); } - printf("LOAD %s - %s|", state_text(result), status_line); - for (i = 0; i < 3; i++) { - if (is_using_scaled_load_values) { - printf("load%d=%.3f;;;0; ", nums[i], la[i]); - printf("scaled_load%d=%.3f;%.3f;%.3f;0; ", nums[i], scaled_la[i], wload[i], cload[i]); - } else { - printf("load%d=%.3f;%.3f;%.3f;0; ", nums[i], la[i], wload[i], cload[i]); - } + mp_subcheck load_sc5 = mp_subcheck_init(); + load_sc5 = mp_set_subcheck_state(load_sc5, mp_get_pd_status(pd_load5)); + mp_add_perfdata_to_subcheck(&load_sc5, pd_load5); + xasprintf(&load_sc5.output, "5 Minutes: %s", pd_value_to_string(pd_load5.value)); + mp_add_subcheck_to_subcheck(&load_sc, load_sc5); + + mp_perfdata pd_load15 = perfdata_init(); + pd_load15.label = "load15"; + pd_load15 = mp_set_pd_value(pd_load15, load_values[2]); + if (!is_using_scaled_load_values) { + pd_load15 = mp_pd_set_thresholds(pd_load15, config.th_load[2]); } - putchar('\n'); - if (n_procs_to_show > 0) { - print_top_consuming_processes(); + mp_subcheck load_sc15 = mp_subcheck_init(); + load_sc15 = mp_set_subcheck_state(load_sc15, mp_get_pd_status(pd_load15)); + mp_add_perfdata_to_subcheck(&load_sc15, pd_load15); + xasprintf(&load_sc15.output, "15 Minutes: %s", pd_value_to_string(pd_load15.value)); + mp_add_subcheck_to_subcheck(&load_sc, load_sc15); + + mp_add_subcheck_to_check(&overall, load_sc); + + if (config.n_procs_to_show > 0) { + mp_subcheck top_proc_sc = mp_subcheck_init(); + top_proc_sc = mp_set_subcheck_state(top_proc_sc, STATE_OK); + top_processes_result top_proc = print_top_consuming_processes(config.n_procs_to_show); + top_proc_sc.output = ""; + + if (top_proc.errorcode == OK) { + for (int i = 0; i < config.n_procs_to_show; i++) { + xasprintf(&top_proc_sc.output, "%s\n%s", top_proc_sc.output, top_proc.top_processes[i]); + } + } } - return result; + + mp_exit(overall); } /* process command-line arguments */ -static int process_arguments(int argc, char **argv) { - int c = 0; - - int option = 0; +static check_load_config_wrapper process_arguments(int argc, char **argv) { static struct option longopts[] = {{"warning", required_argument, 0, 'w'}, {"critical", required_argument, 0, 'c'}, {"percpu", no_argument, 0, 'r'}, @@ -236,26 +267,45 @@ static int process_arguments(int argc, char **argv) { {"procs-to-show", required_argument, 0, 'n'}, {0, 0, 0, 0}}; + check_load_config_wrapper result = { + .errorcode = OK, + .config = check_load_config_init(), + }; + if (argc < 2) { - return ERROR; + result.errorcode = ERROR; + return result; } - while (1) { - c = getopt_long(argc, argv, "Vhrc:w:n:", longopts, &option); + while (true) { + int option = 0; + int option_index = getopt_long(argc, argv, "Vhrc:w:n:", longopts, &option); - if (c == -1 || c == EOF) { + if (option_index == -1 || option_index == EOF) { break; } - switch (c) { - case 'w': /* warning time threshold */ - get_threshold(optarg, wload); - break; - case 'c': /* critical time threshold */ - get_threshold(optarg, cload); - break; + switch (option_index) { + case 'w': /* warning time threshold */ { + parsed_thresholds warning_range = get_threshold(optarg); + result.config.th_load[0].warning = warning_range.load[0]; + result.config.th_load[0].warning_is_set = true; + result.config.th_load[1].warning = warning_range.load[1]; + result.config.th_load[1].warning_is_set = true; + result.config.th_load[2].warning = warning_range.load[2]; + result.config.th_load[2].warning_is_set = true; + } break; + case 'c': /* critical time threshold */ { + parsed_thresholds critical_range = get_threshold(optarg); + result.config.th_load[0].critical = critical_range.load[0]; + result.config.th_load[0].critical_is_set = true; + result.config.th_load[1].critical = critical_range.load[1]; + result.config.th_load[1].critical_is_set = true; + result.config.th_load[2].critical = critical_range.load[2]; + result.config.th_load[2].critical_is_set = true; + } break; case 'r': /* Divide load average by number of CPUs */ - take_into_account_cpus = true; + result.config.take_into_account_cpus = true; break; case 'V': /* version */ print_revision(progname, NP_VERSION); @@ -264,49 +314,49 @@ static int process_arguments(int argc, char **argv) { print_help(); exit(STATE_UNKNOWN); case 'n': - n_procs_to_show = atoi(optarg); + result.config.n_procs_to_show = atoi(optarg); break; case '?': /* help */ usage5(); } } - c = optind; - if (c == argc) { - return validate_arguments(); + int index = optind; + if (index == argc) { + return validate_arguments(result); } /* handle the case if both arguments are missing, * but not if only one is given without -c or -w flag */ - if (c - argc == 2) { - get_threshold(argv[c++], wload); - get_threshold(argv[c++], cload); - } else if (c - argc == 1) { - get_threshold(argv[c++], cload); + if (index - argc == 2) { + parsed_thresholds warning_range = get_threshold(argv[index++]); + result.config.th_load[0].warning = warning_range.load[0]; + result.config.th_load[0].warning_is_set = true; + result.config.th_load[1].warning = warning_range.load[1]; + result.config.th_load[1].warning_is_set = true; + result.config.th_load[2].warning = warning_range.load[2]; + result.config.th_load[2].warning_is_set = true; + parsed_thresholds critical_range = get_threshold(argv[index++]); + result.config.th_load[0].critical = critical_range.load[0]; + result.config.th_load[0].critical_is_set = true; + result.config.th_load[1].critical = critical_range.load[1]; + result.config.th_load[1].critical_is_set = true; + result.config.th_load[2].critical = critical_range.load[2]; + result.config.th_load[2].critical_is_set = true; + } else if (index - argc == 1) { + parsed_thresholds critical_range = get_threshold(argv[index++]); + result.config.th_load[0].critical = critical_range.load[0]; + result.config.th_load[0].critical_is_set = true; + result.config.th_load[1].critical = critical_range.load[1]; + result.config.th_load[1].critical_is_set = true; + result.config.th_load[2].critical = critical_range.load[2]; + result.config.th_load[2].critical_is_set = true; } - return validate_arguments(); + return validate_arguments(result); } -static int validate_arguments(void) { - int i = 0; - - /* match cload first, as it will give the most friendly error message - * if user hasn't given the -c switch properly */ - for (i = 0; i < 3; i++) { - if (cload[i] < 0) { - die(STATE_UNKNOWN, _("Critical threshold for %d-minute load average is not specified\n"), nums[i]); - } - if (wload[i] < 0) { - die(STATE_UNKNOWN, _("Warning threshold for %d-minute load average is not specified\n"), nums[i]); - } - if (wload[i] > cload[i]) { - die(STATE_UNKNOWN, _("Parameter inconsistency: %d-minute \"warning load\" is greater than \"critical load\"\n"), nums[i]); - } - } - - return OK; -} +static check_load_config_wrapper validate_arguments(check_load_config_wrapper config_wrapper) { return config_wrapper; } void print_help(void) { print_revision(progname, NP_VERSION); @@ -363,23 +413,39 @@ int cmpstringp(const void *p1, const void *p2) { } #endif /* PS_USES_PROCPCPU */ -static int print_top_consuming_processes() { - int i = 0; - struct output chld_out, chld_err; +static top_processes_result print_top_consuming_processes(int n_procs_to_show) { + top_processes_result result = { + .errorcode = OK, + }; + struct output chld_out; + struct output chld_err; if (np_runcmd(PS_COMMAND, &chld_out, &chld_err, 0) != 0) { fprintf(stderr, _("'%s' exited with non-zero status.\n"), PS_COMMAND); - return STATE_UNKNOWN; + result.errorcode = ERROR; + return result; } + if (chld_out.lines < 2) { fprintf(stderr, _("some error occurred getting procs list.\n")); - return STATE_UNKNOWN; + result.errorcode = ERROR; + return result; } + #ifdef PS_USES_PROCPCPU qsort(chld_out.line + 1, chld_out.lines - 1, sizeof(char *), cmpstringp); #endif /* PS_USES_PROCPCPU */ int lines_to_show = chld_out.lines < (size_t)(n_procs_to_show + 1) ? (int)chld_out.lines : n_procs_to_show + 1; - for (i = 0; i < lines_to_show; i += 1) { - printf("%s\n", chld_out.line[i]); + + result.top_processes = calloc(lines_to_show, sizeof(char *)); + if (result.top_processes == NULL) { + // Failed allocation + result.errorcode = ERROR; + return result; } - return OK; + + for (int i = 0; i < lines_to_show; i += 1) { + xasprintf(&result.top_processes[i], "%s", chld_out.line[i]); + } + + return result; } diff --git a/plugins/check_load.d/config.h b/plugins/check_load.d/config.h new file mode 100644 index 00000000..d399c19c --- /dev/null +++ b/plugins/check_load.d/config.h @@ -0,0 +1,30 @@ +#pragma once + +#include "output.h" +#include "thresholds.h" +typedef struct { + mp_thresholds th_load[3]; + + bool take_into_account_cpus; + int n_procs_to_show; + + mp_output_format output_format; + bool output_format_set; +} check_load_config; + +check_load_config check_load_config_init() { + check_load_config tmp = { + .th_load = + { + mp_thresholds_init(), + mp_thresholds_init(), + mp_thresholds_init(), + }, + + .take_into_account_cpus = false, + .n_procs_to_show = 0, + + .output_format_set = false, + }; + return tmp; +} -- cgit v1.2.3-74-g34f1 From 205b97b3e2133b14fbaab98f81b5f5991cfca1e9 Mon Sep 17 00:00:00 2001 From: Lorenz Kästle <12514511+RincewindsHat@users.noreply.github.com> Date: Thu, 13 Mar 2025 23:48:33 +0100 Subject: check_load: Remove output formatting test and adapt others --- plugins/t/check_load.t | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) (limited to 'plugins') diff --git a/plugins/t/check_load.t b/plugins/t/check_load.t index bba8947c..3e453703 100644 --- a/plugins/t/check_load.t +++ b/plugins/t/check_load.t @@ -16,28 +16,28 @@ my $successScaledOutput = "/^LOAD OK - scaled load average: $loadValue, $loadVal my $failureOutput = "/^LOAD CRITICAL - total load average: $loadValue, $loadValue, $loadValue/"; my $failurScaledOutput = "/^LOAD CRITICAL - scaled load average: $loadValue, $loadValue, $loadValue - total load average: $loadValue, $loadValue, $loadValue/"; -plan tests => 13; +plan tests => 8; $res = NPTest->testCmd( "./check_load -w 100,100,100 -c 100,100,100" ); cmp_ok( $res->return_code, 'eq', 0, "load not over 100"); -like( $res->output, $successOutput, "Output OK"); +# like( $res->output, $successOutput, "Output OK"); $res = NPTest->testCmd( "./check_load -w 0,0,0 -c 0,0,0" ); cmp_ok( $res->return_code, 'eq', 2, "Load over 0"); -like( $res->output, $failureOutput, "Output OK"); +# like( $res->output, $failureOutput, "Output OK"); $res = NPTest->testCmd( "./check_load -r -w 0,0,0 -c 0,0,0" ); cmp_ok( $res->return_code, 'eq', 2, "Load over 0 with per cpu division"); -like( $res->output, $failurScaledOutput, "Output OK"); +# like( $res->output, $failurScaledOutput, "Output OK"); $res = NPTest->testCmd( "./check_load -w 100 -c 100,110" ); cmp_ok( $res->return_code, 'eq', 0, "Plugin can handle non-triplet-arguments"); -like( $res->output, $successOutput, "Output OK"); -like( $res->perf_output, "/load1=$loadValue;100.000;100.000/", "Test handling of non triplet thresholds (load1)"); -like( $res->perf_output, "/load5=$loadValue;100.000;110.000/", "Test handling of non triplet thresholds (load5)"); -like( $res->perf_output, "/load15=$loadValue;100.000;110.000/", "Test handling of non triplet thresholds (load15)"); +# like( $res->output, $successOutput, "Output OK"); +like( $res->perf_output, "/load1=$loadValue;~:100.0+;~:100.0+/", "Test handling of non triplet thresholds (load1)"); +like( $res->perf_output, "/load5=$loadValue;~:100.0+;~:110.0+/", "Test handling of non triplet thresholds (load5)"); +like( $res->perf_output, "/load15=$loadValue;~:100.0+;~:110.0+/", "Test handling of non triplet thresholds (load15)"); $res = NPTest->testCmd( "./check_load -w 100,100,100 -c 100,100,100 -r" ); cmp_ok( $res->return_code, 'eq', 0, "load not over 100"); -like( $res->output, $successScaledOutput, "Output OK"); +# like( $res->output, $successScaledOutput, "Output OK"); -- cgit v1.2.3-74-g34f1 From fedff97c96ec7f7866fa15bd38b9a349cf260cad Mon Sep 17 00:00:00 2001 From: Lorenz Kästle <12514511+RincewindsHat@users.noreply.github.com> Date: Thu, 13 Mar 2025 23:51:51 +0100 Subject: improved includes and some comments --- plugins/check_load.c | 17 +++++++---------- 1 file changed, 7 insertions(+), 10 deletions(-) (limited to 'plugins') diff --git a/plugins/check_load.c b/plugins/check_load.c index 57be8c69..5d3e6237 100644 --- a/plugins/check_load.c +++ b/plugins/check_load.c @@ -28,28 +28,24 @@ * *****************************************************************************/ -#include "output.h" -#include "perfdata.h" -#include "thresholds.h" const char *progname = "check_load"; const char *copyright = "1999-2022"; const char *email = "devel@monitoring-plugins.org"; #include "./common.h" +#include #include "./runcmd.h" #include "./utils.h" #include "./popen.h" -#include "states.h" +#include "../lib/states.h" +#include "../lib/output.h" +#include "../lib/perfdata.h" +#include "../lib/thresholds.h" #include "check_load.d/config.h" +// getloadavg comes from gnulib #include "../gl/stdlib.h" -#include - -#ifdef HAVE_SYS_LOADAVG_H -# include -#endif - /* needed for compilation under NetBSD, as suggested by Andy Doran */ #ifndef LOADAVG_1MIN # define LOADAVG_1MIN 0 @@ -136,6 +132,7 @@ int main(int argc, char **argv) { double load_values[3] = {0, 0, 0}; + // this should be getloadavg from gnulib, should work everywhere™ int error = getloadavg(load_values, 3); if (error != 3) { die(STATE_UNKNOWN, _("Failed to retrieve load values")); -- cgit v1.2.3-74-g34f1 From 5eaeadbb3a50e254fb465bf22c6022de9ecbab2d Mon Sep 17 00:00:00 2001 From: Lorenz Kästle <12514511+RincewindsHat@users.noreply.github.com> Date: Fri, 14 Mar 2025 00:04:02 +0100 Subject: check_load: Actually allow output format configuring --- plugins/check_load.c | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) (limited to 'plugins') diff --git a/plugins/check_load.c b/plugins/check_load.c index 5d3e6237..bf3c89d8 100644 --- a/plugins/check_load.c +++ b/plugins/check_load.c @@ -256,12 +256,18 @@ int main(int argc, char **argv) { /* process command-line arguments */ static check_load_config_wrapper process_arguments(int argc, char **argv) { + + enum { + output_format_index = CHAR_MAX + 1, + }; + static struct option longopts[] = {{"warning", required_argument, 0, 'w'}, {"critical", required_argument, 0, 'c'}, {"percpu", no_argument, 0, 'r'}, {"version", no_argument, 0, 'V'}, {"help", no_argument, 0, 'h'}, {"procs-to-show", required_argument, 0, 'n'}, + {"output-format", required_argument, 0, output_format_index}, {0, 0, 0, 0}}; check_load_config_wrapper result = { @@ -283,6 +289,18 @@ static check_load_config_wrapper process_arguments(int argc, char **argv) { } switch (option_index) { + 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_set = true; + result.config.output_format = parser.output_format; + break; + } case 'w': /* warning time threshold */ { parsed_thresholds warning_range = get_threshold(optarg); result.config.th_load[0].warning = warning_range.load[0]; @@ -381,6 +399,7 @@ void print_help(void) { printf(" %s\n", _("Number of processes to show when printing the top consuming processes.")); printf(" %s\n", _("NUMBER_OF_PROCS=0 disables this feature. Default value is 0")); + printf(UT_OUTPUT_FORMAT); printf(UT_SUPPORT); } -- cgit v1.2.3-74-g34f1 From 7a5fa0cc5c3c725ddb990fa97ee52652397f1787 Mon Sep 17 00:00:00 2001 From: Lorenz Kästle <12514511+RincewindsHat@users.noreply.github.com> Date: Mon, 17 Mar 2025 12:56:42 +0100 Subject: check_ide_smart: use the more common C90 fixed width integers --- plugins/check_ide_smart.c | 90 ++++++++++++++++++++++++++--------------------- 1 file changed, 49 insertions(+), 41 deletions(-) (limited to 'plugins') diff --git a/plugins/check_ide_smart.c b/plugins/check_ide_smart.c index 9640ef70..16fe3d01 100644 --- a/plugins/check_ide_smart.c +++ b/plugins/check_ide_smart.c @@ -56,7 +56,6 @@ void print_usage(void); # include # include # include -# include /* for __u8 and friends */ # include # include # include @@ -79,48 +78,47 @@ void print_usage(void); #define UNKNOWN -1 typedef struct threshold_s { - __u8 id; - __u8 threshold; - __u8 reserved[10]; + uint8_t id; + uint8_t threshold; + uint8_t reserved[10]; } __attribute__((packed)) threshold_t; typedef struct thresholds_s { - __u16 revision; + uint16_t revision; threshold_t thresholds[NR_ATTRIBUTES]; - __u8 reserved[18]; - __u8 vendor[131]; - __u8 checksum; + uint8_t reserved[18]; + uint8_t vendor[131]; + uint8_t checksum; } __attribute__((packed)) thresholds_t; typedef struct value_s { - __u8 id; - __u16 status; - __u8 value; - __u8 vendor[8]; + uint8_t id; + uint16_t status; + uint8_t value; + uint8_t vendor[8]; } __attribute__((packed)) value_t; typedef struct values_s { - __u16 revision; + uint16_t revision; value_t values[NR_ATTRIBUTES]; - __u8 offline_status; - __u8 vendor1; - __u16 offline_timeout; - __u8 vendor2; - __u8 offline_capability; - __u16 smart_capability; - __u8 reserved[16]; - __u8 vendor[125]; - __u8 checksum; + uint8_t offline_status; + uint8_t vendor1; + uint16_t offline_timeout; + uint8_t vendor2; + uint8_t offline_capability; + uint16_t smart_capability; + uint8_t reserved[16]; + uint8_t vendor[125]; + uint8_t checksum; } __attribute__((packed)) values_t; static struct { - __u8 value; + uint8_t value; char *text; -} offline_status_text[] = {{0x00, "NeverStarted"}, {0x02, "Completed"}, {0x04, "Suspended"}, - {0x05, "Aborted"}, {0x06, "Failed"}, {0, 0}}; +} offline_status_text[] = {{0x00, "NeverStarted"}, {0x02, "Completed"}, {0x04, "Suspended"}, {0x05, "Aborted"}, {0x06, "Failed"}, {0, 0}}; static struct { - __u8 value; + uint8_t value; char *text; } smart_command[] = {{SMART_ENABLE, "SMART_ENABLE"}, {SMART_DISABLE, "SMART_DISABLE"}, @@ -140,7 +138,7 @@ static int smart_read_values(int, values_t *); static int nagios(values_t *, thresholds_t *); static void print_value(value_t *, threshold_t *); static void print_values(values_t *, thresholds_t *); -static int smart_cmd_simple(int, enum SmartCommand, __u8, bool); +static int smart_cmd_simple(int, enum SmartCommand, uint8_t, bool); static int smart_read_thresholds(int, thresholds_t *); static bool verbose = false; @@ -175,8 +173,9 @@ int main(int argc, char *argv[]) { o = getopt_long(argc, argv, "+d:iq10nhVv", longopts, &longindex); - if (o == -1 || o == EOF || o == 1) + if (o == -1 || o == EOF || o == 1) { break; + } switch (o) { case 'd': @@ -234,8 +233,9 @@ int main(int argc, char *argv[]) { smart_read_values(fd, &values); smart_read_thresholds(fd, &thresholds); retval = nagios(&values, &thresholds); - if (verbose) + if (verbose) { print_values(&values, &thresholds); + } close(fd); return retval; @@ -254,7 +254,7 @@ char *get_offline_text(int status) { int smart_read_values(int fd, values_t *values) { #ifdef __linux__ int e; - __u8 args[4 + 512]; + uint8_t args[4 + 512]; args[0] = WIN_SMART; args[1] = 0; args[2] = SMART_READ_VALUES; @@ -282,8 +282,9 @@ int smart_read_values(int fd, values_t *values) { req.cylinder = WDSMART_CYL; if (ioctl(fd, ATAIOCCOMMAND, &req) == 0) { - if (req.retsts != ATACMD_OK) + if (req.retsts != ATACMD_OK) { errno = ENODEV; + } } if (errno != 0) { @@ -370,22 +371,24 @@ void print_values(values_t *p, thresholds_t *t) { p->smart_capability & 1 ? "SaveOnStandBy" : "", p->smart_capability & 2 ? "AutoSave" : ""); } -int smart_cmd_simple(int fd, enum SmartCommand command, __u8 val0, bool show_error) { +int smart_cmd_simple(int fd, enum SmartCommand command, uint8_t val0, bool show_error) { int e = STATE_UNKNOWN; #ifdef __linux__ - __u8 args[4]; + uint8_t args[4]; args[0] = WIN_SMART; args[1] = val0; args[2] = smart_command[command].value; args[3] = 0; if (ioctl(fd, HDIO_DRIVE_CMD, &args)) { e = STATE_CRITICAL; - if (show_error) + if (show_error) { printf(_("CRITICAL - %s: %s\n"), smart_command[command].text, strerror(errno)); + } } else { e = STATE_OK; - if (show_error) + if (show_error) { printf(_("OK - Command sent (%s)\n"), smart_command[command].text); + } } #endif /* __linux__ */ @@ -401,20 +404,24 @@ int smart_cmd_simple(int fd, enum SmartCommand command, __u8 val0, bool show_err req.sec_count = val0; if (ioctl(fd, ATAIOCCOMMAND, &req) == 0) { - if (req.retsts != ATACMD_OK) + if (req.retsts != ATACMD_OK) { errno = ENODEV; - if (req.cylinder != WDSMART_CYL) + } + if (req.cylinder != WDSMART_CYL) { errno = ENODEV; + } } if (errno != 0) { e = STATE_CRITICAL; - if (show_error) + if (show_error) { printf(_("CRITICAL - %s: %s\n"), smart_command[command].text, strerror(errno)); + } } else { e = STATE_OK; - if (show_error) + if (show_error) { printf(_("OK - Command sent (%s)\n"), smart_command[command].text); + } } #endif /* __NetBSD__ */ @@ -424,7 +431,7 @@ int smart_cmd_simple(int fd, enum SmartCommand command, __u8 val0, bool show_err int smart_read_thresholds(int fd, thresholds_t *thresholds) { #ifdef __linux__ int e; - __u8 args[4 + 512]; + uint8_t args[4 + 512]; args[0] = WIN_SMART; args[1] = 0; args[2] = SMART_READ_THRESHOLDS; @@ -452,8 +459,9 @@ int smart_read_thresholds(int fd, thresholds_t *thresholds) { req.cylinder = WDSMART_CYL; if (ioctl(fd, ATAIOCCOMMAND, &req) == 0) { - if (req.retsts != ATACMD_OK) + if (req.retsts != ATACMD_OK) { errno = ENODEV; + } } if (errno != 0) { -- cgit v1.2.3-74-g34f1 From abc87a3d6d3ded76f44b87f28604db8a220fc9ba Mon Sep 17 00:00:00 2001 From: Lorenz Kästle <12514511+RincewindsHat@users.noreply.github.com> Date: Mon, 17 Mar 2025 12:57:21 +0100 Subject: check_ping: fix some variables forgotten during refactoring --- plugins/check_ping.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'plugins') diff --git a/plugins/check_ping.c b/plugins/check_ping.c index 940b9475..6bcdeaad 100644 --- a/plugins/check_ping.c +++ b/plugins/check_ping.c @@ -116,10 +116,10 @@ int main(int argc, char **argv) { # ifdef PING_HAS_TIMEOUT xasprintf(&cmd, rawcmd, timeout_interval, config.max_packets, config.addresses[i]); # else - xasprintf(&cmd, rawcmd, config.max_packets, addresses[i]); + xasprintf(&cmd, rawcmd, config.max_packets, config.addresses[i]); # endif #else - xasprintf(&cmd, rawcmd, addresses[i], config.max_packets); + xasprintf(&cmd, rawcmd, config.addresses[i], config.max_packets); #endif if (verbose >= 2) { -- cgit v1.2.3-74-g34f1 From e04d2ec8c6014eaeb3c5ca51ff2dcb0f340a3a22 Mon Sep 17 00:00:00 2001 From: Lorenz Kästle <12514511+RincewindsHat@users.noreply.github.com> Date: Mon, 17 Mar 2025 12:58:12 +0100 Subject: check_swap: Fixes on NetBSD --- plugins/check_swap.c | 8 +++ plugins/check_swap.d/check_swap.h | 5 +- plugins/check_swap.d/swap.c | 102 ++++++++++++++++++-------------------- 3 files changed, 59 insertions(+), 56 deletions(-) (limited to 'plugins') diff --git a/plugins/check_swap.c b/plugins/check_swap.c index cb95949a..435a104e 100644 --- a/plugins/check_swap.c +++ b/plugins/check_swap.c @@ -90,6 +90,14 @@ int main(int argc, char **argv) { exit(STATE_UNKNOWN); } + if (verbose) { + printf("Swap retrieval result:\n" + "\tFree: %llu\n" + "\tUsed: %llu\n" + "\tTotal: %llu\n", + data.metrics.free, data.metrics.used, data.metrics.total); + } + double percent_used; mp_check overall = mp_check_init(); if (config.output_format_is_set) { diff --git a/plugins/check_swap.d/check_swap.h b/plugins/check_swap.d/check_swap.h index 1000fc9e..da08d65a 100644 --- a/plugins/check_swap.d/check_swap.h +++ b/plugins/check_swap.d/check_swap.h @@ -1,7 +1,8 @@ #pragma once #include "../common.h" -#include "output.h" +#include "../../lib/output.h" +#include "../../lib/states.h" #ifndef SWAP_CONVERSION # define SWAP_CONVERSION 1 @@ -26,7 +27,7 @@ typedef struct { typedef struct { bool allswaps; - int no_swap_state; + mp_state_enum no_swap_state; bool warn_is_set; check_swap_threshold warn; bool crit_is_set; diff --git a/plugins/check_swap.d/swap.c b/plugins/check_swap.d/swap.c index 180d5037..634f80d9 100644 --- a/plugins/check_swap.d/swap.c +++ b/plugins/check_swap.d/swap.c @@ -68,7 +68,7 @@ swap_result getSwapFromProcMeminfo(char proc_meminfo[]) { FILE *meminfo_file_ptr; meminfo_file_ptr = fopen(proc_meminfo, "r"); - swap_result result = {0}; + swap_result result = {}; result.errorcode = STATE_UNKNOWN; if (meminfo_file_ptr == NULL) { @@ -78,83 +78,71 @@ swap_result getSwapFromProcMeminfo(char proc_meminfo[]) { return result; } - uint64_t swap_total = 0; - uint64_t swap_used = 0; - uint64_t swap_free = 0; + unsigned long swap_total = 0; + unsigned long swap_used = 0; + unsigned long swap_free = 0; bool found_total = false; - bool found_used = false; bool found_free = false; char input_buffer[MAX_INPUT_BUFFER]; char str[32]; while (fgets(input_buffer, MAX_INPUT_BUFFER - 1, meminfo_file_ptr)) { - uint64_t tmp_KB = 0; /* * The following sscanf call looks for a line looking like: "Swap: 123 - * 123 123" On which kind of system this format exists, I can not say, - * but I wanted to document this for people who are not adapt with - * sscanf anymore, like me - * Also the units used here are unclear and probably wrong + * 123 123" which exists on NetBSD (at least), + * The unit should be Bytes */ if (sscanf(input_buffer, "%*[S]%*[w]%*[a]%*[p]%*[:] %lu %lu %lu", &swap_total, &swap_used, &swap_free) == 3) { - - result.metrics.total += swap_total; - result.metrics.used += swap_used; - result.metrics.free += swap_free; - found_total = true; found_free = true; - found_used = true; - // Set error result.errorcode = STATE_OK; + // Break out of fgets here, since both scanf expressions might match (NetBSD for example) + break; + } + + /* + * The following sscanf call looks for lines looking like: + * "SwapTotal: 123" and "SwapFree: 123" This format exists at least + * on Debian Linux with a 5.* kernel + */ + unsigned long tmp_KB = 0; + int sscanf_result = sscanf(input_buffer, + "%*[S]%*[w]%*[a]%*[p]%[TotalFreCchd]%*[:] %lu " + "%*[k]%*[B]", + str, &tmp_KB); + + if (sscanf_result == 2) { + + if (verbose >= 3) { + printf("Got %s with %lu\n", str, tmp_KB); + } - /* - * The following sscanf call looks for lines looking like: - * "SwapTotal: 123" and "SwapFree: 123" This format exists at least - * on Debian Linux with a 5.* kernel - */ - } else { - int sscanf_result = sscanf(input_buffer, - "%*[S]%*[w]%*[a]%*[p]%[TotalFreCchd]%*[:] %lu " - "%*[k]%*[B]", - str, &tmp_KB); - - if (sscanf_result == 2) { - - if (verbose >= 3) { - printf("Got %s with %lu\n", str, tmp_KB); - } - - /* I think this part is always in Kb, so convert to bytes */ - if (strcmp("Total", str) == 0) { - swap_total = tmp_KB * 1000; - found_total = true; - } else if (strcmp("Free", str) == 0) { - swap_free = swap_free + tmp_KB * 1000; - found_free = true; - found_used = true; // No explicit used metric available - } else if (strcmp("Cached", str) == 0) { - swap_free = swap_free + tmp_KB * 1000; - found_free = true; - found_used = true; // No explicit used metric available - } - - result.errorcode = STATE_OK; + /* I think this part is always in Kb, so convert to bytes */ + if (strcmp("Total", str) == 0) { + swap_total = tmp_KB * 1000; + found_total = true; + } else if (strcmp("Free", str) == 0) { + swap_free += tmp_KB * 1000; + found_free = true; + } else if (strcmp("Cached", str) == 0) { + swap_free += tmp_KB * 1000; } + + result.errorcode = STATE_OK; } } fclose(meminfo_file_ptr); result.metrics.total = swap_total; - result.metrics.used = swap_total - swap_free; result.metrics.free = swap_free; + result.metrics.used = swap_total - swap_free; - if (!found_free || !found_total || !found_used) { + if (!found_free || !found_total) { result.errorcode = STATE_UNKNOWN; } @@ -297,8 +285,14 @@ struct swapent { }; #else + +// Includes for NetBSD +# include +# include + # define bsd_swapctl swapctl -#endif + +#endif // CHECK_SWAP_SWAPCTL_BSD swap_result getSwapFromSwapctl_BSD(swap_config config) { /* get the number of active swap devices */ @@ -322,8 +316,8 @@ swap_result getSwapFromSwapctl_BSD(swap_config config) { unsigned long long used_swap_mb = 0; for (int i = 0; i < nswaps; i++) { - dsktotal_mb = (float)ent[i].se_nblks / (float)config.conversion_factor; - dskused_mb = (float)ent[i].se_inuse / (float)config.conversion_factor; + dsktotal_mb = (double)ent[i].se_nblks / (double)config.conversion_factor; + dskused_mb = (double)ent[i].se_inuse / (double)config.conversion_factor; dskfree_mb = (dsktotal_mb - dskused_mb); if (config.allswaps && dsktotal_mb > 0) { -- cgit v1.2.3-74-g34f1 From d24316a6b41305f91346e0115ae1f9fe38bff2ce Mon Sep 17 00:00:00 2001 From: Lorenz Kästle <12514511+RincewindsHat@users.noreply.github.com> Date: Mon, 17 Mar 2025 17:40:29 +0100 Subject: check_disk: clang-format --- plugins/check_disk.c | 129 ++++++++++++++++++++++++++++++++++----------------- 1 file changed, 86 insertions(+), 43 deletions(-) (limited to 'plugins') diff --git a/plugins/check_disk.c b/plugins/check_disk.c index 037a6f7a..c3534060 100644 --- a/plugins/check_disk.c +++ b/plugins/check_disk.c @@ -191,8 +191,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")); + } /* If a list of paths has not been selected, find entire mount list and create list of paths @@ -245,12 +246,14 @@ int main(int argc, char **argv) { /* Process for every path in list */ for (path = path_select_list; path; path = path->name_next) { - if (verbose >= 3 && path->freespace_percent->warning != NULL && path->freespace_percent->critical != NULL) + if (verbose >= 3 && path->freespace_percent->warning != NULL && path->freespace_percent->critical != NULL) { printf("Thresholds(pct) for %s warn: %f crit %f\n", path->name, path->freespace_percent->warning->end, path->freespace_percent->critical->end); + } - if (verbose >= 3 && path->group != NULL) + if (verbose >= 3 && path->group != NULL) { printf("Group of %s: %s\n", path->name, path->group); + } /* reset disk result */ disk_result = STATE_UNKNOWN; @@ -262,11 +265,13 @@ int main(int argc, char **argv) { } #ifdef __CYGWIN__ - if (strncmp(path->name, "/cygdrive/", 10) != 0 || strlen(path->name) > 11) + if (strncmp(path->name, "/cygdrive/", 10) != 0 || strlen(path->name) > 11) { continue; + } snprintf(mountdir, sizeof(mountdir), "%s:\\", me->me_mountdir + 10); - if (GetDriveType(mountdir) != DRIVE_FIXED) + if (GetDriveType(mountdir) != DRIVE_FIXED) { me->me_remote = 1; + } #endif /* Filters */ @@ -327,33 +332,39 @@ int main(int argc, char **argv) { /* Threshold comparisons */ temp_result = get_status(path->dfree_units, path->freespace_units); - if (verbose >= 3) + if (verbose >= 3) { printf("Freespace_units result=%d\n", temp_result); + } disk_result = max_state(disk_result, temp_result); temp_result = get_status(path->dfree_pct, path->freespace_percent); - if (verbose >= 3) + if (verbose >= 3) { printf("Freespace%% result=%d\n", temp_result); + } disk_result = max_state(disk_result, temp_result); temp_result = get_status(path->dused_units, path->usedspace_units); - if (verbose >= 3) + if (verbose >= 3) { printf("Usedspace_units result=%d\n", temp_result); + } disk_result = max_state(disk_result, temp_result); temp_result = get_status(path->dused_pct, path->usedspace_percent); - if (verbose >= 3) + if (verbose >= 3) { printf("Usedspace_percent result=%d\n", temp_result); + } disk_result = max_state(disk_result, temp_result); temp_result = get_status(path->dused_inodes_percent, path->usedinodes_percent); - if (verbose >= 3) + if (verbose >= 3) { printf("Usedinodes_percent result=%d\n", temp_result); + } disk_result = max_state(disk_result, temp_result); temp_result = get_status(path->dfree_inodes_percent, path->freeinodes_percent); - if (verbose >= 3) + if (verbose >= 3) { printf("Freeinodes_percent result=%d\n", temp_result); + } disk_result = max_state(disk_result, temp_result); result = max_state(result, disk_result); @@ -414,8 +425,9 @@ int main(int argc, char **argv) { true, path->inodes_total)); } - if (disk_result == STATE_OK && erronly && !verbose) + if (disk_result == STATE_OK && erronly && !verbose) { continue; + } if (disk_result && verbose >= 1) { xasprintf(&flag_header, " %s [", state_text(disk_result)); @@ -434,8 +446,9 @@ int main(int argc, char **argv) { } } - if (verbose >= 2) + if (verbose >= 2) { xasprintf(&output, "%s%s", output, details); + } if (strcmp(output, "") == 0 && !erronly) { preamble = ""; @@ -509,20 +522,24 @@ int process_arguments(int argc, char **argv) { {"help", no_argument, 0, 'h'}, {0, 0, 0, 0}}; - if (argc < 2) + if (argc < 2) { return ERROR; + } np_add_regex(&fs_exclude_list, "iso9660", REG_EXTENDED); - 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, "+?VqhvefCt:c:w:K:W:u:p:x:X:N:mklLPg:R:r:i:I:MEAn", longopts, &option); - if (c == -1 || c == EOF) + if (c == -1 || c == EOF) { break; + } switch (c) { case 't': /* timeout period */ @@ -594,8 +611,9 @@ int process_arguments(int argc, char **argv) { } break; case 'u': - if (units) + if (units) { free(units); + } if (!strcasecmp(optarg, "bytes")) { mult = (uintmax_t)1; units = strdup("B"); @@ -632,19 +650,22 @@ int process_arguments(int argc, char **argv) { } else { die(STATE_UNKNOWN, _("unit type %s not known\n"), optarg); } - if (units == NULL) + if (units == NULL) { die(STATE_UNKNOWN, _("failed allocating storage for '%s'\n"), "units"); + } break; case 'k': /* display mountpoint */ mult = 1024; - if (units) + if (units) { free(units); + } units = strdup("kiB"); break; case 'm': /* display mountpoint */ mult = 1024 * 1024; - if (units) + if (units) { free(units); + } units = strdup("MiB"); break; case 'L': @@ -715,25 +736,28 @@ int process_arguments(int argc, char **argv) { erronly = true; break; case 'E': - if (path_selected) + if (path_selected) { die(STATE_UNKNOWN, "DISK %s: %s", _("UNKNOWN"), _("Must set -E before selecting paths\n")); + } exact_match = true; break; case 'f': freespace_ignore_reserved = true; break; case 'g': - if (path_selected) + if (path_selected) { die(STATE_UNKNOWN, "DISK %s: %s", _("UNKNOWN"), _("Must set group value before selecting paths\n")); + } group = optarg; break; case 'I': cflags |= REG_ICASE; // Intentional fallthrough case 'i': - if (!path_selected) + if (!path_selected) { die(STATE_UNKNOWN, "DISK %s: %s\n", _("UNKNOWN"), _("Paths need to be selected before using -i/-I. Use -A to select all paths explicitly")); + } err = regcomp(&re, optarg, cflags); if (err != 0) { regerror(err, &re, errbuf, MAX_INPUT_BUFFER); @@ -747,13 +771,15 @@ int process_arguments(int argc, char **argv) { if (temp_list->best_match) { if (np_regex_match_mount_entry(temp_list->best_match, &re)) { - if (verbose >= 3) + if (verbose >= 3) { printf("ignoring %s matching regex\n", temp_list->name); + } temp_list = np_del_parameter(temp_list, previous); /* pointer to first element needs to be updated if first item gets deleted */ - if (previous == NULL) + if (previous == NULL) { path_select_list = temp_list; + } } else { previous = temp_list; temp_list = temp_list->name_next; @@ -793,8 +819,9 @@ int process_arguments(int argc, char **argv) { for (me = mount_list; me; me = me->me_next) { if (np_regex_match_mount_entry(me, &re)) { fnd = true; - if (verbose >= 3) + if (verbose >= 3) { printf("%s %s matching expression %s\n", me->me_devname, me->me_mountdir, optarg); + } /* add parameter if not found. overwrite thresholds if path has already been added */ if (!(se = np_find_parameter(path_select_list, me->me_mountdir))) { @@ -810,8 +837,9 @@ int process_arguments(int argc, char **argv) { path_selected = true; break; } - if (!fnd) + if (!fnd) { die(STATE_UNKNOWN, "DISK %s: %s - %s\n", _("UNKNOWN"), _("Regular expression did not match any path or disk"), optarg); + } fnd = false; path_selected = true; @@ -827,8 +855,9 @@ int process_arguments(int argc, char **argv) { if (path_selected == false) { struct parameter_list *path; for (me = mount_list; me; me = me->me_next) { - if (!(path = np_find_parameter(path_select_list, me->me_mountdir))) + if (!(path = np_find_parameter(path_select_list, me->me_mountdir))) { path = np_add_parameter(&path_select_list, me->me_mountdir); + } path->best_match = me; path->group = group; set_all_thresholds(path); @@ -863,11 +892,13 @@ int process_arguments(int argc, char **argv) { /* Support for "check_disk warn crit [fs]" with thresholds at used% level */ c = optind; - if (warn_usedspace_percent == NULL && argc > c && is_intnonneg(argv[c])) + if (warn_usedspace_percent == NULL && argc > c && is_intnonneg(argv[c])) { warn_usedspace_percent = argv[c++]; + } - if (crit_usedspace_percent == NULL && argc > c && is_intnonneg(argv[c])) + if (crit_usedspace_percent == NULL && argc > c && is_intnonneg(argv[c])) { crit_usedspace_percent = argv[c++]; + } if (argc > c) { se = np_add_parameter(&path_select_list, strdup(argv[c++])); @@ -884,23 +915,29 @@ int process_arguments(int argc, char **argv) { } void set_all_thresholds(struct parameter_list *path) { - if (path->freespace_units != NULL) + if (path->freespace_units != NULL) { free(path->freespace_units); + } set_thresholds(&path->freespace_units, warn_freespace_units, crit_freespace_units); - if (path->freespace_percent != NULL) + if (path->freespace_percent != NULL) { free(path->freespace_percent); + } set_thresholds(&path->freespace_percent, warn_freespace_percent, crit_freespace_percent); - if (path->usedspace_units != NULL) + if (path->usedspace_units != NULL) { free(path->usedspace_units); + } set_thresholds(&path->usedspace_units, warn_usedspace_units, crit_usedspace_units); - if (path->usedspace_percent != NULL) + if (path->usedspace_percent != NULL) { free(path->usedspace_percent); + } set_thresholds(&path->usedspace_percent, warn_usedspace_percent, crit_usedspace_percent); - if (path->usedinodes_percent != NULL) + if (path->usedinodes_percent != NULL) { free(path->usedinodes_percent); + } set_thresholds(&path->usedinodes_percent, warn_usedinodes_percent, crit_usedinodes_percent); - if (path->freeinodes_percent != NULL) + if (path->freeinodes_percent != NULL) { free(path->freeinodes_percent); + } set_thresholds(&path->freeinodes_percent, warn_freeinodes_percent, crit_freeinodes_percent); } @@ -1011,11 +1048,13 @@ void print_usage(void) { bool stat_path(struct parameter_list *p) { /* Stat entry to check that dir exists and is accessible */ - if (verbose >= 3) + if (verbose >= 3) { printf("calling stat on %s\n", p->name); + } if (stat(p->name, &stat_buf[0])) { - if (verbose >= 3) + if (verbose >= 3) { printf("stat failed on %s\n", p->name); + } if (ignore_missing == true) { return false; } @@ -1036,18 +1075,21 @@ void get_stats(struct parameter_list *p, struct fs_usage *fsp) { /* find all group members */ for (p_list = path_select_list; p_list; p_list = p_list->name_next) { #ifdef __CYGWIN__ - if (strncmp(p_list->name, "/cygdrive/", 10) != 0) + if (strncmp(p_list->name, "/cygdrive/", 10) != 0) { continue; + } #endif if (p_list->group && !(strcmp(p_list->group, p->group))) { - if (!stat_path(p_list)) + if (!stat_path(p_list)) { continue; + } get_fs_usage(p_list->best_match->me_mountdir, p_list->best_match->me_devname, &tmpfsp); get_path_stats(p_list, &tmpfsp); - if (verbose >= 3) + if (verbose >= 3) { printf("Group %s: adding %lu blocks sized %lu, (%s) used_units=%lu free_units=%lu total_units=%lu mult=%lu\n", p_list->group, tmpfsp.fsu_blocks, tmpfsp.fsu_blocksize, p_list->best_match->me_mountdir, p_list->dused_units, p_list->dfree_units, p_list->dtotal_units, mult); + } /* prevent counting the first FS of a group twice since its parameter_list entry * is used to carry the information of all file systems of the entire group */ @@ -1067,9 +1109,10 @@ void get_stats(struct parameter_list *p, struct fs_usage *fsp) { } first = 0; } - if (verbose >= 3) + if (verbose >= 3) { printf("Group %s now has: used_units=%lu free_units=%lu total_units=%lu fsu_blocksize=%lu mult=%lu\n", p->group, p->dused_units, p->dfree_units, p->dtotal_units, tmpfsp.fsu_blocksize, mult); + } } /* modify devname and mountdir for output */ p->best_match->me_mountdir = p->best_match->me_devname = p->group; -- cgit v1.2.3-74-g34f1 From 969f40c2a083b4e0654a46e6b9e37a0378a4f332 Mon Sep 17 00:00:00 2001 From: Lorenz Kästle <12514511+RincewindsHat@users.noreply.github.com> Date: Mon, 17 Mar 2025 17:44:28 +0100 Subject: check_disk: boolean type and linter fixes --- plugins/check_disk.c | 40 ++++++++++++++++++++-------------------- 1 file changed, 20 insertions(+), 20 deletions(-) (limited to 'plugins') diff --git a/plugins/check_disk.c b/plugins/check_disk.c index c3534060..b5a375d0 100644 --- a/plugins/check_disk.c +++ b/plugins/check_disk.c @@ -62,10 +62,10 @@ const char *email = "devel@monitoring-plugins.org"; static int show_all_fs = 1; /* If nonzero, show only local filesystems. */ -static int show_local_fs = 0; +static bool show_local_fs = false; /* If nonzero, show only local filesystems but call stat() on remote ones. */ -static int stat_remote_fs = 0; +static bool stat_remote_fs = false; /* If positive, the units to use when printing sizes; if negative, the human-readable base. */ @@ -121,7 +121,7 @@ static int process_arguments(int /*argc*/, char ** /*argv*/); static void set_all_thresholds(struct parameter_list *path); static void print_help(void); void print_usage(void); -static double calculate_percent(uintmax_t, uintmax_t); +static double calculate_percent(uintmax_t /*value*/, uintmax_t /*total*/); static bool stat_path(struct parameter_list *p); static void get_stats(struct parameter_list *p, struct fs_usage *fsp); static void get_path_stats(struct parameter_list *p, struct fs_usage *fsp); @@ -198,7 +198,7 @@ int main(int argc, char **argv) { /* If a list of paths has not been selected, find entire mount list and create list of paths */ - if (path_selected == false && path_ignored == false) { + if (!path_selected && !path_ignored) { for (me = mount_list; me; me = me->me_next) { if (!(path = np_find_parameter(path_select_list, me->me_mountdir))) { path = np_add_parameter(&path_select_list, me->me_mountdir); @@ -209,7 +209,7 @@ int main(int argc, char **argv) { } } - if (path_ignored == false) { + if (!path_ignored) { np_set_best_match(path_select_list, mount_list, exact_match); } @@ -217,7 +217,7 @@ int main(int argc, char **argv) { temp_list = path_select_list; while (path_select_list) { - if (!path_select_list->best_match && ignore_missing == true) { + if (!path_select_list->best_match && ignore_missing) { /* If the first element will be deleted, the temp_list must be updated with the new start address as well */ if (path_select_list == temp_list) { temp_list = path_select_list->name_next; @@ -237,7 +237,7 @@ int main(int argc, char **argv) { path_select_list = temp_list; - if (!path_select_list && ignore_missing == true) { + if (!path_select_list && ignore_missing) { result = STATE_OK; if (verbose >= 2) { printf("None of the provided paths were found\n"); @@ -285,7 +285,7 @@ int main(int argc, char **argv) { /* Skip remote filesystems if we're not interested in them */ if (me->me_remote && show_local_fs) { if (stat_remote_fs) { - if (!stat_path(path) && ignore_missing == true) { + if (!stat_path(path) && ignore_missing) { result = STATE_OK; xasprintf(&ignored, "%s %s;", ignored, path->name); } @@ -311,7 +311,7 @@ int main(int argc, char **argv) { } if (!stat_path(path)) { - if (ignore_missing == true) { + if (ignore_missing) { result = STATE_OK; xasprintf(&ignored, "%s %s;", ignored, path->name); } @@ -398,8 +398,8 @@ int main(int argc, char **argv) { /* Nb: *_high_tide are unset when == UINT64_MAX */ xasprintf(&perf, "%s %s", perf, perfdata_uint64((!strcmp(me->me_mountdir, "none") || display_mntp) ? me->me_devname : me->me_mountdir, - path->dused_units * mult, "B", (warning_high_tide == UINT64_MAX ? false : true), warning_high_tide, - (critical_high_tide == UINT64_MAX ? false : true), critical_high_tide, true, 0, true, + path->dused_units * mult, "B", (warning_high_tide != UINT64_MAX ), warning_high_tide, + (critical_high_tide != UINT64_MAX ), critical_high_tide, true, 0, true, path->dtotal_units * mult)); if (display_inodes_perfdata) { @@ -420,8 +420,8 @@ int main(int argc, char **argv) { (!strcmp(me->me_mountdir, "none") || display_mntp) ? me->me_devname : me->me_mountdir); /* Nb: *_high_tide are unset when == UINT64_MAX */ xasprintf(&perf, "%s %s", perf, - perfdata_uint64(perf_ilabel, path->inodes_used, "", (warning_high_tide != UINT64_MAX ? true : false), - warning_high_tide, (critical_high_tide != UINT64_MAX ? true : false), critical_high_tide, true, 0, + perfdata_uint64(perf_ilabel, path->inodes_used, "", (warning_high_tide != UINT64_MAX), + warning_high_tide, (critical_high_tide != UINT64_MAX), critical_high_tide, true, 0, true, path->inodes_total)); } @@ -669,13 +669,13 @@ int process_arguments(int argc, char **argv) { units = strdup("MiB"); break; case 'L': - stat_remote_fs = 1; + stat_remote_fs = true; /* fallthrough */ case 'l': - show_local_fs = 1; + show_local_fs = true; break; case 'P': - display_inodes_perfdata = 1; + display_inodes_perfdata = true; break; case 'p': /* select path */ if (!(warn_freespace_units || crit_freespace_units || warn_freespace_percent || crit_freespace_percent || @@ -688,7 +688,7 @@ int process_arguments(int argc, char **argv) { if (!(se = np_find_parameter(path_select_list, optarg))) { se = np_add_parameter(&path_select_list, optarg); - if (stat(optarg, &stat_buf[0]) && ignore_missing == true) { + if (stat(optarg, &stat_buf[0]) && ignore_missing) { path_ignored = true; break; } @@ -832,7 +832,7 @@ int process_arguments(int argc, char **argv) { } } - if (!fnd && ignore_missing == true) { + if (!fnd && ignore_missing) { path_ignored = true; path_selected = true; break; @@ -852,7 +852,7 @@ int process_arguments(int argc, char **argv) { break; case 'C': /* add all mount entries to path_select list if no partitions have been explicitly defined using -p */ - if (path_selected == false) { + if (!path_selected) { struct parameter_list *path; for (me = mount_list; me; me = me->me_next) { if (!(path = np_find_parameter(path_select_list, me->me_mountdir))) { @@ -1055,7 +1055,7 @@ bool stat_path(struct parameter_list *p) { if (verbose >= 3) { printf("stat failed on %s\n", p->name); } - if (ignore_missing == true) { + if (ignore_missing) { return false; } printf("DISK %s - ", _("CRITICAL")); -- cgit v1.2.3-74-g34f1 From 4fb7fb05b672febfdfa69381f7f403dc872c7aa6 Mon Sep 17 00:00:00 2001 From: Lorenz Kästle <12514511+RincewindsHat@users.noreply.github.com> Date: Mon, 17 Mar 2025 19:36:11 +0100 Subject: check_disk: General refactoring --- plugins/check_disk.c | 353 +++++++++++++++++++++++---------------------------- 1 file changed, 158 insertions(+), 195 deletions(-) (limited to 'plugins') diff --git a/plugins/check_disk.c b/plugins/check_disk.c index b5a375d0..e16c453d 100644 --- a/plugins/check_disk.c +++ b/plugins/check_disk.c @@ -31,13 +31,17 @@ const char *program_name = "check_disk"; /* Required for coreutils libs */ const char *copyright = "1999-2024"; const char *email = "devel@monitoring-plugins.org"; +#include "states.h" #include "common.h" + #ifdef HAVE_SYS_STAT_H # include #endif + #if HAVE_INTTYPES_H # include #endif + #include #include "popen.h" #include "utils.h" @@ -46,9 +50,11 @@ const char *email = "devel@monitoring-plugins.org"; #include "fsusage.h" #include "mountlist.h" #include + #if HAVE_LIMITS_H # include #endif + #include "regex.h" #ifdef __CYGWIN__ @@ -57,39 +63,12 @@ const char *email = "devel@monitoring-plugins.org"; # define ERROR -1 #endif -/* If nonzero, show even filesystems with zero size or - uninteresting types. */ -static int show_all_fs = 1; - /* If nonzero, show only local filesystems. */ static bool show_local_fs = false; /* If nonzero, show only local filesystems but call stat() on remote ones. */ static bool stat_remote_fs = false; -/* If positive, the units to use when printing sizes; - if negative, the human-readable base. */ -/* static int output_block_size; */ - -/* If nonzero, invoke the `sync' system call before getting any usage data. - Using this option can make df very slow, especially with many or very - busy disks. Note that this may make a difference on some systems -- - SunOs4.1.3, for one. It is *not* necessary on Linux. */ -/* static int require_sync = 0; */ - -/* Linked list of filesystem types to display. - If `fs_select_list' is NULL, list all types. - This table is generated dynamically from command-line options, - rather than hardcoding into the program what it thinks are the - valid filesystem types; let the user specify any filesystem type - they want to, and if there are any filesystems of that type, they - will be shown. - - Some filesystem types: - 4.2 4.3 ufs nfs swap ignore io vm efs dbg */ - -/* static struct parameter_list *fs_select_list; */ - /* Linked list of filesystem types to omit. If the list is empty, don't exclude any types. */ static struct regex_list *fs_exclude_list = NULL; @@ -150,43 +129,18 @@ static char *crit_freeinodes_percent = NULL; static bool path_selected = false; static bool path_ignored = false; static char *group = NULL; -static struct stat *stat_buf; static struct name_list *seen = NULL; int main(int argc, char **argv) { - int result = STATE_UNKNOWN; - int disk_result = STATE_UNKNOWN; - char *output = NULL; - char *ignored = NULL; - char *details = NULL; - char *perf = NULL; - char *perf_ilabel = NULL; - char *preamble = " - free space:"; - char *ignored_preamble = " - ignored paths:"; - char *flag_header = NULL; - int temp_result = STATE_UNKNOWN; - - struct mount_entry *me = NULL; - struct fs_usage fsp = {0}; - struct parameter_list *temp_list = NULL; - struct parameter_list *path = NULL; + setlocale(LC_ALL, ""); + bindtextdomain(PACKAGE, LOCALEDIR); + textdomain(PACKAGE); #ifdef __CYGWIN__ char mountdir[32]; #endif - output = strdup(""); - ignored = strdup(""); - details = strdup(""); - perf = strdup(""); - perf_ilabel = strdup(""); - stat_buf = malloc(sizeof *stat_buf); - - setlocale(LC_ALL, ""); - bindtextdomain(PACKAGE, LOCALEDIR); - textdomain(PACKAGE); - - mount_list = read_file_system_list(0); + mount_list = read_file_system_list(false); /* Parse extra opts if any */ argv = np_extra_opts(&argc, argv, progname); @@ -199,7 +153,8 @@ int main(int argc, char **argv) { mount list and create list of paths */ if (!path_selected && !path_ignored) { - for (me = mount_list; me; me = me->me_next) { + for (struct mount_entry *me = mount_list; me; me = me->me_next) { + struct parameter_list *path = NULL; if (!(path = np_find_parameter(path_select_list, me->me_mountdir))) { path = np_add_parameter(&path_select_list, me->me_mountdir); } @@ -214,8 +169,9 @@ int main(int argc, char **argv) { } /* Error if no match found for specified paths */ - temp_list = path_select_list; + struct parameter_list *temp_list = path_select_list; + char *ignored = strdup(""); while (path_select_list) { if (!path_select_list->best_match && ignore_missing) { /* If the first element will be deleted, the temp_list must be updated with the new start address as well */ @@ -237,6 +193,7 @@ int main(int argc, char **argv) { path_select_list = temp_list; + int result = STATE_UNKNOWN; if (!path_select_list && ignore_missing) { result = STATE_OK; if (verbose >= 2) { @@ -244,6 +201,11 @@ int main(int argc, char **argv) { } } + mp_state_enum disk_result = STATE_UNKNOWN; + char *perf = strdup(""); + char *perf_ilabel = strdup(""); + char *output = strdup(""); + struct parameter_list *path = NULL; /* Process for every path in list */ for (path = path_select_list; path; path = path->name_next) { if (verbose >= 3 && path->freespace_percent->warning != NULL && path->freespace_percent->critical != NULL) { @@ -255,12 +217,9 @@ int main(int argc, char **argv) { printf("Group of %s: %s\n", path->name, path->group); } - /* reset disk result */ - disk_result = STATE_UNKNOWN; + struct mount_entry *mount_entry = path->best_match; - me = path->best_match; - - if (!me) { + if (!mount_entry) { continue; } @@ -276,14 +235,14 @@ int main(int argc, char **argv) { /* Filters */ /* Remove filesystems already seen */ - if (np_seen_name(seen, me->me_mountdir)) { + if (np_seen_name(seen, mount_entry->me_mountdir)) { continue; } - np_add_name(&seen, me->me_mountdir); + np_add_name(&seen, mount_entry->me_mountdir); if (path->group == NULL) { /* Skip remote filesystems if we're not interested in them */ - if (me->me_remote && show_local_fs) { + if (mount_entry->me_remote && show_local_fs) { if (stat_remote_fs) { if (!stat_path(path) && ignore_missing) { result = STATE_OK; @@ -293,19 +252,16 @@ int main(int argc, char **argv) { continue; /* Skip pseudo fs's if we haven't asked for all fs's */ } - if (me->me_dummy && !show_all_fs) { - continue; - /* Skip excluded fstypes */ - } - if (fs_exclude_list && np_find_regmatch(fs_exclude_list, me->me_type)) { + if (fs_exclude_list && np_find_regmatch(fs_exclude_list, mount_entry->me_type)) { continue; /* Skip excluded fs's */ } - if (dp_exclude_list && (np_find_name(dp_exclude_list, me->me_devname) || np_find_name(dp_exclude_list, me->me_mountdir))) { + if (dp_exclude_list && + (np_find_name(dp_exclude_list, mount_entry->me_devname) || np_find_name(dp_exclude_list, mount_entry->me_mountdir))) { continue; /* Skip not included fstypes */ } - if (fs_include_list && !np_find_regmatch(fs_include_list, me->me_type)) { + if (fs_include_list && !np_find_regmatch(fs_include_list, mount_entry->me_type)) { continue; } } @@ -317,21 +273,23 @@ int main(int argc, char **argv) { } continue; } - get_fs_usage(me->me_mountdir, me->me_devname, &fsp); - if (fsp.fsu_blocks && strcmp("none", me->me_mountdir)) { + struct fs_usage fsp = {0}; + get_fs_usage(mount_entry->me_mountdir, mount_entry->me_devname, &fsp); + + if (fsp.fsu_blocks && strcmp("none", mount_entry->me_mountdir)) { get_stats(path, &fsp); if (verbose >= 3) { printf("For %s, used_pct=%f free_pct=%f used_units=%lu free_units=%lu total_units=%lu used_inodes_pct=%f " "free_inodes_pct=%f fsp.fsu_blocksize=%lu mult=%lu\n", - me->me_mountdir, path->dused_pct, path->dfree_pct, path->dused_units, path->dfree_units, path->dtotal_units, + mount_entry->me_mountdir, path->dused_pct, path->dfree_pct, path->dused_units, path->dfree_units, path->dtotal_units, path->dused_inodes_percent, path->dfree_inodes_percent, fsp.fsu_blocksize, mult); } /* Threshold comparisons */ - temp_result = get_status(path->dfree_units, path->freespace_units); + mp_state_enum temp_result = get_status(path->dfree_units, path->freespace_units); if (verbose >= 3) { printf("Freespace_units result=%d\n", temp_result); } @@ -397,10 +355,10 @@ int main(int argc, char **argv) { /* Nb: *_high_tide are unset when == UINT64_MAX */ xasprintf(&perf, "%s %s", perf, - perfdata_uint64((!strcmp(me->me_mountdir, "none") || display_mntp) ? me->me_devname : me->me_mountdir, - path->dused_units * mult, "B", (warning_high_tide != UINT64_MAX ), warning_high_tide, - (critical_high_tide != UINT64_MAX ), critical_high_tide, true, 0, true, - path->dtotal_units * mult)); + perfdata_uint64((!strcmp(mount_entry->me_mountdir, "none") || display_mntp) ? mount_entry->me_devname + : mount_entry->me_mountdir, + path->dused_units * mult, "B", (warning_high_tide != UINT64_MAX), warning_high_tide, + (critical_high_tide != UINT64_MAX), critical_high_tide, true, 0, true, path->dtotal_units * mult)); if (display_inodes_perfdata) { /* *_high_tide must be reinitialized at each run */ @@ -417,26 +375,26 @@ int main(int argc, char **argv) { } xasprintf(&perf_ilabel, "%s (inodes)", - (!strcmp(me->me_mountdir, "none") || display_mntp) ? me->me_devname : me->me_mountdir); + (!strcmp(mount_entry->me_mountdir, "none") || display_mntp) ? mount_entry->me_devname : mount_entry->me_mountdir); /* Nb: *_high_tide are unset when == UINT64_MAX */ xasprintf(&perf, "%s %s", perf, - perfdata_uint64(perf_ilabel, path->inodes_used, "", (warning_high_tide != UINT64_MAX), - warning_high_tide, (critical_high_tide != UINT64_MAX), critical_high_tide, true, 0, - true, path->inodes_total)); + perfdata_uint64(perf_ilabel, path->inodes_used, "", (warning_high_tide != UINT64_MAX), warning_high_tide, + (critical_high_tide != UINT64_MAX), critical_high_tide, true, 0, true, path->inodes_total)); } if (disk_result == STATE_OK && erronly && !verbose) { continue; } + char *flag_header = NULL; if (disk_result && verbose >= 1) { xasprintf(&flag_header, " %s [", state_text(disk_result)); } else { xasprintf(&flag_header, ""); } xasprintf(&output, "%s%s %s %llu%s (%.1f%%", output, flag_header, - (!strcmp(me->me_mountdir, "none") || display_mntp) ? me->me_devname : me->me_mountdir, path->dfree_units, units, - path->dfree_pct); + (!strcmp(mount_entry->me_mountdir, "none") || display_mntp) ? mount_entry->me_devname : mount_entry->me_mountdir, + path->dfree_units, units, path->dfree_pct); if (path->dused_inodes_percent < 0) { xasprintf(&output, "%s inode=-)%s;", output, (disk_result ? "]" : "")); } else { @@ -446,15 +404,13 @@ int main(int argc, char **argv) { } } - if (verbose >= 2) { - xasprintf(&output, "%s%s", output, details); - } - + char *preamble = " - free space:"; if (strcmp(output, "") == 0 && !erronly) { preamble = ""; xasprintf(&output, " - No disks were found for provided parameters"); } + char *ignored_preamble = " - ignored paths:"; printf("DISK %s%s%s%s%s|%s\n", state_text(result), ((erronly && result == STATE_OK)) ? "" : preamble, output, (strcmp(ignored, "") == 0) ? "" : ignored_preamble, ignored, perf); return result; @@ -470,19 +426,10 @@ double calculate_percent(uintmax_t value, uintmax_t total) { /* process command-line arguments */ int process_arguments(int argc, char **argv) { - int c; - int err; - struct parameter_list *se; - struct parameter_list *temp_list = NULL; - struct parameter_list *previous = NULL; - struct mount_entry *me; - regex_t re; - int cflags = REG_NOSUB | REG_EXTENDED; - int default_cflags = cflags; - char errbuf[MAX_INPUT_BUFFER]; - int fnd = 0; + if (argc < 2) { + return ERROR; + } - int option = 0; static struct option longopts[] = {{"timeout", required_argument, 0, 't'}, {"warning", required_argument, 0, 'w'}, {"critical", required_argument, 0, 'c'}, @@ -522,26 +469,26 @@ int process_arguments(int argc, char **argv) { {"help", no_argument, 0, 'h'}, {0, 0, 0, 0}}; - if (argc < 2) { - return ERROR; + for (int index = 1; index < argc; index++) { + if (strcmp("-to", argv[index]) == 0) { + strcpy(argv[index], "-t"); + } } - np_add_regex(&fs_exclude_list, "iso9660", REG_EXTENDED); + int cflags = REG_NOSUB | REG_EXTENDED; + int default_cflags = cflags; - for (c = 1; c < argc; c++) { - if (strcmp("-to", argv[c]) == 0) { - strcpy(argv[c], "-t"); - } - } + np_add_regex(&fs_exclude_list, "iso9660", REG_EXTENDED); - while (1) { - c = getopt_long(argc, argv, "+?VqhvefCt:c:w:K:W:u:p:x:X:N:mklLPg:R:r:i:I:MEAn", longopts, &option); + while (true) { + int option = 0; + int option_index = getopt_long(argc, argv, "+?VqhvefCt:c:w:K:W:u:p:x:X:N:mklLPg:R:r:i:I:MEAn", longopts, &option); - if (c == -1 || c == EOF) { + if (option_index == -1 || option_index == EOF) { break; } - switch (c) { + switch (option_index) { case 't': /* timeout period */ if (is_integer(optarg)) { timeout_interval = atoi(optarg); @@ -685,10 +632,12 @@ int process_arguments(int argc, char **argv) { } /* add parameter if not found. overwrite thresholds if path has already been added */ + struct parameter_list *se; if (!(se = np_find_parameter(path_select_list, optarg))) { se = np_add_parameter(&path_select_list, optarg); - if (stat(optarg, &stat_buf[0]) && ignore_missing) { + struct stat stat_buf = {}; + if (stat(optarg, &stat_buf) && ignore_missing) { path_ignored = true; break; } @@ -703,7 +652,7 @@ int process_arguments(int argc, char **argv) { /* NB: We can't free the old mount_list "just like that": both list pointers and struct * pointers are copied around. One of the reason it wasn't done yet is that other parts * of check_disk need the same kind of cleanup so it'd better be done as a whole */ - mount_list = read_file_system_list(0); + mount_list = read_file_system_list(false); np_set_best_match(se, mount_list, exact_match); path_selected = true; @@ -711,9 +660,10 @@ int process_arguments(int argc, char **argv) { case 'x': /* exclude path or partition */ np_add_name(&dp_exclude_list, optarg); break; - case 'X': /* exclude file system type */ - err = np_add_regex(&fs_exclude_list, optarg, REG_EXTENDED); + case 'X': /* exclude file system type */ { + int err = np_add_regex(&fs_exclude_list, optarg, REG_EXTENDED); if (err != 0) { + char errbuf[MAX_INPUT_BUFFER]; regerror(err, &fs_exclude_list->regex, errbuf, MAX_INPUT_BUFFER); die(STATE_UNKNOWN, "DISK %s: %s - %s\n", _("UNKNOWN"), _("Could not compile regular expression"), errbuf); } @@ -721,10 +671,11 @@ int process_arguments(int argc, char **argv) { case 'N': /* include file system type */ err = np_add_regex(&fs_include_list, optarg, REG_EXTENDED); if (err != 0) { + char errbuf[MAX_INPUT_BUFFER]; regerror(err, &fs_exclude_list->regex, errbuf, MAX_INPUT_BUFFER); die(STATE_UNKNOWN, "DISK %s: %s - %s\n", _("UNKNOWN"), _("Could not compile regular expression"), errbuf); } - break; + } break; case 'v': /* verbose */ verbose++; break; @@ -753,23 +704,24 @@ int process_arguments(int argc, char **argv) { case 'I': cflags |= REG_ICASE; // Intentional fallthrough - case 'i': + case 'i': { if (!path_selected) { die(STATE_UNKNOWN, "DISK %s: %s\n", _("UNKNOWN"), _("Paths need to be selected before using -i/-I. Use -A to select all paths explicitly")); } - err = regcomp(&re, optarg, cflags); + regex_t regex; + int err = regcomp(®ex, optarg, cflags); if (err != 0) { - regerror(err, &re, errbuf, MAX_INPUT_BUFFER); + char errbuf[MAX_INPUT_BUFFER]; + regerror(err, ®ex, errbuf, MAX_INPUT_BUFFER); die(STATE_UNKNOWN, "DISK %s: %s - %s\n", _("UNKNOWN"), _("Could not compile regular expression"), errbuf); } - temp_list = path_select_list; - - previous = NULL; + struct parameter_list *temp_list = path_select_list; + struct parameter_list *previous = NULL; while (temp_list) { if (temp_list->best_match) { - if (np_regex_match_mount_entry(temp_list->best_match, &re)) { + if (np_regex_match_mount_entry(temp_list->best_match, ®ex)) { if (verbose >= 3) { printf("ignoring %s matching regex\n", temp_list->name); @@ -791,8 +743,7 @@ int process_arguments(int argc, char **argv) { } cflags = default_cflags; - break; - + } break; case 'n': ignore_missing = true; break; @@ -802,7 +753,7 @@ int process_arguments(int argc, char **argv) { case 'R': cflags |= REG_ICASE; // Intentional fallthrough - case 'r': + case 'r': { if (!(warn_freespace_units || crit_freespace_units || warn_freespace_percent || crit_freespace_percent || warn_usedspace_units || crit_usedspace_units || warn_usedspace_percent || crit_usedspace_percent || warn_usedinodes_percent || crit_usedinodes_percent || warn_freeinodes_percent || crit_freeinodes_percent)) { @@ -810,15 +761,18 @@ int process_arguments(int argc, char **argv) { _("Must set a threshold value before using -r/-R/-A (--ereg-path/--eregi-path/--all)\n")); } - err = regcomp(&re, optarg, cflags); + regex_t regex; + int err = regcomp(®ex, optarg, cflags); if (err != 0) { - regerror(err, &re, errbuf, MAX_INPUT_BUFFER); + char errbuf[MAX_INPUT_BUFFER]; + regerror(err, ®ex, errbuf, MAX_INPUT_BUFFER); die(STATE_UNKNOWN, "DISK %s: %s - %s\n", _("UNKNOWN"), _("Could not compile regular expression"), errbuf); } - for (me = mount_list; me; me = me->me_next) { - if (np_regex_match_mount_entry(me, &re)) { - fnd = true; + bool found = false; + for (struct mount_entry *me = mount_list; me; me = me->me_next) { + if (np_regex_match_mount_entry(me, ®ex)) { + found = true; if (verbose >= 3) { printf("%s %s matching expression %s\n", me->me_devname, me->me_mountdir, optarg); } @@ -832,21 +786,21 @@ int process_arguments(int argc, char **argv) { } } - if (!fnd && ignore_missing) { + if (!found && ignore_missing) { path_ignored = true; path_selected = true; break; } - if (!fnd) { + if (!found) { die(STATE_UNKNOWN, "DISK %s: %s - %s\n", _("UNKNOWN"), _("Regular expression did not match any path or disk"), optarg); } - fnd = false; + found = false; path_selected = true; np_set_best_match(path_select_list, mount_list, exact_match); cflags = default_cflags; - break; + } break; case 'M': /* display mountpoint */ display_mntp = true; break; @@ -854,7 +808,7 @@ int process_arguments(int argc, char **argv) { /* add all mount entries to path_select list if no partitions have been explicitly defined using -p */ if (!path_selected) { struct parameter_list *path; - for (me = mount_list; me; me = me->me_next) { + for (struct mount_entry *me = mount_list; me; me = me->me_next) { if (!(path = np_find_parameter(path_select_list, me->me_mountdir))) { path = np_add_parameter(&path_select_list, me->me_mountdir); } @@ -891,17 +845,17 @@ int process_arguments(int argc, char **argv) { } /* Support for "check_disk warn crit [fs]" with thresholds at used% level */ - c = optind; - if (warn_usedspace_percent == NULL && argc > c && is_intnonneg(argv[c])) { - warn_usedspace_percent = argv[c++]; + int index = optind; + if (warn_usedspace_percent == NULL && argc > index && is_intnonneg(argv[index])) { + warn_usedspace_percent = argv[index++]; } - if (crit_usedspace_percent == NULL && argc > c && is_intnonneg(argv[c])) { - crit_usedspace_percent = argv[c++]; + if (crit_usedspace_percent == NULL && argc > index && is_intnonneg(argv[index])) { + crit_usedspace_percent = argv[index++]; } - if (argc > c) { - se = np_add_parameter(&path_select_list, strdup(argv[c++])); + if (argc > index) { + struct parameter_list *se = np_add_parameter(&path_select_list, strdup(argv[index++])); path_selected = true; set_all_thresholds(se); } @@ -911,7 +865,7 @@ int process_arguments(int argc, char **argv) { mult = (uintmax_t)1024 * 1024; } - return true; + return 0; } void set_all_thresholds(struct parameter_list *path) { @@ -919,22 +873,27 @@ void set_all_thresholds(struct parameter_list *path) { free(path->freespace_units); } set_thresholds(&path->freespace_units, warn_freespace_units, crit_freespace_units); + if (path->freespace_percent != NULL) { free(path->freespace_percent); } set_thresholds(&path->freespace_percent, warn_freespace_percent, crit_freespace_percent); + if (path->usedspace_units != NULL) { free(path->usedspace_units); } set_thresholds(&path->usedspace_units, warn_usedspace_units, crit_usedspace_units); + if (path->usedspace_percent != NULL) { free(path->usedspace_percent); } set_thresholds(&path->usedspace_percent, warn_usedspace_percent, crit_usedspace_percent); + if (path->usedinodes_percent != NULL) { free(path->usedinodes_percent); } set_thresholds(&path->usedinodes_percent, warn_usedinodes_percent, crit_usedinodes_percent); + if (path->freeinodes_percent != NULL) { free(path->freeinodes_percent); } @@ -1046,40 +1005,44 @@ void print_usage(void) { printf("[-t timeout] [-u unit] [-v] [-X type_regex] [-N type]\n"); } -bool stat_path(struct parameter_list *p) { +bool stat_path(struct parameter_list *parameters) { /* Stat entry to check that dir exists and is accessible */ if (verbose >= 3) { - printf("calling stat on %s\n", p->name); + printf("calling stat on %s\n", parameters->name); } - if (stat(p->name, &stat_buf[0])) { + + struct stat stat_buf = {0}; + if (stat(parameters->name, &stat_buf)) { if (verbose >= 3) { - printf("stat failed on %s\n", p->name); + printf("stat failed on %s\n", parameters->name); } if (ignore_missing) { return false; } printf("DISK %s - ", _("CRITICAL")); - die(STATE_CRITICAL, _("%s %s: %s\n"), p->name, _("is not accessible"), strerror(errno)); + die(STATE_CRITICAL, _("%s %s: %s\n"), parameters->name, _("is not accessible"), strerror(errno)); } + return true; } -void get_stats(struct parameter_list *p, struct fs_usage *fsp) { - struct parameter_list *p_list; +void get_stats(struct parameter_list *parameters, struct fs_usage *fsp) { struct fs_usage tmpfsp; - int first = 1; + bool first = true; - if (p->group == NULL) { - get_path_stats(p, fsp); + if (parameters->group == NULL) { + get_path_stats(parameters, fsp); } else { /* find all group members */ - for (p_list = path_select_list; p_list; p_list = p_list->name_next) { + for (struct parameter_list *p_list = path_select_list; p_list; p_list = p_list->name_next) { + #ifdef __CYGWIN__ if (strncmp(p_list->name, "/cygdrive/", 10) != 0) { continue; } #endif - if (p_list->group && !(strcmp(p_list->group, p->group))) { + + if (p_list->group && !(strcmp(p_list->group, parameters->group))) { if (!stat_path(p_list)) { continue; } @@ -1094,63 +1057,63 @@ void get_stats(struct parameter_list *p, struct fs_usage *fsp) { /* prevent counting the first FS of a group twice since its parameter_list entry * is used to carry the information of all file systems of the entire group */ if (!first) { - p->total += p_list->total; - p->available += p_list->available; - p->available_to_root += p_list->available_to_root; - p->used += p_list->used; - - p->dused_units += p_list->dused_units; - p->dfree_units += p_list->dfree_units; - p->dtotal_units += p_list->dtotal_units; - p->inodes_total += p_list->inodes_total; - p->inodes_free += p_list->inodes_free; - p->inodes_free_to_root += p_list->inodes_free_to_root; - p->inodes_used += p_list->inodes_used; + parameters->total += p_list->total; + parameters->available += p_list->available; + parameters->available_to_root += p_list->available_to_root; + parameters->used += p_list->used; + + parameters->dused_units += p_list->dused_units; + parameters->dfree_units += p_list->dfree_units; + parameters->dtotal_units += p_list->dtotal_units; + parameters->inodes_total += p_list->inodes_total; + parameters->inodes_free += p_list->inodes_free; + parameters->inodes_free_to_root += p_list->inodes_free_to_root; + parameters->inodes_used += p_list->inodes_used; } - first = 0; + first = false; } if (verbose >= 3) { - printf("Group %s now has: used_units=%lu free_units=%lu total_units=%lu fsu_blocksize=%lu mult=%lu\n", p->group, - p->dused_units, p->dfree_units, p->dtotal_units, tmpfsp.fsu_blocksize, mult); + printf("Group %s now has: used_units=%lu free_units=%lu total_units=%lu fsu_blocksize=%lu mult=%lu\n", parameters->group, + parameters->dused_units, parameters->dfree_units, parameters->dtotal_units, tmpfsp.fsu_blocksize, mult); } } /* modify devname and mountdir for output */ - p->best_match->me_mountdir = p->best_match->me_devname = p->group; + parameters->best_match->me_mountdir = parameters->best_match->me_devname = parameters->group; } /* finally calculate percentages for either plain FS or summed up group */ - p->dused_pct = calculate_percent(p->used, p->used + p->available); /* used + available can never be > uintmax */ - p->dfree_pct = 100.0 - p->dused_pct; - p->dused_inodes_percent = calculate_percent(p->inodes_total - p->inodes_free, p->inodes_total); - p->dfree_inodes_percent = 100 - p->dused_inodes_percent; + parameters->dused_pct = calculate_percent(parameters->used, parameters->used + parameters->available); /* used + available can never be > uintmax */ + parameters->dfree_pct = 100.0 - parameters->dused_pct; + parameters->dused_inodes_percent = calculate_percent(parameters->inodes_total - parameters->inodes_free, parameters->inodes_total); + parameters->dfree_inodes_percent = 100 - parameters->dused_inodes_percent; } -void get_path_stats(struct parameter_list *p, struct fs_usage *fsp) { - p->available = fsp->fsu_bavail; - p->available_to_root = fsp->fsu_bfree; - p->used = fsp->fsu_blocks - fsp->fsu_bfree; +void get_path_stats(struct parameter_list *parameters, struct fs_usage *fsp) { + parameters->available = fsp->fsu_bavail; + parameters->available_to_root = fsp->fsu_bfree; + parameters->used = fsp->fsu_blocks - fsp->fsu_bfree; if (freespace_ignore_reserved) { /* option activated : we subtract the root-reserved space from the total */ - p->total = fsp->fsu_blocks - p->available_to_root + p->available; + parameters->total = fsp->fsu_blocks - parameters->available_to_root + parameters->available; } else { /* default behaviour : take all the blocks into account */ - p->total = fsp->fsu_blocks; + parameters->total = fsp->fsu_blocks; } - p->dused_units = p->used * fsp->fsu_blocksize / mult; - p->dfree_units = p->available * fsp->fsu_blocksize / mult; - p->dtotal_units = p->total * fsp->fsu_blocksize / mult; + parameters->dused_units = parameters->used * fsp->fsu_blocksize / mult; + parameters->dfree_units = parameters->available * fsp->fsu_blocksize / mult; + parameters->dtotal_units = parameters->total * fsp->fsu_blocksize / mult; /* Free file nodes. Not sure the workaround is required, but in case...*/ - p->inodes_free = fsp->fsu_ffree; - p->inodes_free_to_root = fsp->fsu_ffree; /* Free file nodes for root. */ - p->inodes_used = fsp->fsu_files - fsp->fsu_ffree; + parameters->inodes_free = fsp->fsu_ffree; + parameters->inodes_free_to_root = fsp->fsu_ffree; /* Free file nodes for root. */ + parameters->inodes_used = fsp->fsu_files - fsp->fsu_ffree; if (freespace_ignore_reserved) { /* option activated : we subtract the root-reserved inodes from the total */ /* not all OS report fsp->fsu_favail, only the ones with statvfs syscall */ /* for others, fsp->fsu_ffree == fsp->fsu_favail */ - p->inodes_total = fsp->fsu_files - p->inodes_free_to_root + p->inodes_free; + parameters->inodes_total = fsp->fsu_files - parameters->inodes_free_to_root + parameters->inodes_free; } else { /* default behaviour : take all the inodes into account */ - p->inodes_total = fsp->fsu_files; + parameters->inodes_total = fsp->fsu_files; } - np_add_name(&seen, p->best_match->me_mountdir); + np_add_name(&seen, parameters->best_match->me_mountdir); } -- cgit v1.2.3-74-g34f1 From ef3045b97eea23a4dec3197277e5ff4e5afc5c71 Mon Sep 17 00:00:00 2001 From: Andre Klärner Date: Mon, 17 Mar 2025 16:13:46 +0100 Subject: change error message for missing certificate The old error message is quite similar to the openssl `failed to retrieve issuer certificate` and can mislead users to troubleshooting certificate stores. The new message should be distinct enough to make it clear to users that this is not a problem raised by the underlying SSL implementation, but a problem inside monitoring-plugins. --- plugins/sslutils.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'plugins') diff --git a/plugins/sslutils.c b/plugins/sslutils.c index 719de575..96740b3a 100644 --- a/plugins/sslutils.c +++ b/plugins/sslutils.c @@ -201,7 +201,7 @@ int np_net_ssl_check_certificate(X509 *certificate, int days_till_exp_warn, int time_t tm_t; if (!certificate) { - printf("%s\n", _("CRITICAL - Cannot retrieve server certificate.")); + printf("%s\n", _("CRITICAL - No server certificate present to inspect.")); return STATE_CRITICAL; } -- cgit v1.2.3-74-g34f1 From 7b53cbbd265ed135941bf59da77ed22b8664b6eb Mon Sep 17 00:00:00 2001 From: Lorenz Kästle <12514511+RincewindsHat@users.noreply.github.com> Date: Mon, 17 Mar 2025 20:21:58 +0100 Subject: check_disk: Little fixes and improvements --- plugins/check_disk.c | 31 +++++++++++++++++++++++-------- 1 file changed, 23 insertions(+), 8 deletions(-) (limited to 'plugins') diff --git a/plugins/check_disk.c b/plugins/check_disk.c index e16c453d..a333a8b5 100644 --- a/plugins/check_disk.c +++ b/plugins/check_disk.c @@ -101,9 +101,9 @@ static void set_all_thresholds(struct parameter_list *path); static void print_help(void); void print_usage(void); static double calculate_percent(uintmax_t /*value*/, uintmax_t /*total*/); -static bool stat_path(struct parameter_list *p); -static void get_stats(struct parameter_list *p, struct fs_usage *fsp); -static void get_path_stats(struct parameter_list *p, struct fs_usage *fsp); +static bool stat_path(struct parameter_list * /*parameters*/); +static void get_stats(struct parameter_list * /*parameters*/, struct fs_usage *fsp); +static void get_path_stats(struct parameter_list * /*parameters*/, struct fs_usage *fsp); static char *units; static uintmax_t mult = 1024 * 1024; @@ -624,7 +624,7 @@ int process_arguments(int argc, char **argv) { case 'P': display_inodes_perfdata = true; break; - case 'p': /* select path */ + case 'p': /* select path */ { if (!(warn_freespace_units || crit_freespace_units || warn_freespace_percent || crit_freespace_percent || warn_usedspace_units || crit_usedspace_units || warn_usedspace_percent || crit_usedspace_percent || warn_usedinodes_percent || crit_usedinodes_percent || warn_freeinodes_percent || crit_freeinodes_percent)) { @@ -656,7 +656,7 @@ int process_arguments(int argc, char **argv) { np_set_best_match(se, mount_list, exact_match); path_selected = true; - break; + } break; case 'x': /* exclude path or partition */ np_add_name(&dp_exclude_list, optarg); break; @@ -778,6 +778,7 @@ int process_arguments(int argc, char **argv) { } /* add parameter if not found. overwrite thresholds if path has already been added */ + struct parameter_list *se = NULL; if (!(se = np_find_parameter(path_select_list, me->me_mountdir))) { se = np_add_parameter(&path_select_list, me->me_mountdir); } @@ -804,7 +805,7 @@ int process_arguments(int argc, char **argv) { case 'M': /* display mountpoint */ display_mntp = true; break; - case 'C': + case 'C': { /* add all mount entries to path_select list if no partitions have been explicitly defined using -p */ if (!path_selected) { struct parameter_list *path; @@ -832,7 +833,7 @@ int process_arguments(int argc, char **argv) { path_selected = false; group = NULL; - break; + } break; case 'V': /* version */ print_revision(progname, NP_VERSION); exit(STATE_UNKNOWN); @@ -843,18 +844,31 @@ int process_arguments(int argc, char **argv) { usage(_("Unknown argument")); } } + if (verbose > 0) { + printf("ping\n"); + } /* Support for "check_disk warn crit [fs]" with thresholds at used% level */ int index = optind; + if (warn_usedspace_percent == NULL && argc > index && is_intnonneg(argv[index])) { + if (verbose > 0) { + printf("Got an positional warn threshold: %s\n", argv[index]); + } warn_usedspace_percent = argv[index++]; } if (crit_usedspace_percent == NULL && argc > index && is_intnonneg(argv[index])) { + if (verbose > 0) { + printf("Got an positional crit threshold: %s\n", argv[index]); + } crit_usedspace_percent = argv[index++]; } if (argc > index) { + if (verbose > 0) { + printf("Got an positional filesystem: %s\n", argv[index]); + } struct parameter_list *se = np_add_parameter(&path_select_list, strdup(argv[index++])); path_selected = true; set_all_thresholds(se); @@ -1081,7 +1095,8 @@ void get_stats(struct parameter_list *parameters, struct fs_usage *fsp) { parameters->best_match->me_mountdir = parameters->best_match->me_devname = parameters->group; } /* finally calculate percentages for either plain FS or summed up group */ - parameters->dused_pct = calculate_percent(parameters->used, parameters->used + parameters->available); /* used + available can never be > uintmax */ + parameters->dused_pct = + calculate_percent(parameters->used, parameters->used + parameters->available); /* used + available can never be > uintmax */ parameters->dfree_pct = 100.0 - parameters->dused_pct; parameters->dused_inodes_percent = calculate_percent(parameters->inodes_total - parameters->inodes_free, parameters->inodes_total); parameters->dfree_inodes_percent = 100 - parameters->dused_inodes_percent; -- cgit v1.2.3-74-g34f1 From 096afc90a79f462e6c705764451273a887fd8c0e Mon Sep 17 00:00:00 2001 From: Lorenz Kästle <12514511+RincewindsHat@users.noreply.github.com> Date: Mon, 17 Mar 2025 20:37:28 +0100 Subject: check_disk: reset single file system result in between checks --- plugins/check_disk.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'plugins') diff --git a/plugins/check_disk.c b/plugins/check_disk.c index a333a8b5..f67f3d57 100644 --- a/plugins/check_disk.c +++ b/plugins/check_disk.c @@ -217,6 +217,9 @@ int main(int argc, char **argv) { printf("Group of %s: %s\n", path->name, path->group); } + // reset disk result + disk_result = STATE_UNKNOWN; + struct mount_entry *mount_entry = path->best_match; if (!mount_entry) { -- cgit v1.2.3-74-g34f1 From 285db2a9fa25519cacd48a76347ae2dee0c06605 Mon Sep 17 00:00:00 2001 From: Lorenz Kästle <12514511+RincewindsHat@users.noreply.github.com> Date: Tue, 18 Mar 2025 14:36:20 +0100 Subject: Move disk specific stuff from lib to plugin specific directory --- lib/Makefile.am | 3 +- lib/utils_disk.c | 255 -------------------------------------- lib/utils_disk.h | 48 ------- plugins/Makefile.am | 2 + plugins/check_disk.d/utils_disk.c | 255 ++++++++++++++++++++++++++++++++++++++ plugins/check_disk.d/utils_disk.h | 48 +++++++ 6 files changed, 306 insertions(+), 305 deletions(-) delete mode 100644 lib/utils_disk.c delete mode 100644 lib/utils_disk.h create mode 100644 plugins/check_disk.d/utils_disk.c create mode 100644 plugins/check_disk.d/utils_disk.h (limited to 'plugins') diff --git a/lib/Makefile.am b/lib/Makefile.am index e41201c4..a9f3ff40 100644 --- a/lib/Makefile.am +++ b/lib/Makefile.am @@ -7,10 +7,9 @@ noinst_LIBRARIES = libmonitoringplug.a AM_CPPFLAGS = -DNP_STATE_DIR_PREFIX=\"$(localstatedir)\" \ -I$(srcdir) -I$(top_srcdir)/gl -I$(top_srcdir)/intl -I$(top_srcdir)/plugins -libmonitoringplug_a_SOURCES = utils_base.c utils_disk.c utils_tcp.c utils_cmd.c maxfd.c output.c perfdata.c output.c thresholds.c vendor/cJSON/cJSON.c +libmonitoringplug_a_SOURCES = utils_base.c utils_tcp.c utils_cmd.c maxfd.c output.c perfdata.c output.c thresholds.c vendor/cJSON/cJSON.c EXTRA_DIST = utils_base.h \ - utils_disk.h \ utils_tcp.h \ utils_cmd.h \ parse_ini.h \ diff --git a/lib/utils_disk.c b/lib/utils_disk.c deleted file mode 100644 index 2b761f5e..00000000 --- a/lib/utils_disk.c +++ /dev/null @@ -1,255 +0,0 @@ -/***************************************************************************** - * - * Library for check_disk - * - * License: GPL - * Copyright (c) 1999-2024 Monitoring Plugins Development Team - * - * Description: - * - * This file contains utilities for check_disk. These are tested by libtap - * - * - * 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 . - * - * - *****************************************************************************/ - -#include "common.h" -#include "utils_disk.h" -#include "gl/fsusage.h" -#include - -void np_add_name(struct name_list **list, const char *name) { - struct name_list *new_entry; - new_entry = (struct name_list *)malloc(sizeof *new_entry); - new_entry->name = (char *)name; - new_entry->next = *list; - *list = new_entry; -} - -/* @brief Initialises a new regex at the begin of list via regcomp(3) - * - * @details if the regex fails to compile the error code of regcomp(3) is returned - * and list is not modified, otherwise list is modified to point to the new - * element - * @param list Pointer to a linked list of regex_list elements - * @param regex the string containing the regex which should be inserted into the list - * @param clags the cflags parameter for regcomp(3) - */ -int np_add_regex(struct regex_list **list, const char *regex, int cflags) { - struct regex_list *new_entry = (struct regex_list *)malloc(sizeof *new_entry); - - if (new_entry == NULL) { - die(STATE_UNKNOWN, _("Cannot allocate memory: %s"), strerror(errno)); - } - - int regcomp_result = regcomp(&new_entry->regex, regex, cflags); - - if (!regcomp_result) { - // regcomp succeeded - new_entry->next = *list; - *list = new_entry; - - return 0; - } else { - // regcomp failed - free(new_entry); - - return regcomp_result; - } -} - -/* Initialises a new parameter at the end of list */ -struct parameter_list *np_add_parameter(struct parameter_list **list, const char *name) { - struct parameter_list *current = *list; - struct parameter_list *new_path; - new_path = (struct parameter_list *)malloc(sizeof *new_path); - new_path->name = (char *)malloc(strlen(name) + 1); - new_path->best_match = NULL; - new_path->name_next = NULL; - new_path->name_prev = NULL; - new_path->freespace_bytes = NULL; - new_path->freespace_units = NULL; - new_path->freespace_percent = NULL; - new_path->usedspace_bytes = NULL; - new_path->usedspace_units = NULL; - new_path->usedspace_percent = NULL; - new_path->usedinodes_percent = NULL; - new_path->freeinodes_percent = NULL; - new_path->group = NULL; - new_path->dfree_pct = -1; - new_path->dused_pct = -1; - new_path->total = 0; - new_path->available = 0; - new_path->available_to_root = 0; - new_path->used = 0; - new_path->dused_units = 0; - new_path->dfree_units = 0; - new_path->dtotal_units = 0; - new_path->inodes_total = 0; - new_path->inodes_free = 0; - new_path->inodes_free_to_root = 0; - new_path->inodes_used = 0; - new_path->dused_inodes_percent = 0; - new_path->dfree_inodes_percent = 0; - - strcpy(new_path->name, name); - - if (current == NULL) { - *list = new_path; - new_path->name_prev = NULL; - } else { - while (current->name_next) { - current = current->name_next; - } - current->name_next = new_path; - new_path->name_prev = current; - } - return new_path; -} - -/* Delete a given parameter from list and return pointer to next element*/ -struct parameter_list *np_del_parameter(struct parameter_list *item, struct parameter_list *prev) { - if (item == NULL) { - return NULL; - } - struct parameter_list *next; - - if (item->name_next) - next = item->name_next; - else - next = NULL; - - if (next) - next->name_prev = prev; - - if (prev) - prev->name_next = next; - - if (item->name) { - free(item->name); - } - free(item); - - return next; -} - -/* returns a pointer to the struct found in the list */ -struct parameter_list *np_find_parameter(struct parameter_list *list, const char *name) { - struct parameter_list *temp_list; - for (temp_list = list; temp_list; temp_list = temp_list->name_next) { - if (!strcmp(temp_list->name, name)) - return temp_list; - } - - return NULL; -} - -void np_set_best_match(struct parameter_list *desired, struct mount_entry *mount_list, bool exact) { - struct parameter_list *d; - for (d = desired; d; d = d->name_next) { - if (!d->best_match) { - struct mount_entry *me; - size_t name_len = strlen(d->name); - size_t best_match_len = 0; - struct mount_entry *best_match = NULL; - struct fs_usage fsp; - - /* set best match if path name exactly matches a mounted device name */ - for (me = mount_list; me; me = me->me_next) { - if (strcmp(me->me_devname, d->name) == 0) { - if (get_fs_usage(me->me_mountdir, me->me_devname, &fsp) >= 0) { - best_match = me; - } - } - } - - /* set best match by directory name if no match was found by devname */ - if (!best_match) { - for (me = mount_list; me; me = me->me_next) { - size_t len = strlen(me->me_mountdir); - if ((!exact && - (best_match_len <= len && len <= name_len && (len == 1 || strncmp(me->me_mountdir, d->name, len) == 0))) || - (exact && strcmp(me->me_mountdir, d->name) == 0)) { - if (get_fs_usage(me->me_mountdir, me->me_devname, &fsp) >= 0) { - best_match = me; - best_match_len = len; - } - } - } - } - - if (best_match) { - d->best_match = best_match; - } else { - d->best_match = NULL; /* Not sure why this is needed as it should be null on initialisation */ - } - } - } -} - -/* Returns true if name is in list */ -bool np_find_name(struct name_list *list, const char *name) { - const struct name_list *n; - - if (list == NULL || name == NULL) { - return false; - } - for (n = list; n; n = n->next) { - if (!strcmp(name, n->name)) { - return true; - } - } - return false; -} - -/* Returns true if name is in list */ -bool np_find_regmatch(struct regex_list *list, const char *name) { - int len; - regmatch_t m; - - if (name == NULL) { - return false; - } - - len = strlen(name); - - for (; list; list = list->next) { - /* Emulate a full match as if surrounded with ^( )$ - by checking whether the match spans the whole name */ - if (!regexec(&list->regex, name, 1, &m, 0) && m.rm_so == 0 && m.rm_eo == len) { - return true; - } - } - - return false; -} - -bool np_seen_name(struct name_list *list, const char *name) { - const struct name_list *s; - for (s = list; s; s = s->next) { - if (!strcmp(s->name, name)) { - return true; - } - } - return false; -} - -bool np_regex_match_mount_entry(struct mount_entry *me, regex_t *re) { - if (regexec(re, me->me_devname, (size_t)0, NULL, 0) == 0 || regexec(re, me->me_mountdir, (size_t)0, NULL, 0) == 0) { - return true; - } - return false; -} diff --git a/lib/utils_disk.h b/lib/utils_disk.h deleted file mode 100644 index c5e81dc1..00000000 --- a/lib/utils_disk.h +++ /dev/null @@ -1,48 +0,0 @@ -/* Header file for utils_disk */ - -#include "mountlist.h" -#include "utils_base.h" -#include "regex.h" - -struct name_list { - char *name; - struct name_list *next; -}; - -struct regex_list { - regex_t regex; - struct regex_list *next; -}; - -struct parameter_list { - char *name; - thresholds *freespace_bytes; - thresholds *freespace_units; - thresholds *freespace_percent; - thresholds *usedspace_bytes; - thresholds *usedspace_units; - thresholds *usedspace_percent; - thresholds *usedinodes_percent; - thresholds *freeinodes_percent; - char *group; - struct mount_entry *best_match; - struct parameter_list *name_next; - struct parameter_list *name_prev; - uintmax_t total, available, available_to_root, used, inodes_free, inodes_free_to_root, inodes_used, inodes_total; - double dfree_pct, dused_pct; - uint64_t dused_units, dfree_units, dtotal_units; - double dused_inodes_percent, dfree_inodes_percent; -}; - -void np_add_name(struct name_list **list, const char *name); -bool np_find_name(struct name_list *list, const char *name); -bool np_seen_name(struct name_list *list, const char *name); -int np_add_regex(struct regex_list **list, const char *regex, int cflags); -bool np_find_regmatch(struct regex_list *list, const char *name); -struct parameter_list *np_add_parameter(struct parameter_list **list, const char *name); -struct parameter_list *np_find_parameter(struct parameter_list *list, const char *name); -struct parameter_list *np_del_parameter(struct parameter_list *item, struct parameter_list *prev); - -int search_parameter_list(struct parameter_list *list, const char *name); -void np_set_best_match(struct parameter_list *desired, struct mount_entry *mount_list, bool exact); -bool np_regex_match_mount_entry(struct mount_entry *me, regex_t *re); diff --git a/plugins/Makefile.am b/plugins/Makefile.am index e2bed4c3..30283cb4 100644 --- a/plugins/Makefile.am +++ b/plugins/Makefile.am @@ -55,6 +55,7 @@ EXTRA_DIST = t \ check_hpjd.d \ check_game.d \ check_radius.d \ + check_disk.d \ check_time.d \ check_nagios.d \ check_dbi.d \ @@ -119,6 +120,7 @@ check_curl_LDADD = $(NETLIBS) $(LIBCURLLIBS) $(SSLOBJS) $(URIPARSERLIBS) picohtt check_dbi_LDADD = $(NETLIBS) $(DBILIBS) check_dig_LDADD = $(NETLIBS) check_disk_LDADD = $(BASEOBJS) +check_disk_SOURCES = check_disk.c check_disk.d/utils_disk.c check_dns_LDADD = $(NETLIBS) check_dummy_LDADD = $(BASEOBJS) check_fping_LDADD = $(NETLIBS) diff --git a/plugins/check_disk.d/utils_disk.c b/plugins/check_disk.d/utils_disk.c new file mode 100644 index 00000000..2b761f5e --- /dev/null +++ b/plugins/check_disk.d/utils_disk.c @@ -0,0 +1,255 @@ +/***************************************************************************** + * + * Library for check_disk + * + * License: GPL + * Copyright (c) 1999-2024 Monitoring Plugins Development Team + * + * Description: + * + * This file contains utilities for check_disk. These are tested by libtap + * + * + * 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 . + * + * + *****************************************************************************/ + +#include "common.h" +#include "utils_disk.h" +#include "gl/fsusage.h" +#include + +void np_add_name(struct name_list **list, const char *name) { + struct name_list *new_entry; + new_entry = (struct name_list *)malloc(sizeof *new_entry); + new_entry->name = (char *)name; + new_entry->next = *list; + *list = new_entry; +} + +/* @brief Initialises a new regex at the begin of list via regcomp(3) + * + * @details if the regex fails to compile the error code of regcomp(3) is returned + * and list is not modified, otherwise list is modified to point to the new + * element + * @param list Pointer to a linked list of regex_list elements + * @param regex the string containing the regex which should be inserted into the list + * @param clags the cflags parameter for regcomp(3) + */ +int np_add_regex(struct regex_list **list, const char *regex, int cflags) { + struct regex_list *new_entry = (struct regex_list *)malloc(sizeof *new_entry); + + if (new_entry == NULL) { + die(STATE_UNKNOWN, _("Cannot allocate memory: %s"), strerror(errno)); + } + + int regcomp_result = regcomp(&new_entry->regex, regex, cflags); + + if (!regcomp_result) { + // regcomp succeeded + new_entry->next = *list; + *list = new_entry; + + return 0; + } else { + // regcomp failed + free(new_entry); + + return regcomp_result; + } +} + +/* Initialises a new parameter at the end of list */ +struct parameter_list *np_add_parameter(struct parameter_list **list, const char *name) { + struct parameter_list *current = *list; + struct parameter_list *new_path; + new_path = (struct parameter_list *)malloc(sizeof *new_path); + new_path->name = (char *)malloc(strlen(name) + 1); + new_path->best_match = NULL; + new_path->name_next = NULL; + new_path->name_prev = NULL; + new_path->freespace_bytes = NULL; + new_path->freespace_units = NULL; + new_path->freespace_percent = NULL; + new_path->usedspace_bytes = NULL; + new_path->usedspace_units = NULL; + new_path->usedspace_percent = NULL; + new_path->usedinodes_percent = NULL; + new_path->freeinodes_percent = NULL; + new_path->group = NULL; + new_path->dfree_pct = -1; + new_path->dused_pct = -1; + new_path->total = 0; + new_path->available = 0; + new_path->available_to_root = 0; + new_path->used = 0; + new_path->dused_units = 0; + new_path->dfree_units = 0; + new_path->dtotal_units = 0; + new_path->inodes_total = 0; + new_path->inodes_free = 0; + new_path->inodes_free_to_root = 0; + new_path->inodes_used = 0; + new_path->dused_inodes_percent = 0; + new_path->dfree_inodes_percent = 0; + + strcpy(new_path->name, name); + + if (current == NULL) { + *list = new_path; + new_path->name_prev = NULL; + } else { + while (current->name_next) { + current = current->name_next; + } + current->name_next = new_path; + new_path->name_prev = current; + } + return new_path; +} + +/* Delete a given parameter from list and return pointer to next element*/ +struct parameter_list *np_del_parameter(struct parameter_list *item, struct parameter_list *prev) { + if (item == NULL) { + return NULL; + } + struct parameter_list *next; + + if (item->name_next) + next = item->name_next; + else + next = NULL; + + if (next) + next->name_prev = prev; + + if (prev) + prev->name_next = next; + + if (item->name) { + free(item->name); + } + free(item); + + return next; +} + +/* returns a pointer to the struct found in the list */ +struct parameter_list *np_find_parameter(struct parameter_list *list, const char *name) { + struct parameter_list *temp_list; + for (temp_list = list; temp_list; temp_list = temp_list->name_next) { + if (!strcmp(temp_list->name, name)) + return temp_list; + } + + return NULL; +} + +void np_set_best_match(struct parameter_list *desired, struct mount_entry *mount_list, bool exact) { + struct parameter_list *d; + for (d = desired; d; d = d->name_next) { + if (!d->best_match) { + struct mount_entry *me; + size_t name_len = strlen(d->name); + size_t best_match_len = 0; + struct mount_entry *best_match = NULL; + struct fs_usage fsp; + + /* set best match if path name exactly matches a mounted device name */ + for (me = mount_list; me; me = me->me_next) { + if (strcmp(me->me_devname, d->name) == 0) { + if (get_fs_usage(me->me_mountdir, me->me_devname, &fsp) >= 0) { + best_match = me; + } + } + } + + /* set best match by directory name if no match was found by devname */ + if (!best_match) { + for (me = mount_list; me; me = me->me_next) { + size_t len = strlen(me->me_mountdir); + if ((!exact && + (best_match_len <= len && len <= name_len && (len == 1 || strncmp(me->me_mountdir, d->name, len) == 0))) || + (exact && strcmp(me->me_mountdir, d->name) == 0)) { + if (get_fs_usage(me->me_mountdir, me->me_devname, &fsp) >= 0) { + best_match = me; + best_match_len = len; + } + } + } + } + + if (best_match) { + d->best_match = best_match; + } else { + d->best_match = NULL; /* Not sure why this is needed as it should be null on initialisation */ + } + } + } +} + +/* Returns true if name is in list */ +bool np_find_name(struct name_list *list, const char *name) { + const struct name_list *n; + + if (list == NULL || name == NULL) { + return false; + } + for (n = list; n; n = n->next) { + if (!strcmp(name, n->name)) { + return true; + } + } + return false; +} + +/* Returns true if name is in list */ +bool np_find_regmatch(struct regex_list *list, const char *name) { + int len; + regmatch_t m; + + if (name == NULL) { + return false; + } + + len = strlen(name); + + for (; list; list = list->next) { + /* Emulate a full match as if surrounded with ^( )$ + by checking whether the match spans the whole name */ + if (!regexec(&list->regex, name, 1, &m, 0) && m.rm_so == 0 && m.rm_eo == len) { + return true; + } + } + + return false; +} + +bool np_seen_name(struct name_list *list, const char *name) { + const struct name_list *s; + for (s = list; s; s = s->next) { + if (!strcmp(s->name, name)) { + return true; + } + } + return false; +} + +bool np_regex_match_mount_entry(struct mount_entry *me, regex_t *re) { + if (regexec(re, me->me_devname, (size_t)0, NULL, 0) == 0 || regexec(re, me->me_mountdir, (size_t)0, NULL, 0) == 0) { + return true; + } + return false; +} diff --git a/plugins/check_disk.d/utils_disk.h b/plugins/check_disk.d/utils_disk.h new file mode 100644 index 00000000..c5e81dc1 --- /dev/null +++ b/plugins/check_disk.d/utils_disk.h @@ -0,0 +1,48 @@ +/* Header file for utils_disk */ + +#include "mountlist.h" +#include "utils_base.h" +#include "regex.h" + +struct name_list { + char *name; + struct name_list *next; +}; + +struct regex_list { + regex_t regex; + struct regex_list *next; +}; + +struct parameter_list { + char *name; + thresholds *freespace_bytes; + thresholds *freespace_units; + thresholds *freespace_percent; + thresholds *usedspace_bytes; + thresholds *usedspace_units; + thresholds *usedspace_percent; + thresholds *usedinodes_percent; + thresholds *freeinodes_percent; + char *group; + struct mount_entry *best_match; + struct parameter_list *name_next; + struct parameter_list *name_prev; + uintmax_t total, available, available_to_root, used, inodes_free, inodes_free_to_root, inodes_used, inodes_total; + double dfree_pct, dused_pct; + uint64_t dused_units, dfree_units, dtotal_units; + double dused_inodes_percent, dfree_inodes_percent; +}; + +void np_add_name(struct name_list **list, const char *name); +bool np_find_name(struct name_list *list, const char *name); +bool np_seen_name(struct name_list *list, const char *name); +int np_add_regex(struct regex_list **list, const char *regex, int cflags); +bool np_find_regmatch(struct regex_list *list, const char *name); +struct parameter_list *np_add_parameter(struct parameter_list **list, const char *name); +struct parameter_list *np_find_parameter(struct parameter_list *list, const char *name); +struct parameter_list *np_del_parameter(struct parameter_list *item, struct parameter_list *prev); + +int search_parameter_list(struct parameter_list *list, const char *name); +void np_set_best_match(struct parameter_list *desired, struct mount_entry *mount_list, bool exact); +bool np_regex_match_mount_entry(struct mount_entry *me, regex_t *re); -- cgit v1.2.3-74-g34f1 From 8ccff07bed03046a97637a54d45a9ffe77edc235 Mon Sep 17 00:00:00 2001 From: Lorenz Kästle <12514511+RincewindsHat@users.noreply.github.com> Date: Tue, 18 Mar 2025 14:37:02 +0100 Subject: refactor check_disk.d code a bit --- plugins/check_disk.d/utils_disk.c | 139 +++++++++++++++++++------------------- plugins/check_disk.d/utils_disk.h | 39 ++++++++--- 2 files changed, 100 insertions(+), 78 deletions(-) (limited to 'plugins') diff --git a/plugins/check_disk.d/utils_disk.c b/plugins/check_disk.d/utils_disk.c index 2b761f5e..1d806715 100644 --- a/plugins/check_disk.d/utils_disk.c +++ b/plugins/check_disk.d/utils_disk.c @@ -63,12 +63,46 @@ int np_add_regex(struct regex_list **list, const char *regex, int cflags) { *list = new_entry; return 0; - } else { - // regcomp failed - free(new_entry); - - return regcomp_result; } + // regcomp failed + free(new_entry); + + return regcomp_result; +} + +struct parameter_list parameter_list_init(const char *name) { + struct parameter_list result = { + .name = strdup(name), + .best_match = NULL, + + .name_next = NULL, + .name_prev = NULL, + + .freespace_units = NULL, + .freespace_percent = NULL, + .usedspace_units = NULL, + .usedspace_percent = NULL, + .usedinodes_percent = NULL, + .freeinodes_percent = NULL, + + .group = NULL, + .dfree_pct = -1, + .dused_pct = -1, + .total = 0, + .available = 0, + .available_to_root = 0, + .used = 0, + .dused_units = 0, + .dfree_units = 0, + .dtotal_units = 0, + .inodes_total = 0, + .inodes_free = 0, + .inodes_free_to_root = 0, + .inodes_used = 0, + .dused_inodes_percent = 0, + .dfree_inodes_percent = 0, + }; + return result; } /* Initialises a new parameter at the end of list */ @@ -76,36 +110,8 @@ struct parameter_list *np_add_parameter(struct parameter_list **list, const char struct parameter_list *current = *list; struct parameter_list *new_path; new_path = (struct parameter_list *)malloc(sizeof *new_path); - new_path->name = (char *)malloc(strlen(name) + 1); - new_path->best_match = NULL; - new_path->name_next = NULL; - new_path->name_prev = NULL; - new_path->freespace_bytes = NULL; - new_path->freespace_units = NULL; - new_path->freespace_percent = NULL; - new_path->usedspace_bytes = NULL; - new_path->usedspace_units = NULL; - new_path->usedspace_percent = NULL; - new_path->usedinodes_percent = NULL; - new_path->freeinodes_percent = NULL; - new_path->group = NULL; - new_path->dfree_pct = -1; - new_path->dused_pct = -1; - new_path->total = 0; - new_path->available = 0; - new_path->available_to_root = 0; - new_path->used = 0; - new_path->dused_units = 0; - new_path->dfree_units = 0; - new_path->dtotal_units = 0; - new_path->inodes_total = 0; - new_path->inodes_free = 0; - new_path->inodes_free_to_root = 0; - new_path->inodes_used = 0; - new_path->dused_inodes_percent = 0; - new_path->dfree_inodes_percent = 0; - - strcpy(new_path->name, name); + + *new_path = parameter_list_init(name); if (current == NULL) { *list = new_path; @@ -125,18 +131,22 @@ struct parameter_list *np_del_parameter(struct parameter_list *item, struct para if (item == NULL) { return NULL; } + struct parameter_list *next; - if (item->name_next) + if (item->name_next) { next = item->name_next; - else + } else { next = NULL; + } - if (next) + if (next) { next->name_prev = prev; + } - if (prev) + if (prev) { prev->name_next = next; + } if (item->name) { free(item->name); @@ -148,43 +158,42 @@ struct parameter_list *np_del_parameter(struct parameter_list *item, struct para /* returns a pointer to the struct found in the list */ struct parameter_list *np_find_parameter(struct parameter_list *list, const char *name) { - struct parameter_list *temp_list; - for (temp_list = list; temp_list; temp_list = temp_list->name_next) { - if (!strcmp(temp_list->name, name)) + for (struct parameter_list *temp_list = list; temp_list; temp_list = temp_list->name_next) { + if (!strcmp(temp_list->name, name)) { return temp_list; + } } return NULL; } void np_set_best_match(struct parameter_list *desired, struct mount_entry *mount_list, bool exact) { - struct parameter_list *d; - for (d = desired; d; d = d->name_next) { + for (struct parameter_list *d = desired; d; d = d->name_next) { if (!d->best_match) { - struct mount_entry *me; + struct mount_entry *mount_entry; size_t name_len = strlen(d->name); size_t best_match_len = 0; struct mount_entry *best_match = NULL; struct fs_usage fsp; /* set best match if path name exactly matches a mounted device name */ - for (me = mount_list; me; me = me->me_next) { - if (strcmp(me->me_devname, d->name) == 0) { - if (get_fs_usage(me->me_mountdir, me->me_devname, &fsp) >= 0) { - best_match = me; + for (mount_entry = mount_list; mount_entry; mount_entry = mount_entry->me_next) { + if (strcmp(mount_entry->me_devname, d->name) == 0) { + if (get_fs_usage(mount_entry->me_mountdir, mount_entry->me_devname, &fsp) >= 0) { + best_match = mount_entry; } } } /* set best match by directory name if no match was found by devname */ if (!best_match) { - for (me = mount_list; me; me = me->me_next) { - size_t len = strlen(me->me_mountdir); - if ((!exact && - (best_match_len <= len && len <= name_len && (len == 1 || strncmp(me->me_mountdir, d->name, len) == 0))) || - (exact && strcmp(me->me_mountdir, d->name) == 0)) { - if (get_fs_usage(me->me_mountdir, me->me_devname, &fsp) >= 0) { - best_match = me; + for (mount_entry = mount_list; mount_entry; mount_entry = mount_entry->me_next) { + size_t len = strlen(mount_entry->me_mountdir); + if ((!exact && (best_match_len <= len && len <= name_len && + (len == 1 || strncmp(mount_entry->me_mountdir, d->name, len) == 0))) || + (exact && strcmp(mount_entry->me_mountdir, d->name) == 0)) { + if (get_fs_usage(mount_entry->me_mountdir, mount_entry->me_devname, &fsp) >= 0) { + best_match = mount_entry; best_match_len = len; } } @@ -202,12 +211,10 @@ void np_set_best_match(struct parameter_list *desired, struct mount_entry *mount /* Returns true if name is in list */ bool np_find_name(struct name_list *list, const char *name) { - const struct name_list *n; - if (list == NULL || name == NULL) { return false; } - for (n = list; n; n = n->next) { + for (struct name_list *n = list; n; n = n->next) { if (!strcmp(name, n->name)) { return true; } @@ -217,18 +224,16 @@ bool np_find_name(struct name_list *list, const char *name) { /* Returns true if name is in list */ bool np_find_regmatch(struct regex_list *list, const char *name) { - int len; - regmatch_t m; - if (name == NULL) { return false; } - len = strlen(name); + int len = strlen(name); for (; list; list = list->next) { /* Emulate a full match as if surrounded with ^( )$ by checking whether the match spans the whole name */ + regmatch_t m; if (!regexec(&list->regex, name, 1, &m, 0) && m.rm_so == 0 && m.rm_eo == len) { return true; } @@ -238,8 +243,7 @@ bool np_find_regmatch(struct regex_list *list, const char *name) { } bool np_seen_name(struct name_list *list, const char *name) { - const struct name_list *s; - for (s = list; s; s = s->next) { + for (struct name_list *s = list; s; s = s->next) { if (!strcmp(s->name, name)) { return true; } @@ -248,8 +252,5 @@ bool np_seen_name(struct name_list *list, const char *name) { } bool np_regex_match_mount_entry(struct mount_entry *me, regex_t *re) { - if (regexec(re, me->me_devname, (size_t)0, NULL, 0) == 0 || regexec(re, me->me_mountdir, (size_t)0, NULL, 0) == 0) { - return true; - } - return false; + return ((regexec(re, me->me_devname, (size_t)0, NULL, 0) == 0) || (regexec(re, me->me_mountdir, (size_t)0, NULL, 0) == 0)); } diff --git a/plugins/check_disk.d/utils_disk.h b/plugins/check_disk.d/utils_disk.h index c5e81dc1..1c68fed9 100644 --- a/plugins/check_disk.d/utils_disk.h +++ b/plugins/check_disk.d/utils_disk.h @@ -1,8 +1,10 @@ /* Header file for utils_disk */ -#include "mountlist.h" +#include "../../config.h" +#include "../../gl/mountlist.h" #include "utils_base.h" #include "regex.h" +#include struct name_list { char *name; @@ -16,22 +18,39 @@ struct regex_list { struct parameter_list { char *name; - thresholds *freespace_bytes; + char *group; + thresholds *freespace_units; thresholds *freespace_percent; - thresholds *usedspace_bytes; thresholds *usedspace_units; thresholds *usedspace_percent; + thresholds *usedinodes_percent; thresholds *freeinodes_percent; - char *group; + struct mount_entry *best_match; + + uintmax_t total; + uintmax_t available; + uintmax_t available_to_root; + uintmax_t used; + uintmax_t inodes_free; + uintmax_t inodes_free_to_root; + uintmax_t inodes_used; + uintmax_t inodes_total; + + double dfree_pct; + double dused_pct; + + uint64_t dused_units; + uint64_t dfree_units; + uint64_t dtotal_units; + + double dused_inodes_percent; + double dfree_inodes_percent; + struct parameter_list *name_next; struct parameter_list *name_prev; - uintmax_t total, available, available_to_root, used, inodes_free, inodes_free_to_root, inodes_used, inodes_total; - double dfree_pct, dused_pct; - uint64_t dused_units, dfree_units, dtotal_units; - double dused_inodes_percent, dfree_inodes_percent; }; void np_add_name(struct name_list **list, const char *name); @@ -39,10 +58,12 @@ bool np_find_name(struct name_list *list, const char *name); bool np_seen_name(struct name_list *list, const char *name); int np_add_regex(struct regex_list **list, const char *regex, int cflags); bool np_find_regmatch(struct regex_list *list, const char *name); + struct parameter_list *np_add_parameter(struct parameter_list **list, const char *name); struct parameter_list *np_find_parameter(struct parameter_list *list, const char *name); struct parameter_list *np_del_parameter(struct parameter_list *item, struct parameter_list *prev); +struct parameter_list parameter_list_init(const char *); int search_parameter_list(struct parameter_list *list, const char *name); void np_set_best_match(struct parameter_list *desired, struct mount_entry *mount_list, bool exact); -bool np_regex_match_mount_entry(struct mount_entry *me, regex_t *re); +bool np_regex_match_mount_entry(struct mount_entry *, regex_t *); -- cgit v1.2.3-74-g34f1 From 29d946b9b516662a0f625b7d229ee41962cac264 Mon Sep 17 00:00:00 2001 From: Lorenz Kästle <12514511+RincewindsHat@users.noreply.github.com> Date: Tue, 18 Mar 2025 14:37:49 +0100 Subject: Refactor check_disk, no more global variables --- plugins/check_disk.c | 530 +++++++++++++++++++++--------------------- plugins/check_disk.d/config.h | 92 ++++++++ 2 files changed, 358 insertions(+), 264 deletions(-) create mode 100644 plugins/check_disk.d/config.h (limited to 'plugins') diff --git a/plugins/check_disk.c b/plugins/check_disk.c index f67f3d57..2df89aa3 100644 --- a/plugins/check_disk.c +++ b/plugins/check_disk.c @@ -43,13 +43,15 @@ const char *email = "devel@monitoring-plugins.org"; #endif #include -#include "popen.h" -#include "utils.h" -#include "utils_disk.h" #include -#include "fsusage.h" -#include "mountlist.h" +#include #include +#include "./popen.h" +#include "./utils.h" +#include "./check_disk.d/utils_disk.h" +#include "../gl/fsusage.h" +#include "../gl/mountlist.h" +#include "check_disk.d/config.h" #if HAVE_LIMITS_H # include @@ -63,27 +65,6 @@ const char *email = "devel@monitoring-plugins.org"; # define ERROR -1 #endif -/* If nonzero, show only local filesystems. */ -static bool show_local_fs = false; - -/* If nonzero, show only local filesystems but call stat() on remote ones. */ -static bool stat_remote_fs = false; - -/* Linked list of filesystem types to omit. - If the list is empty, don't exclude any types. */ -static struct regex_list *fs_exclude_list = NULL; - -/* Linked list of filesystem types to check. - If the list is empty, include all types. */ -static struct regex_list *fs_include_list; - -static struct name_list *dp_exclude_list; - -static struct parameter_list *path_select_list = NULL; - -/* Linked list of mounted filesystems. */ -static struct mount_entry *mount_list; - /* For long options that have no equivalent short option, use a non-character as a pseudo short option, starting with CHAR_MAX + 1. */ enum { @@ -96,40 +77,27 @@ enum { # pragma alloca #endif -static int process_arguments(int /*argc*/, char ** /*argv*/); -static void set_all_thresholds(struct parameter_list *path); +typedef struct { + int errorcode; + check_disk_config config; +} check_disk_config_wrapper; +static check_disk_config_wrapper process_arguments(int /*argc*/, char ** /*argv*/); +static void set_all_thresholds(struct parameter_list *path, char * /*warn_freespace_units*/, char * /*crit_freespace_units*/, + char * /*warn_freespace_percent*/, char * /*crit_freespace_percent*/, char * /*warn_usedspace_units*/, + char * /*crit_usedspace_units*/, char * /*warn_usedspace_percent*/, char * /*crit_usedspace_percent*/, + char * /*warn_usedinodes_percent*/, char * /*crit_usedinodes_percent*/, char * /*warn_freeinodes_percent*/, + char * /*crit_freeinodes_percent*/); static void print_help(void); void print_usage(void); static double calculate_percent(uintmax_t /*value*/, uintmax_t /*total*/); -static bool stat_path(struct parameter_list * /*parameters*/); -static void get_stats(struct parameter_list * /*parameters*/, struct fs_usage *fsp); -static void get_path_stats(struct parameter_list * /*parameters*/, struct fs_usage *fsp); +static bool stat_path(struct parameter_list * /*parameters*/, bool /*ignore_missing*/); +static void get_stats(struct parameter_list * /*parameters*/, struct fs_usage *fsp, bool /*ignore_missing*/, + bool /*freespace_ignore_reserved*/, uintmax_t /*mult*/, struct parameter_list * /*path_select_list*/, + struct name_list * /*seen*/); +static void get_path_stats(struct parameter_list * /*parameters*/, struct fs_usage *fsp, bool /*freespace_ignore_reserved*/, + uintmax_t /*mult*/, struct name_list * /*seen*/); -static char *units; -static uintmax_t mult = 1024 * 1024; static int verbose = 0; -static bool erronly = false; -static bool display_mntp = false; -static bool exact_match = false; -static bool ignore_missing = false; -static bool freespace_ignore_reserved = false; -static bool display_inodes_perfdata = false; -static char *warn_freespace_units = NULL; -static char *crit_freespace_units = NULL; -static char *warn_freespace_percent = NULL; -static char *crit_freespace_percent = NULL; -static char *warn_usedspace_units = NULL; -static char *crit_usedspace_units = NULL; -static char *warn_usedspace_percent = NULL; -static char *crit_usedspace_percent = NULL; -static char *warn_usedinodes_percent = NULL; -static char *crit_usedinodes_percent = NULL; -static char *warn_freeinodes_percent = NULL; -static char *crit_freeinodes_percent = NULL; -static bool path_selected = false; -static bool path_ignored = false; -static char *group = NULL; -static struct name_list *seen = NULL; int main(int argc, char **argv) { setlocale(LC_ALL, ""); @@ -140,74 +108,78 @@ int main(int argc, char **argv) { char mountdir[32]; #endif - mount_list = read_file_system_list(false); - /* Parse extra opts if any */ argv = np_extra_opts(&argc, argv, progname); - if (process_arguments(argc, argv) == ERROR) { + check_disk_config_wrapper tmp_config = process_arguments(argc, argv); + if (tmp_config.errorcode == ERROR) { usage4(_("Could not parse arguments")); } + check_disk_config config = tmp_config.config; + /* If a list of paths has not been selected, find entire mount list and create list of paths */ - if (!path_selected && !path_ignored) { - for (struct mount_entry *me = mount_list; me; me = me->me_next) { + if (!config.path_selected && !config.path_ignored) { + for (struct mount_entry *me = config.mount_list; me; me = me->me_next) { struct parameter_list *path = NULL; - if (!(path = np_find_parameter(path_select_list, me->me_mountdir))) { - path = np_add_parameter(&path_select_list, me->me_mountdir); + if (!(path = np_find_parameter(config.path_select_list, me->me_mountdir))) { + path = np_add_parameter(&config.path_select_list, me->me_mountdir); } path->best_match = me; - path->group = group; - set_all_thresholds(path); + path->group = config.group; + set_all_thresholds(path, config.warn_freespace_units, config.crit_freespace_units, config.warn_freespace_percent, + config.crit_freespace_percent, config.warn_usedspace_units, config.crit_usedspace_units, + config.warn_usedspace_percent, config.crit_usedspace_percent, config.warn_usedinodes_percent, + config.crit_usedinodes_percent, config.warn_freeinodes_percent, config.crit_freeinodes_percent); } } - if (!path_ignored) { - np_set_best_match(path_select_list, mount_list, exact_match); + if (!config.path_ignored) { + np_set_best_match(config.path_select_list, config.mount_list, config.exact_match); } /* Error if no match found for specified paths */ - struct parameter_list *temp_list = path_select_list; + struct parameter_list *temp_list = config.path_select_list; char *ignored = strdup(""); - while (path_select_list) { - if (!path_select_list->best_match && ignore_missing) { + while (config.path_select_list) { + if (!config.path_select_list->best_match && config.ignore_missing) { /* If the first element will be deleted, the temp_list must be updated with the new start address as well */ - if (path_select_list == temp_list) { - temp_list = path_select_list->name_next; + if (config.path_select_list == temp_list) { + temp_list = config.path_select_list->name_next; } /* Add path argument to list of ignored paths to inform about missing paths being ignored and not alerted */ - xasprintf(&ignored, "%s %s;", ignored, path_select_list->name); + xasprintf(&ignored, "%s %s;", ignored, config.path_select_list->name); /* Delete the path from the list so that it is not stat-checked later in the code. */ - path_select_list = np_del_parameter(path_select_list, path_select_list->name_prev); - } else if (!path_select_list->best_match) { + config.path_select_list = np_del_parameter(config.path_select_list, config.path_select_list->name_prev); + } else if (!config.path_select_list->best_match) { /* Without --ignore-missing option, exit with Critical state. */ - die(STATE_CRITICAL, _("DISK %s: %s not found\n"), _("CRITICAL"), path_select_list->name); + die(STATE_CRITICAL, _("DISK %s: %s not found\n"), _("CRITICAL"), config.path_select_list->name); } else { /* Continue jumping through the list */ - path_select_list = path_select_list->name_next; + config.path_select_list = config.path_select_list->name_next; } } - path_select_list = temp_list; + config.path_select_list = temp_list; - int result = STATE_UNKNOWN; - if (!path_select_list && ignore_missing) { + mp_state_enum result = STATE_UNKNOWN; + if (!config.path_select_list && config.ignore_missing) { result = STATE_OK; if (verbose >= 2) { printf("None of the provided paths were found\n"); } } - mp_state_enum disk_result = STATE_UNKNOWN; + mp_state_enum filesystem_result = STATE_UNKNOWN; char *perf = strdup(""); char *perf_ilabel = strdup(""); char *output = strdup(""); struct parameter_list *path = NULL; /* Process for every path in list */ - for (path = path_select_list; path; path = path->name_next) { + for (path = config.path_select_list; path; path = path->name_next) { if (verbose >= 3 && path->freespace_percent->warning != NULL && path->freespace_percent->critical != NULL) { printf("Thresholds(pct) for %s warn: %f crit %f\n", path->name, path->freespace_percent->warning->end, path->freespace_percent->critical->end); @@ -217,8 +189,8 @@ int main(int argc, char **argv) { printf("Group of %s: %s\n", path->name, path->group); } - // reset disk result - disk_result = STATE_UNKNOWN; + // reset filesystem result + filesystem_result = STATE_UNKNOWN; struct mount_entry *mount_entry = path->best_match; @@ -238,16 +210,16 @@ int main(int argc, char **argv) { /* Filters */ /* Remove filesystems already seen */ - if (np_seen_name(seen, mount_entry->me_mountdir)) { + if (np_seen_name(config.seen, mount_entry->me_mountdir)) { continue; } - np_add_name(&seen, mount_entry->me_mountdir); + np_add_name(&config.seen, mount_entry->me_mountdir); if (path->group == NULL) { /* Skip remote filesystems if we're not interested in them */ - if (mount_entry->me_remote && show_local_fs) { - if (stat_remote_fs) { - if (!stat_path(path) && ignore_missing) { + if (mount_entry->me_remote && config.show_local_fs) { + if (config.stat_remote_fs) { + if (!stat_path(path, config.ignore_missing) && config.ignore_missing) { result = STATE_OK; xasprintf(&ignored, "%s %s;", ignored, path->name); } @@ -255,22 +227,22 @@ int main(int argc, char **argv) { continue; /* Skip pseudo fs's if we haven't asked for all fs's */ } - if (fs_exclude_list && np_find_regmatch(fs_exclude_list, mount_entry->me_type)) { + if (config.fs_exclude_list && np_find_regmatch(config.fs_exclude_list, mount_entry->me_type)) { continue; /* Skip excluded fs's */ } - if (dp_exclude_list && - (np_find_name(dp_exclude_list, mount_entry->me_devname) || np_find_name(dp_exclude_list, mount_entry->me_mountdir))) { + if (config.device_path_exclude_list && (np_find_name(config.device_path_exclude_list, mount_entry->me_devname) || + np_find_name(config.device_path_exclude_list, mount_entry->me_mountdir))) { continue; /* Skip not included fstypes */ } - if (fs_include_list && !np_find_regmatch(fs_include_list, mount_entry->me_type)) { + if (config.fs_include_list && !np_find_regmatch(config.fs_include_list, mount_entry->me_type)) { continue; } } - if (!stat_path(path)) { - if (ignore_missing) { + if (!stat_path(path, config.ignore_missing)) { + if (config.ignore_missing) { result = STATE_OK; xasprintf(&ignored, "%s %s;", ignored, path->name); } @@ -281,13 +253,14 @@ int main(int argc, char **argv) { get_fs_usage(mount_entry->me_mountdir, mount_entry->me_devname, &fsp); if (fsp.fsu_blocks && strcmp("none", mount_entry->me_mountdir)) { - get_stats(path, &fsp); + get_stats(path, &fsp, config.ignore_missing, config.freespace_ignore_reserved, config.mult, config.path_select_list, + config.seen); if (verbose >= 3) { printf("For %s, used_pct=%f free_pct=%f used_units=%lu free_units=%lu total_units=%lu used_inodes_pct=%f " "free_inodes_pct=%f fsp.fsu_blocksize=%lu mult=%lu\n", mount_entry->me_mountdir, path->dused_pct, path->dfree_pct, path->dused_units, path->dfree_units, path->dtotal_units, - path->dused_inodes_percent, path->dfree_inodes_percent, fsp.fsu_blocksize, mult); + path->dused_inodes_percent, path->dfree_inodes_percent, fsp.fsu_blocksize, config.mult); } /* Threshold comparisons */ @@ -296,39 +269,39 @@ int main(int argc, char **argv) { if (verbose >= 3) { printf("Freespace_units result=%d\n", temp_result); } - disk_result = max_state(disk_result, temp_result); + filesystem_result = max_state(filesystem_result, temp_result); temp_result = get_status(path->dfree_pct, path->freespace_percent); if (verbose >= 3) { printf("Freespace%% result=%d\n", temp_result); } - disk_result = max_state(disk_result, temp_result); + filesystem_result = max_state(filesystem_result, temp_result); temp_result = get_status(path->dused_units, path->usedspace_units); if (verbose >= 3) { printf("Usedspace_units result=%d\n", temp_result); } - disk_result = max_state(disk_result, temp_result); + filesystem_result = max_state(filesystem_result, temp_result); temp_result = get_status(path->dused_pct, path->usedspace_percent); if (verbose >= 3) { printf("Usedspace_percent result=%d\n", temp_result); } - disk_result = max_state(disk_result, temp_result); + filesystem_result = max_state(filesystem_result, temp_result); temp_result = get_status(path->dused_inodes_percent, path->usedinodes_percent); if (verbose >= 3) { printf("Usedinodes_percent result=%d\n", temp_result); } - disk_result = max_state(disk_result, temp_result); + filesystem_result = max_state(filesystem_result, temp_result); temp_result = get_status(path->dfree_inodes_percent, path->freeinodes_percent); if (verbose >= 3) { printf("Freeinodes_percent result=%d\n", temp_result); } - disk_result = max_state(disk_result, temp_result); + filesystem_result = max_state(filesystem_result, temp_result); - result = max_state(result, disk_result); + result = max_state(result, filesystem_result); /* What a mess of units. The output shows free space, the perf data shows used space. Yikes! Hack here. Trying to get warn/crit levels from freespace_(units|percent) for perf @@ -339,31 +312,32 @@ int main(int argc, char **argv) { uint64_t warning_high_tide = UINT64_MAX; if (path->freespace_units->warning != NULL) { - warning_high_tide = (path->dtotal_units - path->freespace_units->warning->end) * mult; + warning_high_tide = (path->dtotal_units - path->freespace_units->warning->end) * config.mult; } if (path->freespace_percent->warning != NULL) { - warning_high_tide = - min(warning_high_tide, (uint64_t)((1.0 - path->freespace_percent->warning->end / 100) * (path->dtotal_units * mult))); + warning_high_tide = min(warning_high_tide, (uint64_t)((1.0 - path->freespace_percent->warning->end / 100) * + (path->dtotal_units * config.mult))); } uint64_t critical_high_tide = UINT64_MAX; if (path->freespace_units->critical != NULL) { - critical_high_tide = (path->dtotal_units - path->freespace_units->critical->end) * mult; + critical_high_tide = (path->dtotal_units - path->freespace_units->critical->end) * config.mult; } if (path->freespace_percent->critical != NULL) { - critical_high_tide = - min(critical_high_tide, (uint64_t)((1.0 - path->freespace_percent->critical->end / 100) * (path->dtotal_units * mult))); + critical_high_tide = min(critical_high_tide, (uint64_t)((1.0 - path->freespace_percent->critical->end / 100) * + (path->dtotal_units * config.mult))); } /* Nb: *_high_tide are unset when == UINT64_MAX */ xasprintf(&perf, "%s %s", perf, - perfdata_uint64((!strcmp(mount_entry->me_mountdir, "none") || display_mntp) ? mount_entry->me_devname - : mount_entry->me_mountdir, - path->dused_units * mult, "B", (warning_high_tide != UINT64_MAX), warning_high_tide, - (critical_high_tide != UINT64_MAX), critical_high_tide, true, 0, true, path->dtotal_units * mult)); + perfdata_uint64((!strcmp(mount_entry->me_mountdir, "none") || config.display_mntp) ? mount_entry->me_devname + : mount_entry->me_mountdir, + path->dused_units * config.mult, "B", (warning_high_tide != UINT64_MAX), warning_high_tide, + (critical_high_tide != UINT64_MAX), critical_high_tide, true, 0, true, + path->dtotal_units * config.mult)); - if (display_inodes_perfdata) { + if (config.display_inodes_perfdata) { /* *_high_tide must be reinitialized at each run */ warning_high_tide = UINT64_MAX; critical_high_tide = UINT64_MAX; @@ -378,43 +352,46 @@ int main(int argc, char **argv) { } xasprintf(&perf_ilabel, "%s (inodes)", - (!strcmp(mount_entry->me_mountdir, "none") || display_mntp) ? mount_entry->me_devname : mount_entry->me_mountdir); + (!strcmp(mount_entry->me_mountdir, "none") || config.display_mntp) ? mount_entry->me_devname + : mount_entry->me_mountdir); /* Nb: *_high_tide are unset when == UINT64_MAX */ xasprintf(&perf, "%s %s", perf, perfdata_uint64(perf_ilabel, path->inodes_used, "", (warning_high_tide != UINT64_MAX), warning_high_tide, (critical_high_tide != UINT64_MAX), critical_high_tide, true, 0, true, path->inodes_total)); } - if (disk_result == STATE_OK && erronly && !verbose) { + if (filesystem_result == STATE_OK && config.erronly && !verbose) { continue; } char *flag_header = NULL; - if (disk_result && verbose >= 1) { - xasprintf(&flag_header, " %s [", state_text(disk_result)); + if (filesystem_result && verbose >= 1) { + xasprintf(&flag_header, " %s [", state_text(filesystem_result)); } else { xasprintf(&flag_header, ""); } xasprintf(&output, "%s%s %s %llu%s (%.1f%%", output, flag_header, - (!strcmp(mount_entry->me_mountdir, "none") || display_mntp) ? mount_entry->me_devname : mount_entry->me_mountdir, - path->dfree_units, units, path->dfree_pct); + (!strcmp(mount_entry->me_mountdir, "none") || config.display_mntp) ? mount_entry->me_devname + : mount_entry->me_mountdir, + path->dfree_units, config.units, path->dfree_pct); if (path->dused_inodes_percent < 0) { - xasprintf(&output, "%s inode=-)%s;", output, (disk_result ? "]" : "")); + xasprintf(&output, "%s inode=-)%s;", output, (filesystem_result ? "]" : "")); } else { - xasprintf(&output, "%s inode=%.0f%%)%s;", output, path->dfree_inodes_percent, ((disk_result && verbose >= 1) ? "]" : "")); + xasprintf(&output, "%s inode=%.0f%%)%s;", output, path->dfree_inodes_percent, + ((filesystem_result && verbose >= 1) ? "]" : "")); } free(flag_header); } } char *preamble = " - free space:"; - if (strcmp(output, "") == 0 && !erronly) { + if (strcmp(output, "") == 0 && !config.erronly) { preamble = ""; xasprintf(&output, " - No disks were found for provided parameters"); } char *ignored_preamble = " - ignored paths:"; - printf("DISK %s%s%s%s%s|%s\n", state_text(result), ((erronly && result == STATE_OK)) ? "" : preamble, output, + printf("DISK %s%s%s%s%s|%s\n", state_text(result), (config.erronly && (result == STATE_OK)) ? "" : preamble, output, (strcmp(ignored, "") == 0) ? "" : ignored_preamble, ignored, perf); return result; } @@ -428,9 +405,16 @@ double calculate_percent(uintmax_t value, uintmax_t total) { } /* process command-line arguments */ -int process_arguments(int argc, char **argv) { +check_disk_config_wrapper process_arguments(int argc, char **argv) { + + check_disk_config_wrapper result = { + .errorcode = OK, + .config = check_disk_config_init(), + }; + if (argc < 2) { - return ERROR; + result.errorcode = ERROR; + return result; } static struct option longopts[] = {{"timeout", required_argument, 0, 't'}, @@ -480,8 +464,9 @@ int process_arguments(int argc, char **argv) { int cflags = REG_NOSUB | REG_EXTENDED; int default_cflags = cflags; + result.config.mount_list = read_file_system_list(false); - np_add_regex(&fs_exclude_list, "iso9660", REG_EXTENDED); + np_add_regex(&result.config.fs_exclude_list, "iso9660", REG_EXTENDED); while (true) { int option = 0; @@ -508,15 +493,15 @@ int process_arguments(int argc, char **argv) { if (strstr(optarg, "%")) { if (*optarg == '@') { - warn_freespace_percent = optarg; + result.config.warn_freespace_percent = optarg; } else { - xasprintf(&warn_freespace_percent, "@%s", optarg); + xasprintf(&result.config.warn_freespace_percent, "@%s", optarg); } } else { if (*optarg == '@') { - warn_freespace_units = optarg; + result.config.warn_freespace_units = optarg; } else { - xasprintf(&warn_freespace_units, "@%s", optarg); + xasprintf(&result.config.warn_freespace_units, "@%s", optarg); } } break; @@ -533,149 +518,149 @@ int process_arguments(int argc, char **argv) { if (strstr(optarg, "%")) { if (*optarg == '@') { - crit_freespace_percent = optarg; + result.config.crit_freespace_percent = optarg; } else { - xasprintf(&crit_freespace_percent, "@%s", optarg); + xasprintf(&result.config.crit_freespace_percent, "@%s", optarg); } } else { if (*optarg == '@') { - crit_freespace_units = optarg; + result.config.crit_freespace_units = optarg; } else { - xasprintf(&crit_freespace_units, "@%s", optarg); + xasprintf(&result.config.crit_freespace_units, "@%s", optarg); } } break; case 'W': /* warning inode threshold */ if (*optarg == '@') { - warn_freeinodes_percent = optarg; + result.config.warn_freeinodes_percent = optarg; } else { - xasprintf(&warn_freeinodes_percent, "@%s", optarg); + xasprintf(&result.config.warn_freeinodes_percent, "@%s", optarg); } break; case 'K': /* critical inode threshold */ if (*optarg == '@') { - crit_freeinodes_percent = optarg; + result.config.crit_freeinodes_percent = optarg; } else { - xasprintf(&crit_freeinodes_percent, "@%s", optarg); + xasprintf(&result.config.crit_freeinodes_percent, "@%s", optarg); } break; case 'u': - if (units) { - free(units); - } + free(result.config.units); if (!strcasecmp(optarg, "bytes")) { - mult = (uintmax_t)1; - units = strdup("B"); + result.config.mult = (uintmax_t)1; + result.config.units = strdup("B"); } else if (!strcmp(optarg, "KiB")) { - mult = (uintmax_t)1024; - units = strdup("KiB"); + result.config.mult = (uintmax_t)1024; + result.config.units = strdup("KiB"); } else if (!strcmp(optarg, "kB")) { - mult = (uintmax_t)1000; - units = strdup("kB"); + result.config.mult = (uintmax_t)1000; + result.config.units = strdup("kB"); } else if (!strcmp(optarg, "MiB")) { - mult = (uintmax_t)1024 * 1024; - units = strdup("MiB"); + result.config.mult = (uintmax_t)1024 * 1024; + result.config.units = strdup("MiB"); } else if (!strcmp(optarg, "MB")) { - mult = (uintmax_t)1000 * 1000; - units = strdup("MB"); + result.config.mult = (uintmax_t)1000 * 1000; + result.config.units = strdup("MB"); } else if (!strcmp(optarg, "GiB")) { - mult = (uintmax_t)1024 * 1024 * 1024; - units = strdup("GiB"); + result.config.mult = (uintmax_t)1024 * 1024 * 1024; + result.config.units = strdup("GiB"); } else if (!strcmp(optarg, "GB")) { - mult = (uintmax_t)1000 * 1000 * 1000; - units = strdup("GB"); + result.config.mult = (uintmax_t)1000 * 1000 * 1000; + result.config.units = strdup("GB"); } else if (!strcmp(optarg, "TiB")) { - mult = (uintmax_t)1024 * 1024 * 1024 * 1024; - units = strdup("TiB"); + result.config.mult = (uintmax_t)1024 * 1024 * 1024 * 1024; + result.config.units = strdup("TiB"); } else if (!strcmp(optarg, "TB")) { - mult = (uintmax_t)1000 * 1000 * 1000 * 1000; - units = strdup("TB"); + result.config.mult = (uintmax_t)1000 * 1000 * 1000 * 1000; + result.config.units = strdup("TB"); } else if (!strcmp(optarg, "PiB")) { - mult = (uintmax_t)1024 * 1024 * 1024 * 1024 * 1024; - units = strdup("PiB"); + result.config.mult = (uintmax_t)1024 * 1024 * 1024 * 1024 * 1024; + result.config.units = strdup("PiB"); } else if (!strcmp(optarg, "PB")) { - mult = (uintmax_t)1000 * 1000 * 1000 * 1000 * 1000; - units = strdup("PB"); + result.config.mult = (uintmax_t)1000 * 1000 * 1000 * 1000 * 1000; + result.config.units = strdup("PB"); } else { die(STATE_UNKNOWN, _("unit type %s not known\n"), optarg); } - if (units == NULL) { + if (result.config.units == NULL) { die(STATE_UNKNOWN, _("failed allocating storage for '%s'\n"), "units"); } break; case 'k': /* display mountpoint */ - mult = 1024; - if (units) { - free(units); - } - units = strdup("kiB"); + result.config.mult = 1024; + free(result.config.units); + result.config.units = strdup("kiB"); break; case 'm': /* display mountpoint */ - mult = 1024 * 1024; - if (units) { - free(units); - } - units = strdup("MiB"); + result.config.mult = 1024 * 1024; + free(result.config.units); + result.config.units = strdup("MiB"); break; case 'L': - stat_remote_fs = true; + result.config.stat_remote_fs = true; /* fallthrough */ case 'l': - show_local_fs = true; + result.config.show_local_fs = true; break; case 'P': - display_inodes_perfdata = true; + result.config.display_inodes_perfdata = true; break; case 'p': /* select path */ { - if (!(warn_freespace_units || crit_freespace_units || warn_freespace_percent || crit_freespace_percent || - warn_usedspace_units || crit_usedspace_units || warn_usedspace_percent || crit_usedspace_percent || - warn_usedinodes_percent || crit_usedinodes_percent || warn_freeinodes_percent || crit_freeinodes_percent)) { + if (!(result.config.warn_freespace_units || result.config.crit_freespace_units || result.config.warn_freespace_percent || + result.config.crit_freespace_percent || result.config.warn_usedspace_units || result.config.crit_usedspace_units || + result.config.warn_usedspace_percent || result.config.crit_usedspace_percent || result.config.warn_usedinodes_percent || + result.config.crit_usedinodes_percent || result.config.warn_freeinodes_percent || + result.config.crit_freeinodes_percent)) { die(STATE_UNKNOWN, "DISK %s: %s", _("UNKNOWN"), _("Must set a threshold value before using -p\n")); } /* add parameter if not found. overwrite thresholds if path has already been added */ struct parameter_list *se; - if (!(se = np_find_parameter(path_select_list, optarg))) { - se = np_add_parameter(&path_select_list, optarg); + if (!(se = np_find_parameter(result.config.path_select_list, optarg))) { + se = np_add_parameter(&result.config.path_select_list, optarg); struct stat stat_buf = {}; - if (stat(optarg, &stat_buf) && ignore_missing) { - path_ignored = true; + if (stat(optarg, &stat_buf) && result.config.ignore_missing) { + result.config.path_ignored = true; break; } } - se->group = group; - set_all_thresholds(se); + se->group = result.config.group; + set_all_thresholds( + se, result.config.warn_freespace_units, result.config.crit_freespace_units, result.config.warn_freespace_percent, + result.config.crit_freespace_percent, result.config.warn_usedspace_units, result.config.crit_usedspace_units, + result.config.warn_usedspace_percent, result.config.crit_usedspace_percent, result.config.warn_usedinodes_percent, + result.config.crit_usedinodes_percent, result.config.warn_freeinodes_percent, result.config.crit_freeinodes_percent); /* With autofs, it is required to stat() the path before re-populating the mount_list */ - if (!stat_path(se)) { + if (!stat_path(se, result.config.ignore_missing)) { break; } /* NB: We can't free the old mount_list "just like that": both list pointers and struct * pointers are copied around. One of the reason it wasn't done yet is that other parts * of check_disk need the same kind of cleanup so it'd better be done as a whole */ - mount_list = read_file_system_list(false); - np_set_best_match(se, mount_list, exact_match); + result.config.mount_list = read_file_system_list(false); + np_set_best_match(se, result.config.mount_list, result.config.exact_match); - path_selected = true; + result.config.path_selected = true; } break; case 'x': /* exclude path or partition */ - np_add_name(&dp_exclude_list, optarg); + np_add_name(&result.config.device_path_exclude_list, optarg); break; case 'X': /* exclude file system type */ { - int err = np_add_regex(&fs_exclude_list, optarg, REG_EXTENDED); + int err = np_add_regex(&result.config.fs_exclude_list, optarg, REG_EXTENDED); if (err != 0) { char errbuf[MAX_INPUT_BUFFER]; - regerror(err, &fs_exclude_list->regex, errbuf, MAX_INPUT_BUFFER); + regerror(err, &result.config.fs_exclude_list->regex, errbuf, MAX_INPUT_BUFFER); die(STATE_UNKNOWN, "DISK %s: %s - %s\n", _("UNKNOWN"), _("Could not compile regular expression"), errbuf); } break; case 'N': /* include file system type */ - err = np_add_regex(&fs_include_list, optarg, REG_EXTENDED); + err = np_add_regex(&result.config.fs_include_list, optarg, REG_EXTENDED); if (err != 0) { char errbuf[MAX_INPUT_BUFFER]; - regerror(err, &fs_exclude_list->regex, errbuf, MAX_INPUT_BUFFER); + regerror(err, &result.config.fs_exclude_list->regex, errbuf, MAX_INPUT_BUFFER); die(STATE_UNKNOWN, "DISK %s: %s - %s\n", _("UNKNOWN"), _("Could not compile regular expression"), errbuf); } } break; @@ -684,31 +669,31 @@ int process_arguments(int argc, char **argv) { break; case 'q': /* TODO: this function should eventually go away (removed 2007-09-20) */ /* verbose--; **replaced by line below**. -q was only a broken way of implementing -e */ - erronly = true; + result.config.erronly = true; break; case 'e': - erronly = true; + result.config.erronly = true; break; case 'E': - if (path_selected) { + if (result.config.path_selected) { die(STATE_UNKNOWN, "DISK %s: %s", _("UNKNOWN"), _("Must set -E before selecting paths\n")); } - exact_match = true; + result.config.exact_match = true; break; case 'f': - freespace_ignore_reserved = true; + result.config.freespace_ignore_reserved = true; break; case 'g': - if (path_selected) { + if (result.config.path_selected) { die(STATE_UNKNOWN, "DISK %s: %s", _("UNKNOWN"), _("Must set group value before selecting paths\n")); } - group = optarg; + result.config.group = optarg; break; case 'I': cflags |= REG_ICASE; // Intentional fallthrough case 'i': { - if (!path_selected) { + if (!result.config.path_selected) { die(STATE_UNKNOWN, "DISK %s: %s\n", _("UNKNOWN"), _("Paths need to be selected before using -i/-I. Use -A to select all paths explicitly")); } @@ -720,7 +705,7 @@ int process_arguments(int argc, char **argv) { die(STATE_UNKNOWN, "DISK %s: %s - %s\n", _("UNKNOWN"), _("Could not compile regular expression"), errbuf); } - struct parameter_list *temp_list = path_select_list; + struct parameter_list *temp_list = result.config.path_select_list; struct parameter_list *previous = NULL; while (temp_list) { if (temp_list->best_match) { @@ -733,7 +718,7 @@ int process_arguments(int argc, char **argv) { temp_list = np_del_parameter(temp_list, previous); /* pointer to first element needs to be updated if first item gets deleted */ if (previous == NULL) { - path_select_list = temp_list; + result.config.path_select_list = temp_list; } } else { previous = temp_list; @@ -748,7 +733,7 @@ int process_arguments(int argc, char **argv) { cflags = default_cflags; } break; case 'n': - ignore_missing = true; + result.config.ignore_missing = true; break; case 'A': optarg = strdup(".*"); @@ -757,9 +742,11 @@ int process_arguments(int argc, char **argv) { cflags |= REG_ICASE; // Intentional fallthrough case 'r': { - if (!(warn_freespace_units || crit_freespace_units || warn_freespace_percent || crit_freespace_percent || - warn_usedspace_units || crit_usedspace_units || warn_usedspace_percent || crit_usedspace_percent || - warn_usedinodes_percent || crit_usedinodes_percent || warn_freeinodes_percent || crit_freeinodes_percent)) { + if (!(result.config.warn_freespace_units || result.config.crit_freespace_units || result.config.warn_freespace_percent || + result.config.crit_freespace_percent || result.config.warn_usedspace_units || result.config.crit_usedspace_units || + result.config.warn_usedspace_percent || result.config.crit_usedspace_percent || result.config.warn_usedinodes_percent || + result.config.crit_usedinodes_percent || result.config.warn_freeinodes_percent || + result.config.crit_freeinodes_percent)) { die(STATE_UNKNOWN, "DISK %s: %s", _("UNKNOWN"), _("Must set a threshold value before using -r/-R/-A (--ereg-path/--eregi-path/--all)\n")); } @@ -773,7 +760,7 @@ int process_arguments(int argc, char **argv) { } bool found = false; - for (struct mount_entry *me = mount_list; me; me = me->me_next) { + for (struct mount_entry *me = result.config.mount_list; me; me = me->me_next) { if (np_regex_match_mount_entry(me, ®ex)) { found = true; if (verbose >= 3) { @@ -782,60 +769,69 @@ int process_arguments(int argc, char **argv) { /* add parameter if not found. overwrite thresholds if path has already been added */ struct parameter_list *se = NULL; - if (!(se = np_find_parameter(path_select_list, me->me_mountdir))) { - se = np_add_parameter(&path_select_list, me->me_mountdir); + if (!(se = np_find_parameter(result.config.path_select_list, me->me_mountdir))) { + se = np_add_parameter(&result.config.path_select_list, me->me_mountdir); } - se->group = group; - set_all_thresholds(se); + se->group = result.config.group; + set_all_thresholds(se, result.config.warn_freespace_units, result.config.crit_freespace_units, + result.config.warn_freespace_percent, result.config.crit_freespace_percent, + result.config.warn_usedspace_units, result.config.crit_usedspace_units, + result.config.warn_usedspace_percent, result.config.crit_usedspace_percent, + result.config.warn_usedinodes_percent, result.config.crit_usedinodes_percent, + result.config.warn_freeinodes_percent, result.config.crit_freeinodes_percent); } } - if (!found && ignore_missing) { - path_ignored = true; - path_selected = true; + if (!found && result.config.ignore_missing) { + result.config.path_ignored = true; + result.config.path_selected = true; break; } if (!found) { die(STATE_UNKNOWN, "DISK %s: %s - %s\n", _("UNKNOWN"), _("Regular expression did not match any path or disk"), optarg); } - found = false; - path_selected = true; - np_set_best_match(path_select_list, mount_list, exact_match); + result.config.path_selected = true; + np_set_best_match(result.config.path_select_list, result.config.mount_list, result.config.exact_match); cflags = default_cflags; } break; case 'M': /* display mountpoint */ - display_mntp = true; + result.config.display_mntp = true; break; case 'C': { /* add all mount entries to path_select list if no partitions have been explicitly defined using -p */ - if (!path_selected) { + if (!result.config.path_selected) { struct parameter_list *path; - for (struct mount_entry *me = mount_list; me; me = me->me_next) { - if (!(path = np_find_parameter(path_select_list, me->me_mountdir))) { - path = np_add_parameter(&path_select_list, me->me_mountdir); + for (struct mount_entry *me = result.config.mount_list; me; me = me->me_next) { + if (!(path = np_find_parameter(result.config.path_select_list, me->me_mountdir))) { + path = np_add_parameter(&result.config.path_select_list, me->me_mountdir); } path->best_match = me; - path->group = group; - set_all_thresholds(path); + path->group = result.config.group; + set_all_thresholds(path, result.config.warn_freespace_units, result.config.crit_freespace_units, + result.config.warn_freespace_percent, result.config.crit_freespace_percent, + result.config.warn_usedspace_units, result.config.crit_usedspace_units, + result.config.warn_usedspace_percent, result.config.crit_usedspace_percent, + result.config.warn_usedinodes_percent, result.config.crit_usedinodes_percent, + result.config.warn_freeinodes_percent, result.config.crit_freeinodes_percent); } } - warn_freespace_units = NULL; - crit_freespace_units = NULL; - warn_usedspace_units = NULL; - crit_usedspace_units = NULL; - warn_freespace_percent = NULL; - crit_freespace_percent = NULL; - warn_usedspace_percent = NULL; - crit_usedspace_percent = NULL; - warn_usedinodes_percent = NULL; - crit_usedinodes_percent = NULL; - warn_freeinodes_percent = NULL; - crit_freeinodes_percent = NULL; - - path_selected = false; - group = NULL; + result.config.warn_freespace_units = NULL; + result.config.crit_freespace_units = NULL; + result.config.warn_usedspace_units = NULL; + result.config.crit_usedspace_units = NULL; + result.config.warn_freespace_percent = NULL; + result.config.crit_freespace_percent = NULL; + result.config.warn_usedspace_percent = NULL; + result.config.crit_usedspace_percent = NULL; + result.config.warn_usedinodes_percent = NULL; + result.config.crit_usedinodes_percent = NULL; + result.config.warn_freeinodes_percent = NULL; + result.config.crit_freeinodes_percent = NULL; + + result.config.path_selected = false; + result.config.group = NULL; } break; case 'V': /* version */ print_revision(progname, NP_VERSION); @@ -847,45 +843,49 @@ int process_arguments(int argc, char **argv) { usage(_("Unknown argument")); } } - if (verbose > 0) { - printf("ping\n"); - } /* Support for "check_disk warn crit [fs]" with thresholds at used% level */ int index = optind; - if (warn_usedspace_percent == NULL && argc > index && is_intnonneg(argv[index])) { + if (result.config.warn_usedspace_percent == NULL && argc > index && is_intnonneg(argv[index])) { if (verbose > 0) { printf("Got an positional warn threshold: %s\n", argv[index]); } - warn_usedspace_percent = argv[index++]; + result.config.warn_usedspace_percent = argv[index++]; } - if (crit_usedspace_percent == NULL && argc > index && is_intnonneg(argv[index])) { + if (result.config.crit_usedspace_percent == NULL && argc > index && is_intnonneg(argv[index])) { if (verbose > 0) { printf("Got an positional crit threshold: %s\n", argv[index]); } - crit_usedspace_percent = argv[index++]; + result.config.crit_usedspace_percent = argv[index++]; } if (argc > index) { if (verbose > 0) { printf("Got an positional filesystem: %s\n", argv[index]); } - struct parameter_list *se = np_add_parameter(&path_select_list, strdup(argv[index++])); - path_selected = true; - set_all_thresholds(se); + struct parameter_list *se = np_add_parameter(&result.config.path_select_list, strdup(argv[index++])); + result.config.path_selected = true; + set_all_thresholds(se, result.config.warn_freespace_units, result.config.crit_freespace_units, result.config.warn_freespace_percent, + result.config.crit_freespace_percent, result.config.warn_usedspace_units, result.config.crit_usedspace_units, + result.config.warn_usedspace_percent, result.config.crit_usedspace_percent, + result.config.warn_usedinodes_percent, result.config.crit_usedinodes_percent, + result.config.warn_freeinodes_percent, result.config.crit_freeinodes_percent); } - if (units == NULL) { - units = strdup("MiB"); - mult = (uintmax_t)1024 * 1024; + if (result.config.units == NULL) { + result.config.units = strdup("MiB"); + result.config.mult = (uintmax_t)1024 * 1024; } - return 0; + return result; } -void set_all_thresholds(struct parameter_list *path) { +void set_all_thresholds(struct parameter_list *path, char *warn_freespace_units, char *crit_freespace_units, char *warn_freespace_percent, + char *crit_freespace_percent, char *warn_usedspace_units, char *crit_usedspace_units, char *warn_usedspace_percent, + char *crit_usedspace_percent, char *warn_usedinodes_percent, char *crit_usedinodes_percent, + char *warn_freeinodes_percent, char *crit_freeinodes_percent) { if (path->freespace_units != NULL) { free(path->freespace_units); } @@ -1022,7 +1022,7 @@ void print_usage(void) { printf("[-t timeout] [-u unit] [-v] [-X type_regex] [-N type]\n"); } -bool stat_path(struct parameter_list *parameters) { +bool stat_path(struct parameter_list *parameters, bool ignore_missing) { /* Stat entry to check that dir exists and is accessible */ if (verbose >= 3) { printf("calling stat on %s\n", parameters->name); @@ -1043,12 +1043,13 @@ bool stat_path(struct parameter_list *parameters) { return true; } -void get_stats(struct parameter_list *parameters, struct fs_usage *fsp) { +void get_stats(struct parameter_list *parameters, struct fs_usage *fsp, bool ignore_missing, bool freespace_ignore_reserved, uintmax_t mult, + struct parameter_list *path_select_list, struct name_list *seen) { struct fs_usage tmpfsp; bool first = true; if (parameters->group == NULL) { - get_path_stats(parameters, fsp); + get_path_stats(parameters, fsp, freespace_ignore_reserved, mult, seen); } else { /* find all group members */ for (struct parameter_list *p_list = path_select_list; p_list; p_list = p_list->name_next) { @@ -1060,11 +1061,11 @@ void get_stats(struct parameter_list *parameters, struct fs_usage *fsp) { #endif if (p_list->group && !(strcmp(p_list->group, parameters->group))) { - if (!stat_path(p_list)) { + if (!stat_path(p_list, ignore_missing)) { continue; } get_fs_usage(p_list->best_match->me_mountdir, p_list->best_match->me_devname, &tmpfsp); - get_path_stats(p_list, &tmpfsp); + get_path_stats(p_list, &tmpfsp, freespace_ignore_reserved, mult, seen); if (verbose >= 3) { printf("Group %s: adding %lu blocks sized %lu, (%s) used_units=%lu free_units=%lu total_units=%lu mult=%lu\n", p_list->group, tmpfsp.fsu_blocks, tmpfsp.fsu_blocksize, p_list->best_match->me_mountdir, p_list->dused_units, @@ -1105,7 +1106,8 @@ void get_stats(struct parameter_list *parameters, struct fs_usage *fsp) { parameters->dfree_inodes_percent = 100 - parameters->dused_inodes_percent; } -void get_path_stats(struct parameter_list *parameters, struct fs_usage *fsp) { +void get_path_stats(struct parameter_list *parameters, struct fs_usage *fsp, bool freespace_ignore_reserved, uintmax_t mult, + struct name_list *seen) { parameters->available = fsp->fsu_bavail; parameters->available_to_root = fsp->fsu_bfree; parameters->used = fsp->fsu_blocks - fsp->fsu_bfree; diff --git a/plugins/check_disk.d/config.h b/plugins/check_disk.d/config.h new file mode 100644 index 00000000..d890fc1a --- /dev/null +++ b/plugins/check_disk.d/config.h @@ -0,0 +1,92 @@ +#pragma once + +#include "../../config.h" +#include +#include + +typedef struct { + // Output options + bool erronly; + bool display_mntp; + /* show only local filesystems. */ + bool show_local_fs; + /* show only local filesystems but call stat() on remote ones. */ + bool stat_remote_fs; + bool display_inodes_perfdata; + + bool exact_match; + bool ignore_missing; + bool path_ignored; + bool path_selected; + bool freespace_ignore_reserved; + + char *warn_freespace_units; + char *crit_freespace_units; + char *warn_freespace_percent; + char *crit_freespace_percent; + char *warn_usedspace_units; + char *crit_usedspace_units; + char *warn_usedspace_percent; + char *crit_usedspace_percent; + char *warn_usedinodes_percent; + char *crit_usedinodes_percent; + char *warn_freeinodes_percent; + char *crit_freeinodes_percent; + + /* Linked list of filesystem types to omit. + If the list is empty, don't exclude any types. */ + struct regex_list *fs_exclude_list; + /* Linked list of filesystem types to check. + If the list is empty, include all types. */ + struct regex_list *fs_include_list; + struct name_list *device_path_exclude_list; + struct parameter_list *path_select_list; + /* Linked list of mounted filesystems. */ + struct mount_entry *mount_list; + struct name_list *seen; + + char *units; + uintmax_t mult; + char *group; +} check_disk_config; + +check_disk_config check_disk_config_init() { + check_disk_config tmp = { + .erronly = false, + .display_mntp = false, + .show_local_fs = false, + .stat_remote_fs = false, + .display_inodes_perfdata = false, + + .exact_match = false, + .ignore_missing = false, + .path_ignored = false, + .path_selected = false, + .freespace_ignore_reserved = false, + + .warn_freespace_units = NULL, + .crit_freespace_units = NULL, + .warn_freespace_percent = NULL, + .crit_freespace_percent = NULL, + .warn_usedspace_units = NULL, + .crit_usedspace_units = NULL, + .warn_usedspace_percent = NULL, + .crit_usedspace_percent = NULL, + .warn_usedinodes_percent = NULL, + .crit_usedinodes_percent = NULL, + .warn_freeinodes_percent = NULL, + .crit_freeinodes_percent = NULL, + + .fs_exclude_list = NULL, + .fs_include_list = NULL, + .device_path_exclude_list = NULL, + .path_select_list = NULL, + .mount_list = NULL, + .seen = NULL, + + .units = NULL, + .mult = 1024 * 1024, + .group = NULL, + }; + return tmp; +} -- cgit v1.2.3-74-g34f1 From 59e0a258f9c0f393bf29cced1f35743f74e7b10c Mon Sep 17 00:00:00 2001 From: Lorenz Kästle <12514511+RincewindsHat@users.noreply.github.com> Date: Tue, 18 Mar 2025 15:57:44 +0100 Subject: Migrate disk tests from lib, tool --- .gitignore | 3 +- configure.ac | 4 +- lib/tests/Makefile.am | 6 +- lib/tests/test_disk.c | 192 -------------------------------------- lib/tests/test_disk.t | 6 -- plugins/Makefile.am | 8 +- plugins/check_disk.d/utils_disk.c | 4 +- plugins/check_disk.d/utils_disk.h | 2 +- plugins/common.h | 6 +- plugins/tests/test_check_disk.c | 192 ++++++++++++++++++++++++++++++++++++++ plugins/tests/test_check_disk.t | 6 ++ 11 files changed, 216 insertions(+), 213 deletions(-) delete mode 100644 lib/tests/test_disk.c delete mode 100755 lib/tests/test_disk.t create mode 100644 plugins/tests/test_check_disk.c create mode 100755 plugins/tests/test_check_disk.t (limited to 'plugins') diff --git a/.gitignore b/.gitignore index 5245495e..8b14f429 100644 --- a/.gitignore +++ b/.gitignore @@ -114,7 +114,6 @@ NP-VERSION-FILE /lib/tests/Makefile.in /lib/tests/test_base64 /lib/tests/test_cmd -/lib/tests/test_disk /lib/tests/test_tcp /lib/tests/test_utils /lib/tests/utils_base.Po @@ -223,7 +222,7 @@ plugins/check_disk.d/.dirstamp /plugins/tests/Makefile /plugins/tests/Makefile.in /plugins/tests/test_utils -/plugins/tests/test_disk +/plugins/tests/test_check_disk /plugins/tests/test_check_swap /plugins/tests/.deps /plugins/tests/.dirstamp diff --git a/configure.ac b/configure.ac index 204fc6e3..fdc9b699 100644 --- a/configure.ac +++ b/configure.ac @@ -181,10 +181,10 @@ fi # Finally, define tests if we use libtap if test "$enable_libtap" = "yes" ; then - EXTRA_TEST="test_utils test_disk test_tcp test_cmd test_base64" + EXTRA_TEST="test_utils test_tcp test_cmd test_base64" AC_SUBST(EXTRA_TEST) - EXTRA_PLUGIN_TESTS="tests/test_check_swap" + EXTRA_PLUGIN_TESTS="tests/test_check_swap tests/test_check_disk" AC_SUBST(EXTRA_PLUGIN_TESTS) fi diff --git a/lib/tests/Makefile.am b/lib/tests/Makefile.am index 9be94f6d..7798a72e 100644 --- a/lib/tests/Makefile.am +++ b/lib/tests/Makefile.am @@ -8,9 +8,9 @@ check_PROGRAMS = @EXTRA_TEST@ AM_CPPFLAGS = -DNP_STATE_DIR_PREFIX=\"$(localstatedir)\" \ -I$(top_srcdir)/lib -I$(top_srcdir)/gl -I$(top_srcdir)/intl -I$(top_srcdir)/plugins -EXTRA_PROGRAMS = test_utils test_disk test_tcp test_cmd test_base64 test_ini1 test_ini3 test_opts1 test_opts2 test_opts3 test_generic_output +EXTRA_PROGRAMS = test_utils test_tcp test_cmd test_base64 test_ini1 test_ini3 test_opts1 test_opts2 test_opts3 test_generic_output -np_test_scripts = test_base64.t test_cmd.t test_disk.t test_ini1.t test_ini3.t test_opts1.t test_opts2.t test_opts3.t test_tcp.t test_utils.t test_generic_output.t +np_test_scripts = test_base64.t test_cmd.t test_ini1.t test_ini3.t test_opts1.t test_opts2.t test_opts3.t test_tcp.t test_utils.t test_generic_output.t np_test_files = config-dos.ini config-opts.ini config-tiny.ini plugin.ini plugins.ini EXTRA_DIST = $(np_test_scripts) $(np_test_files) var @@ -29,7 +29,7 @@ AM_CFLAGS = -g -I$(top_srcdir)/lib -I$(top_srcdir)/gl $(tap_cflags) AM_LDFLAGS = $(tap_ldflags) -ltap LDADD = $(top_srcdir)/lib/libmonitoringplug.a $(top_srcdir)/gl/libgnu.a $(LIB_CRYPTO) -SOURCES = test_utils.c test_disk.c test_tcp.c test_cmd.c test_base64.c test_ini1.c test_ini3.c test_opts1.c test_opts2.c test_opts3.c test_generic_output.c +SOURCES = test_utils.c test_tcp.c test_cmd.c test_base64.c test_ini1.c test_ini3.c test_opts1.c test_opts2.c test_opts3.c test_generic_output.c test: ${noinst_PROGRAMS} perl -MTest::Harness -e '$$Test::Harness::switches=""; runtests(map {$$_ .= ".t"} @ARGV)' $(EXTRA_PROGRAMS) diff --git a/lib/tests/test_disk.c b/lib/tests/test_disk.c deleted file mode 100644 index c18db7a4..00000000 --- a/lib/tests/test_disk.c +++ /dev/null @@ -1,192 +0,0 @@ -/***************************************************************************** - * - * 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 . - * - * - *****************************************************************************/ - -#include "common.h" -#include "utils_disk.h" -#include "tap.h" -#include "regex.h" - -void np_test_mount_entry_regex(struct mount_entry *dummy_mount_list, char *regstr, int cflags, int expect, char *desc); - -int main(int argc, char **argv) { - struct name_list *exclude_filesystem = NULL; - struct name_list *exclude_fstype = NULL; - struct name_list *dummy_mountlist = NULL; - struct name_list *temp_name; - struct parameter_list *paths = NULL; - struct parameter_list *p, *prev = NULL, *last = NULL; - - struct mount_entry *dummy_mount_list; - struct mount_entry *me; - struct mount_entry **mtail = &dummy_mount_list; - int cflags = REG_NOSUB | REG_EXTENDED; - int found = 0, count = 0; - - plan_tests(33); - - ok(np_find_name(exclude_filesystem, "/var/log") == false, "/var/log not in list"); - np_add_name(&exclude_filesystem, "/var/log"); - ok(np_find_name(exclude_filesystem, "/var/log") == true, "is in list now"); - ok(np_find_name(exclude_filesystem, "/home") == false, "/home not in list"); - np_add_name(&exclude_filesystem, "/home"); - ok(np_find_name(exclude_filesystem, "/home") == true, "is in list now"); - ok(np_find_name(exclude_filesystem, "/var/log") == true, "/var/log still in list"); - - ok(np_find_name(exclude_fstype, "iso9660") == false, "iso9660 not in list"); - np_add_name(&exclude_fstype, "iso9660"); - ok(np_find_name(exclude_fstype, "iso9660") == true, "is in list now"); - - ok(np_find_name(exclude_filesystem, "iso9660") == false, "Make sure no clashing in variables"); - - /* - for (temp_name = exclude_filesystem; temp_name; temp_name = temp_name->next) { - printf("Name: %s\n", temp_name->name); - } - */ - - me = (struct mount_entry *)malloc(sizeof *me); - me->me_devname = strdup("/dev/c0t0d0s0"); - me->me_mountdir = strdup("/"); - *mtail = me; - mtail = &me->me_next; - - me = (struct mount_entry *)malloc(sizeof *me); - me->me_devname = strdup("/dev/c1t0d1s0"); - me->me_mountdir = strdup("/var"); - *mtail = me; - mtail = &me->me_next; - - me = (struct mount_entry *)malloc(sizeof *me); - me->me_devname = strdup("/dev/c2t0d0s0"); - me->me_mountdir = strdup("/home"); - *mtail = me; - mtail = &me->me_next; - - np_test_mount_entry_regex(dummy_mount_list, strdup("/"), cflags, 3, strdup("a")); - np_test_mount_entry_regex(dummy_mount_list, strdup("/dev"), cflags, 3, strdup("regex on dev names:")); - np_test_mount_entry_regex(dummy_mount_list, strdup("/foo"), cflags, 0, strdup("regex on non existent dev/path:")); - np_test_mount_entry_regex(dummy_mount_list, strdup("/Foo"), cflags | REG_ICASE, 0, strdup("regi on non existent dev/path:")); - np_test_mount_entry_regex(dummy_mount_list, strdup("/c.t0"), cflags, 3, strdup("partial devname regex match:")); - np_test_mount_entry_regex(dummy_mount_list, strdup("c0t0"), cflags, 1, strdup("partial devname regex match:")); - np_test_mount_entry_regex(dummy_mount_list, strdup("C0t0"), cflags | REG_ICASE, 1, strdup("partial devname regi match:")); - np_test_mount_entry_regex(dummy_mount_list, strdup("home"), cflags, 1, strdup("partial pathname regex match:")); - np_test_mount_entry_regex(dummy_mount_list, strdup("hOme"), cflags | REG_ICASE, 1, strdup("partial pathname regi match:")); - np_test_mount_entry_regex(dummy_mount_list, strdup("(/home)|(/var)"), cflags, 2, strdup("grouped regex pathname match:")); - np_test_mount_entry_regex(dummy_mount_list, strdup("(/homE)|(/Var)"), cflags | REG_ICASE, 2, strdup("grouped regi pathname match:")); - - np_add_parameter(&paths, "/home/groups"); - np_add_parameter(&paths, "/var"); - np_add_parameter(&paths, "/tmp"); - np_add_parameter(&paths, "/home/tonvoon"); - np_add_parameter(&paths, "/dev/c2t0d0s0"); - - np_set_best_match(paths, dummy_mount_list, false); - for (p = paths; p; p = p->name_next) { - struct mount_entry *temp_me; - temp_me = p->best_match; - if (!strcmp(p->name, "/home/groups")) { - ok(temp_me && !strcmp(temp_me->me_mountdir, "/home"), "/home/groups got right best match: /home"); - } else if (!strcmp(p->name, "/var")) { - ok(temp_me && !strcmp(temp_me->me_mountdir, "/var"), "/var got right best match: /var"); - } else if (!strcmp(p->name, "/tmp")) { - ok(temp_me && !strcmp(temp_me->me_mountdir, "/"), "/tmp got right best match: /"); - } else if (!strcmp(p->name, "/home/tonvoon")) { - ok(temp_me && !strcmp(temp_me->me_mountdir, "/home"), "/home/tonvoon got right best match: /home"); - } else if (!strcmp(p->name, "/dev/c2t0d0s0")) { - ok(temp_me && !strcmp(temp_me->me_devname, "/dev/c2t0d0s0"), "/dev/c2t0d0s0 got right best match: /dev/c2t0d0s0"); - } - } - - paths = NULL; /* Bad boy - should free, but this is a test suite */ - np_add_parameter(&paths, "/home/groups"); - np_add_parameter(&paths, "/var"); - np_add_parameter(&paths, "/tmp"); - np_add_parameter(&paths, "/home/tonvoon"); - np_add_parameter(&paths, "/home"); - - np_set_best_match(paths, dummy_mount_list, true); - for (p = paths; p; p = p->name_next) { - if (!strcmp(p->name, "/home/groups")) { - ok(!p->best_match, "/home/groups correctly not found"); - } else if (!strcmp(p->name, "/var")) { - ok(p->best_match, "/var found"); - } else if (!strcmp(p->name, "/tmp")) { - ok(!p->best_match, "/tmp correctly not found"); - } else if (!strcmp(p->name, "/home/tonvoon")) { - ok(!p->best_match, "/home/tonvoon not found"); - } else if (!strcmp(p->name, "/home")) { - ok(p->best_match, "/home found"); - } - } - - /* test deleting first element in paths */ - paths = np_del_parameter(paths, NULL); - for (p = paths; p; p = p->name_next) { - if (!strcmp(p->name, "/home/groups")) - found = 1; - } - ok(found == 0, "first element successfully deleted"); - found = 0; - - p = paths; - while (p) { - if (!strcmp(p->name, "/tmp")) - p = np_del_parameter(p, prev); - else { - prev = p; - p = p->name_next; - } - } - - for (p = paths; p; p = p->name_next) { - if (!strcmp(p->name, "/tmp")) - found = 1; - if (p->name_next) - prev = p; - else - last = p; - } - ok(found == 0, "/tmp element successfully deleted"); - - p = np_del_parameter(last, prev); - for (p = paths; p; p = p->name_next) { - if (!strcmp(p->name, "/home")) - found = 1; - last = p; - count++; - } - ok(found == 0, "last (/home) element successfully deleted"); - ok(count == 2, "two elements remaining"); - - return exit_status(); -} - -void np_test_mount_entry_regex(struct mount_entry *dummy_mount_list, char *regstr, int cflags, int expect, char *desc) { - int matches = 0; - regex_t re; - struct mount_entry *me; - if (regcomp(&re, regstr, cflags) == 0) { - for (me = dummy_mount_list; me; me = me->me_next) { - if (np_regex_match_mount_entry(me, &re)) - matches++; - } - ok(matches == expect, "%s '%s' matched %i/3 entries. ok: %i/3", desc, regstr, expect, matches); - - } else - ok(false, "regex '%s' not compilable", regstr); -} diff --git a/lib/tests/test_disk.t b/lib/tests/test_disk.t deleted file mode 100755 index da84dfdf..00000000 --- a/lib/tests/test_disk.t +++ /dev/null @@ -1,6 +0,0 @@ -#!/usr/bin/perl -use Test::More; -if (! -e "./test_disk") { - plan skip_all => "./test_disk not compiled - please enable libtap library to test"; -} -exec "./test_disk"; diff --git a/plugins/Makefile.am b/plugins/Makefile.am index 30283cb4..04fb7ed2 100644 --- a/plugins/Makefile.am +++ b/plugins/Makefile.am @@ -40,11 +40,13 @@ EXTRA_PROGRAMS = check_mysql check_radius check_pgsql check_snmp check_hpjd \ check_nagios check_by_ssh check_dns check_nt check_ide_smart \ check_procs check_mysql_query check_apt check_dbi check_curl \ \ - tests/test_check_swap + tests/test_check_swap \ + tests/test_check_disk SUBDIRS = picohttpparser -np_test_scripts = tests/test_check_swap.t +np_test_scripts = tests/test_check_swap.t \ + tests/test_check_disk.t EXTRA_DIST = t \ tests \ @@ -167,6 +169,8 @@ endif tests_test_check_swap_LDADD = $(BASEOBJS) $(tap_ldflags) -ltap tests_test_check_swap_SOURCES = tests/test_check_swap.c check_swap.d/swap.c +tests_test_check_disk_LDADD = $(BASEOBJS) $(tap_ldflags) check_disk.d/utils_disk.c -ltap +tests_test_check_disk_SOURCES = tests/test_check_disk.c ############################################################################## # secondary dependencies diff --git a/plugins/check_disk.d/utils_disk.c b/plugins/check_disk.d/utils_disk.c index 1d806715..369c85d5 100644 --- a/plugins/check_disk.d/utils_disk.c +++ b/plugins/check_disk.d/utils_disk.c @@ -26,9 +26,9 @@ * *****************************************************************************/ -#include "common.h" +#include "../common.h" #include "utils_disk.h" -#include "gl/fsusage.h" +#include "../../gl/fsusage.h" #include void np_add_name(struct name_list **list, const char *name) { diff --git a/plugins/check_disk.d/utils_disk.h b/plugins/check_disk.d/utils_disk.h index 1c68fed9..0c69f987 100644 --- a/plugins/check_disk.d/utils_disk.h +++ b/plugins/check_disk.d/utils_disk.h @@ -2,7 +2,7 @@ #include "../../config.h" #include "../../gl/mountlist.h" -#include "utils_base.h" +#include "../../lib/utils_base.h" #include "regex.h" #include diff --git a/plugins/common.h b/plugins/common.h index 603bae55..35d1e549 100644 --- a/plugins/common.h +++ b/plugins/common.h @@ -31,7 +31,7 @@ #ifndef _COMMON_H_ #define _COMMON_H_ -#include "config.h" +#include "../config.h" #include "../lib/monitoringplug.h" #ifdef HAVE_FEATURES_H @@ -110,7 +110,7 @@ /* GNU Libraries */ #include -#include "dirname.h" +#include "../gl/dirname.h" #include @@ -190,7 +190,7 @@ enum { * Internationalization * */ -#include "gettext.h" +#include "../gl/gettext.h" #define _(String) gettext (String) #if ! ENABLE_NLS # undef textdomain diff --git a/plugins/tests/test_check_disk.c b/plugins/tests/test_check_disk.c new file mode 100644 index 00000000..92d0d270 --- /dev/null +++ b/plugins/tests/test_check_disk.c @@ -0,0 +1,192 @@ +/***************************************************************************** + * + * 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 . + * + * + *****************************************************************************/ + +#include "common.h" +#include "../check_disk.d/utils_disk.h" +#include "../../tap/tap.h" +#include "regex.h" + +void np_test_mount_entry_regex(struct mount_entry *dummy_mount_list, char *regstr, int cflags, int expect, char *desc); + +int main(int argc, char **argv) { + struct name_list *exclude_filesystem = NULL; + struct name_list *exclude_fstype = NULL; + struct name_list *dummy_mountlist = NULL; + struct name_list *temp_name; + struct parameter_list *paths = NULL; + struct parameter_list *p, *prev = NULL, *last = NULL; + + struct mount_entry *dummy_mount_list; + struct mount_entry *me; + struct mount_entry **mtail = &dummy_mount_list; + int cflags = REG_NOSUB | REG_EXTENDED; + int found = 0, count = 0; + + plan_tests(33); + + ok(np_find_name(exclude_filesystem, "/var/log") == false, "/var/log not in list"); + np_add_name(&exclude_filesystem, "/var/log"); + ok(np_find_name(exclude_filesystem, "/var/log") == true, "is in list now"); + ok(np_find_name(exclude_filesystem, "/home") == false, "/home not in list"); + np_add_name(&exclude_filesystem, "/home"); + ok(np_find_name(exclude_filesystem, "/home") == true, "is in list now"); + ok(np_find_name(exclude_filesystem, "/var/log") == true, "/var/log still in list"); + + ok(np_find_name(exclude_fstype, "iso9660") == false, "iso9660 not in list"); + np_add_name(&exclude_fstype, "iso9660"); + ok(np_find_name(exclude_fstype, "iso9660") == true, "is in list now"); + + ok(np_find_name(exclude_filesystem, "iso9660") == false, "Make sure no clashing in variables"); + + /* + for (temp_name = exclude_filesystem; temp_name; temp_name = temp_name->next) { + printf("Name: %s\n", temp_name->name); + } + */ + + me = (struct mount_entry *)malloc(sizeof *me); + me->me_devname = strdup("/dev/c0t0d0s0"); + me->me_mountdir = strdup("/"); + *mtail = me; + mtail = &me->me_next; + + me = (struct mount_entry *)malloc(sizeof *me); + me->me_devname = strdup("/dev/c1t0d1s0"); + me->me_mountdir = strdup("/var"); + *mtail = me; + mtail = &me->me_next; + + me = (struct mount_entry *)malloc(sizeof *me); + me->me_devname = strdup("/dev/c2t0d0s0"); + me->me_mountdir = strdup("/home"); + *mtail = me; + mtail = &me->me_next; + + np_test_mount_entry_regex(dummy_mount_list, strdup("/"), cflags, 3, strdup("a")); + np_test_mount_entry_regex(dummy_mount_list, strdup("/dev"), cflags, 3, strdup("regex on dev names:")); + np_test_mount_entry_regex(dummy_mount_list, strdup("/foo"), cflags, 0, strdup("regex on non existent dev/path:")); + np_test_mount_entry_regex(dummy_mount_list, strdup("/Foo"), cflags | REG_ICASE, 0, strdup("regi on non existent dev/path:")); + np_test_mount_entry_regex(dummy_mount_list, strdup("/c.t0"), cflags, 3, strdup("partial devname regex match:")); + np_test_mount_entry_regex(dummy_mount_list, strdup("c0t0"), cflags, 1, strdup("partial devname regex match:")); + np_test_mount_entry_regex(dummy_mount_list, strdup("C0t0"), cflags | REG_ICASE, 1, strdup("partial devname regi match:")); + np_test_mount_entry_regex(dummy_mount_list, strdup("home"), cflags, 1, strdup("partial pathname regex match:")); + np_test_mount_entry_regex(dummy_mount_list, strdup("hOme"), cflags | REG_ICASE, 1, strdup("partial pathname regi match:")); + np_test_mount_entry_regex(dummy_mount_list, strdup("(/home)|(/var)"), cflags, 2, strdup("grouped regex pathname match:")); + np_test_mount_entry_regex(dummy_mount_list, strdup("(/homE)|(/Var)"), cflags | REG_ICASE, 2, strdup("grouped regi pathname match:")); + + np_add_parameter(&paths, "/home/groups"); + np_add_parameter(&paths, "/var"); + np_add_parameter(&paths, "/tmp"); + np_add_parameter(&paths, "/home/tonvoon"); + np_add_parameter(&paths, "/dev/c2t0d0s0"); + + np_set_best_match(paths, dummy_mount_list, false); + for (p = paths; p; p = p->name_next) { + struct mount_entry *temp_me; + temp_me = p->best_match; + if (!strcmp(p->name, "/home/groups")) { + ok(temp_me && !strcmp(temp_me->me_mountdir, "/home"), "/home/groups got right best match: /home"); + } else if (!strcmp(p->name, "/var")) { + ok(temp_me && !strcmp(temp_me->me_mountdir, "/var"), "/var got right best match: /var"); + } else if (!strcmp(p->name, "/tmp")) { + ok(temp_me && !strcmp(temp_me->me_mountdir, "/"), "/tmp got right best match: /"); + } else if (!strcmp(p->name, "/home/tonvoon")) { + ok(temp_me && !strcmp(temp_me->me_mountdir, "/home"), "/home/tonvoon got right best match: /home"); + } else if (!strcmp(p->name, "/dev/c2t0d0s0")) { + ok(temp_me && !strcmp(temp_me->me_devname, "/dev/c2t0d0s0"), "/dev/c2t0d0s0 got right best match: /dev/c2t0d0s0"); + } + } + + paths = NULL; /* Bad boy - should free, but this is a test suite */ + np_add_parameter(&paths, "/home/groups"); + np_add_parameter(&paths, "/var"); + np_add_parameter(&paths, "/tmp"); + np_add_parameter(&paths, "/home/tonvoon"); + np_add_parameter(&paths, "/home"); + + np_set_best_match(paths, dummy_mount_list, true); + for (p = paths; p; p = p->name_next) { + if (!strcmp(p->name, "/home/groups")) { + ok(!p->best_match, "/home/groups correctly not found"); + } else if (!strcmp(p->name, "/var")) { + ok(p->best_match, "/var found"); + } else if (!strcmp(p->name, "/tmp")) { + ok(!p->best_match, "/tmp correctly not found"); + } else if (!strcmp(p->name, "/home/tonvoon")) { + ok(!p->best_match, "/home/tonvoon not found"); + } else if (!strcmp(p->name, "/home")) { + ok(p->best_match, "/home found"); + } + } + + /* test deleting first element in paths */ + paths = np_del_parameter(paths, NULL); + for (p = paths; p; p = p->name_next) { + if (!strcmp(p->name, "/home/groups")) + found = 1; + } + ok(found == 0, "first element successfully deleted"); + found = 0; + + p = paths; + while (p) { + if (!strcmp(p->name, "/tmp")) + p = np_del_parameter(p, prev); + else { + prev = p; + p = p->name_next; + } + } + + for (p = paths; p; p = p->name_next) { + if (!strcmp(p->name, "/tmp")) + found = 1; + if (p->name_next) + prev = p; + else + last = p; + } + ok(found == 0, "/tmp element successfully deleted"); + + p = np_del_parameter(last, prev); + for (p = paths; p; p = p->name_next) { + if (!strcmp(p->name, "/home")) + found = 1; + last = p; + count++; + } + ok(found == 0, "last (/home) element successfully deleted"); + ok(count == 2, "two elements remaining"); + + return exit_status(); +} + +void np_test_mount_entry_regex(struct mount_entry *dummy_mount_list, char *regstr, int cflags, int expect, char *desc) { + int matches = 0; + regex_t re; + struct mount_entry *me; + if (regcomp(&re, regstr, cflags) == 0) { + for (me = dummy_mount_list; me; me = me->me_next) { + if (np_regex_match_mount_entry(me, &re)) + matches++; + } + ok(matches == expect, "%s '%s' matched %i/3 entries. ok: %i/3", desc, regstr, expect, matches); + + } else + ok(false, "regex '%s' not compilable", regstr); +} diff --git a/plugins/tests/test_check_disk.t b/plugins/tests/test_check_disk.t new file mode 100755 index 00000000..56354650 --- /dev/null +++ b/plugins/tests/test_check_disk.t @@ -0,0 +1,6 @@ +#!/usr/bin/perl +use Test::More; +if (! -e "./test_check_disk") { + plan skip_all => "./test_check_disk not compiled - please enable libtap library to test"; +} +exec "./test_check_disk"; -- cgit v1.2.3-74-g34f1 From 75cf0d307285c413d5547662e5ba677e1f70de62 Mon Sep 17 00:00:00 2001 From: Lorenz Kästle <12514511+RincewindsHat@users.noreply.github.com> Date: Tue, 18 Mar 2025 16:23:06 +0100 Subject: Remove some unused code --- plugins/check_disk.c | 8 -------- 1 file changed, 8 deletions(-) (limited to 'plugins') diff --git a/plugins/check_disk.c b/plugins/check_disk.c index 2df89aa3..15ec06cd 100644 --- a/plugins/check_disk.c +++ b/plugins/check_disk.c @@ -65,14 +65,6 @@ const char *email = "devel@monitoring-plugins.org"; # define ERROR -1 #endif -/* For long options that have no equivalent short option, use a - non-character as a pseudo short option, starting with CHAR_MAX + 1. */ -enum { - SYNC_OPTION = CHAR_MAX + 1, - NO_SYNC_OPTION, - BLOCK_SIZE_OPTION -}; - #ifdef _AIX # pragma alloca #endif -- cgit v1.2.3-74-g34f1 From 42531fa92a97318f2b96265f501f37e7fd96ea4c Mon Sep 17 00:00:00 2001 From: Lorenz Kästle <12514511+RincewindsHat@users.noreply.github.com> Date: Tue, 18 Mar 2025 16:23:33 +0100 Subject: Refactor test_check_disk.c --- plugins/tests/test_check_disk.c | 86 +++++++++++++++++++++-------------------- 1 file changed, 44 insertions(+), 42 deletions(-) (limited to 'plugins') diff --git a/plugins/tests/test_check_disk.c b/plugins/tests/test_check_disk.c index 92d0d270..963a9413 100644 --- a/plugins/tests/test_check_disk.c +++ b/plugins/tests/test_check_disk.c @@ -24,21 +24,9 @@ void np_test_mount_entry_regex(struct mount_entry *dummy_mount_list, char *regstr, int cflags, int expect, char *desc); int main(int argc, char **argv) { - struct name_list *exclude_filesystem = NULL; - struct name_list *exclude_fstype = NULL; - struct name_list *dummy_mountlist = NULL; - struct name_list *temp_name; - struct parameter_list *paths = NULL; - struct parameter_list *p, *prev = NULL, *last = NULL; - - struct mount_entry *dummy_mount_list; - struct mount_entry *me; - struct mount_entry **mtail = &dummy_mount_list; - int cflags = REG_NOSUB | REG_EXTENDED; - int found = 0, count = 0; - plan_tests(33); + struct name_list *exclude_filesystem = NULL; ok(np_find_name(exclude_filesystem, "/var/log") == false, "/var/log not in list"); np_add_name(&exclude_filesystem, "/var/log"); ok(np_find_name(exclude_filesystem, "/var/log") == true, "is in list now"); @@ -47,6 +35,7 @@ int main(int argc, char **argv) { ok(np_find_name(exclude_filesystem, "/home") == true, "is in list now"); ok(np_find_name(exclude_filesystem, "/var/log") == true, "/var/log still in list"); + struct name_list *exclude_fstype = NULL; ok(np_find_name(exclude_fstype, "iso9660") == false, "iso9660 not in list"); np_add_name(&exclude_fstype, "iso9660"); ok(np_find_name(exclude_fstype, "iso9660") == true, "is in list now"); @@ -59,7 +48,9 @@ int main(int argc, char **argv) { } */ - me = (struct mount_entry *)malloc(sizeof *me); + struct mount_entry *dummy_mount_list; + struct mount_entry **mtail = &dummy_mount_list; + struct mount_entry *me = (struct mount_entry *)malloc(sizeof *me); me->me_devname = strdup("/dev/c0t0d0s0"); me->me_mountdir = strdup("/"); *mtail = me; @@ -77,6 +68,7 @@ int main(int argc, char **argv) { *mtail = me; mtail = &me->me_next; + int cflags = REG_NOSUB | REG_EXTENDED; np_test_mount_entry_regex(dummy_mount_list, strdup("/"), cflags, 3, strdup("a")); np_test_mount_entry_regex(dummy_mount_list, strdup("/dev"), cflags, 3, strdup("regex on dev names:")); np_test_mount_entry_regex(dummy_mount_list, strdup("/foo"), cflags, 0, strdup("regex on non existent dev/path:")); @@ -89,6 +81,7 @@ int main(int argc, char **argv) { np_test_mount_entry_regex(dummy_mount_list, strdup("(/home)|(/var)"), cflags, 2, strdup("grouped regex pathname match:")); np_test_mount_entry_regex(dummy_mount_list, strdup("(/homE)|(/Var)"), cflags | REG_ICASE, 2, strdup("grouped regi pathname match:")); + struct parameter_list *paths = NULL; np_add_parameter(&paths, "/home/groups"); np_add_parameter(&paths, "/var"); np_add_parameter(&paths, "/tmp"); @@ -96,7 +89,7 @@ int main(int argc, char **argv) { np_add_parameter(&paths, "/dev/c2t0d0s0"); np_set_best_match(paths, dummy_mount_list, false); - for (p = paths; p; p = p->name_next) { + for (struct parameter_list *p = paths; p; p = p->name_next) { struct mount_entry *temp_me; temp_me = p->best_match; if (!strcmp(p->name, "/home/groups")) { @@ -120,7 +113,7 @@ int main(int argc, char **argv) { np_add_parameter(&paths, "/home"); np_set_best_match(paths, dummy_mount_list, true); - for (p = paths; p; p = p->name_next) { + for (struct parameter_list *p = paths; p; p = p->name_next) { if (!strcmp(p->name, "/home/groups")) { ok(!p->best_match, "/home/groups correctly not found"); } else if (!strcmp(p->name, "/var")) { @@ -134,59 +127,68 @@ int main(int argc, char **argv) { } } + bool found = false; /* test deleting first element in paths */ paths = np_del_parameter(paths, NULL); - for (p = paths; p; p = p->name_next) { - if (!strcmp(p->name, "/home/groups")) - found = 1; + for (struct parameter_list *p = paths; p; p = p->name_next) { + if (!strcmp(p->name, "/home/groups")) { + found = true; + } } - ok(found == 0, "first element successfully deleted"); - found = 0; + ok(!found, "first element successfully deleted"); + found = false; - p = paths; + struct parameter_list *prev = NULL; + struct parameter_list *p = paths; while (p) { - if (!strcmp(p->name, "/tmp")) + if (!strcmp(p->name, "/tmp")) { p = np_del_parameter(p, prev); - else { + } else { prev = p; p = p->name_next; } } - for (p = paths; p; p = p->name_next) { - if (!strcmp(p->name, "/tmp")) - found = 1; - if (p->name_next) - prev = p; - else - last = p; + struct parameter_list *last = NULL; + for (struct parameter_list *path = paths; path; path = path->name_next) { + if (!strcmp(path->name, "/tmp")) { + found = true; + } + if (path->name_next) { + prev = path; + } else { + last = path; + } } - ok(found == 0, "/tmp element successfully deleted"); + ok(!found, "/tmp element successfully deleted"); + int count = 0; p = np_del_parameter(last, prev); for (p = paths; p; p = p->name_next) { - if (!strcmp(p->name, "/home")) - found = 1; + if (!strcmp(p->name, "/home")) { + found = true; + } last = p; count++; } - ok(found == 0, "last (/home) element successfully deleted"); + ok(!found, "last (/home) element successfully deleted"); ok(count == 2, "two elements remaining"); return exit_status(); } void np_test_mount_entry_regex(struct mount_entry *dummy_mount_list, char *regstr, int cflags, int expect, char *desc) { - int matches = 0; - regex_t re; - struct mount_entry *me; - if (regcomp(&re, regstr, cflags) == 0) { - for (me = dummy_mount_list; me; me = me->me_next) { - if (np_regex_match_mount_entry(me, &re)) + regex_t regex; + if (regcomp(®ex, regstr, cflags) == 0) { + int matches = 0; + for (struct mount_entry *me = dummy_mount_list; me; me = me->me_next) { + if (np_regex_match_mount_entry(me, ®ex)) { matches++; + } } ok(matches == expect, "%s '%s' matched %i/3 entries. ok: %i/3", desc, regstr, expect, matches); - } else + } else { ok(false, "regex '%s' not compilable", regstr); + } } -- cgit v1.2.3-74-g34f1 From a0710dbd72ea6314cf6a1ec50d2fa3c3c0543748 Mon Sep 17 00:00:00 2001 From: Lorenz Kästle <12514511+RincewindsHat@users.noreply.github.com> Date: Tue, 18 Mar 2025 16:26:14 +0100 Subject: check_disk: Remove unnecessary NULL checks --- plugins/check_disk.c | 24 ++++++------------------ 1 file changed, 6 insertions(+), 18 deletions(-) (limited to 'plugins') diff --git a/plugins/check_disk.c b/plugins/check_disk.c index 15ec06cd..050298d6 100644 --- a/plugins/check_disk.c +++ b/plugins/check_disk.c @@ -878,34 +878,22 @@ void set_all_thresholds(struct parameter_list *path, char *warn_freespace_units, char *crit_freespace_percent, char *warn_usedspace_units, char *crit_usedspace_units, char *warn_usedspace_percent, char *crit_usedspace_percent, char *warn_usedinodes_percent, char *crit_usedinodes_percent, char *warn_freeinodes_percent, char *crit_freeinodes_percent) { - if (path->freespace_units != NULL) { - free(path->freespace_units); - } + free(path->freespace_units); set_thresholds(&path->freespace_units, warn_freespace_units, crit_freespace_units); - if (path->freespace_percent != NULL) { - free(path->freespace_percent); - } + free(path->freespace_percent); set_thresholds(&path->freespace_percent, warn_freespace_percent, crit_freespace_percent); - if (path->usedspace_units != NULL) { - free(path->usedspace_units); - } + free(path->usedspace_units); set_thresholds(&path->usedspace_units, warn_usedspace_units, crit_usedspace_units); - if (path->usedspace_percent != NULL) { - free(path->usedspace_percent); - } + free(path->usedspace_percent); set_thresholds(&path->usedspace_percent, warn_usedspace_percent, crit_usedspace_percent); - if (path->usedinodes_percent != NULL) { - free(path->usedinodes_percent); - } + free(path->usedinodes_percent); set_thresholds(&path->usedinodes_percent, warn_usedinodes_percent, crit_usedinodes_percent); - if (path->freeinodes_percent != NULL) { - free(path->freeinodes_percent); - } + free(path->freeinodes_percent); set_thresholds(&path->freeinodes_percent, warn_freeinodes_percent, crit_freeinodes_percent); } -- cgit v1.2.3-74-g34f1 From 908aed4e6f9072e601a189d4ceff3152bdecc49d Mon Sep 17 00:00:00 2001 From: Lorenz Kästle <12514511+RincewindsHat@users.noreply.github.com> Date: Sun, 30 Mar 2025 22:37:48 +0200 Subject: Refactor check_disk and library functions --- plugins/check_disk.c | 1069 ++++++++++++++++++++----------------- plugins/check_disk.d/config.h | 92 ---- plugins/check_disk.d/utils_disk.c | 469 ++++++++++++---- plugins/check_disk.d/utils_disk.h | 142 ++++- 4 files changed, 1048 insertions(+), 724 deletions(-) delete mode 100644 plugins/check_disk.d/config.h (limited to 'plugins') diff --git a/plugins/check_disk.c b/plugins/check_disk.c index 050298d6..3cab816d 100644 --- a/plugins/check_disk.c +++ b/plugins/check_disk.c @@ -33,6 +33,10 @@ const char *email = "devel@monitoring-plugins.org"; #include "states.h" #include "common.h" +#include "output.h" +#include "perfdata.h" +#include "utils_base.h" +#include "lib/thresholds.h" #ifdef HAVE_SYS_STAT_H # include @@ -48,10 +52,9 @@ const char *email = "devel@monitoring-plugins.org"; #include #include "./popen.h" #include "./utils.h" -#include "./check_disk.d/utils_disk.h" #include "../gl/fsusage.h" #include "../gl/mountlist.h" -#include "check_disk.d/config.h" +#include "./check_disk.d/utils_disk.h" #if HAVE_LIMITS_H # include @@ -74,20 +77,22 @@ typedef struct { check_disk_config config; } check_disk_config_wrapper; static check_disk_config_wrapper process_arguments(int /*argc*/, char ** /*argv*/); -static void set_all_thresholds(struct parameter_list *path, char * /*warn_freespace_units*/, char * /*crit_freespace_units*/, - char * /*warn_freespace_percent*/, char * /*crit_freespace_percent*/, char * /*warn_usedspace_units*/, - char * /*crit_usedspace_units*/, char * /*warn_usedspace_percent*/, char * /*crit_usedspace_percent*/, - char * /*warn_usedinodes_percent*/, char * /*crit_usedinodes_percent*/, char * /*warn_freeinodes_percent*/, - char * /*crit_freeinodes_percent*/); -static void print_help(void); -void print_usage(void); + +static void set_all_thresholds(parameter_list_elem *path, char *warn_freespace_units, char *crit_freespace_units, + char *warn_freespace_percent, char *crit_freespace_percent, char *warn_freeinodes_percent, + char *crit_freeinodes_percent); static double calculate_percent(uintmax_t /*value*/, uintmax_t /*total*/); -static bool stat_path(struct parameter_list * /*parameters*/, bool /*ignore_missing*/); -static void get_stats(struct parameter_list * /*parameters*/, struct fs_usage *fsp, bool /*ignore_missing*/, - bool /*freespace_ignore_reserved*/, uintmax_t /*mult*/, struct parameter_list * /*path_select_list*/, - struct name_list * /*seen*/); -static void get_path_stats(struct parameter_list * /*parameters*/, struct fs_usage *fsp, bool /*freespace_ignore_reserved*/, - uintmax_t /*mult*/, struct name_list * /*seen*/); +static bool stat_path(parameter_list_elem * /*parameters*/, bool /*ignore_missing*/); + +/* + * Puts the values from a struct fs_usage into a parameter_list with an additional flag to control how reserved + * and inodes should be judged (ignored or not) + */ +static parameter_list_elem get_path_stats(parameter_list_elem parameters, struct fs_usage fsp, bool freespace_ignore_reserved); +static mp_subcheck evaluate_filesystem(measurement_unit measurement_unit, bool display_inodes_perfdata, byte_unit unit); + +void print_usage(void); +static void print_help(void); static int verbose = 0; @@ -100,7 +105,7 @@ int main(int argc, char **argv) { char mountdir[32]; #endif - /* Parse extra opts if any */ + // Parse extra opts if any argv = np_extra_opts(&argc, argv, progname); check_disk_config_wrapper tmp_config = process_arguments(argc, argv); @@ -110,289 +115,222 @@ int main(int argc, char **argv) { check_disk_config config = tmp_config.config; - /* If a list of paths has not been selected, find entire - mount list and create list of paths - */ - if (!config.path_selected && !config.path_ignored) { - for (struct mount_entry *me = config.mount_list; me; me = me->me_next) { - struct parameter_list *path = NULL; - if (!(path = np_find_parameter(config.path_select_list, me->me_mountdir))) { - path = np_add_parameter(&config.path_select_list, me->me_mountdir); - } - path->best_match = me; - path->group = config.group; - set_all_thresholds(path, config.warn_freespace_units, config.crit_freespace_units, config.warn_freespace_percent, - config.crit_freespace_percent, config.warn_usedspace_units, config.crit_usedspace_units, - config.warn_usedspace_percent, config.crit_usedspace_percent, config.warn_usedinodes_percent, - config.crit_usedinodes_percent, config.warn_freeinodes_percent, config.crit_freeinodes_percent); - } + if (config.output_format_is_set) { + mp_set_format(config.output_format); } - if (!config.path_ignored) { - np_set_best_match(config.path_select_list, config.mount_list, config.exact_match); + if (config.erronly) { + mp_set_level_of_detail(MP_DETAIL_NON_OK_ONLY); } - /* Error if no match found for specified paths */ - struct parameter_list *temp_list = config.path_select_list; + if (!config.path_ignored) { + mp_int_fs_list_set_best_match(config.path_select_list, config.mount_list, config.exact_match); + } - char *ignored = strdup(""); - while (config.path_select_list) { - if (!config.path_select_list->best_match && config.ignore_missing) { - /* If the first element will be deleted, the temp_list must be updated with the new start address as well */ - if (config.path_select_list == temp_list) { - temp_list = config.path_select_list->name_next; - } - /* Add path argument to list of ignored paths to inform about missing paths being ignored and not alerted */ - xasprintf(&ignored, "%s %s;", ignored, config.path_select_list->name); + // Error if no match found for specified paths + for (parameter_list_elem *elem = config.path_select_list.first; elem;) { + if (!elem->best_match && config.ignore_missing) { /* Delete the path from the list so that it is not stat-checked later in the code. */ - config.path_select_list = np_del_parameter(config.path_select_list, config.path_select_list->name_prev); - } else if (!config.path_select_list->best_match) { + elem = mp_int_fs_list_del(&config.path_select_list, elem); + continue; + } + if (!elem->best_match) { /* Without --ignore-missing option, exit with Critical state. */ - die(STATE_CRITICAL, _("DISK %s: %s not found\n"), _("CRITICAL"), config.path_select_list->name); - } else { - /* Continue jumping through the list */ - config.path_select_list = config.path_select_list->name_next; + die(STATE_CRITICAL, _("DISK %s: %s not found\n"), _("CRITICAL"), elem->name); } - } - config.path_select_list = temp_list; - - mp_state_enum result = STATE_UNKNOWN; - if (!config.path_select_list && config.ignore_missing) { - result = STATE_OK; - if (verbose >= 2) { - printf("None of the provided paths were found\n"); - } + elem = mp_int_fs_list_get_next(elem); } - mp_state_enum filesystem_result = STATE_UNKNOWN; - char *perf = strdup(""); - char *perf_ilabel = strdup(""); - char *output = strdup(""); - struct parameter_list *path = NULL; - /* Process for every path in list */ - for (path = config.path_select_list; path; path = path->name_next) { - if (verbose >= 3 && path->freespace_percent->warning != NULL && path->freespace_percent->critical != NULL) { - printf("Thresholds(pct) for %s warn: %f crit %f\n", path->name, path->freespace_percent->warning->end, - path->freespace_percent->critical->end); + mp_check overall = mp_check_init(); + if (config.path_select_list.length == 0) { + mp_subcheck none_sc = mp_subcheck_init(); + xasprintf(&none_sc.output, "No filesystems were found for the provided parameters"); + if (config.ignore_missing) { + none_sc = mp_set_subcheck_state(none_sc, STATE_OK); + } else { + none_sc = mp_set_subcheck_state(none_sc, STATE_UNKNOWN); + if (verbose >= 2) { + printf("None of the provided paths were found\n"); + } } + mp_add_subcheck_to_check(&overall, none_sc); + mp_exit(overall); + } - if (verbose >= 3 && path->group != NULL) { - printf("Group of %s: %s\n", path->name, path->group); + // Filter list first + for (parameter_list_elem *path = config.path_select_list.first; path;) { + if (!path->best_match) { + path = mp_int_fs_list_del(&config.path_select_list, path); + continue; } - // reset filesystem result - filesystem_result = STATE_UNKNOWN; - struct mount_entry *mount_entry = path->best_match; - if (!mount_entry) { - continue; - } - #ifdef __CYGWIN__ if (strncmp(path->name, "/cygdrive/", 10) != 0 || strlen(path->name) > 11) { + path = mp_int_fs_list_del(&config.path_select_list, path); continue; } + + char *mountdir = NULL; snprintf(mountdir, sizeof(mountdir), "%s:\\", me->me_mountdir + 10); if (GetDriveType(mountdir) != DRIVE_FIXED) { - me->me_remote = 1; + mount_entry->me_remote = 1; } #endif - /* Filters */ /* Remove filesystems already seen */ if (np_seen_name(config.seen, mount_entry->me_mountdir)) { + path = mp_int_fs_list_del(&config.path_select_list, path); continue; } - np_add_name(&config.seen, mount_entry->me_mountdir); if (path->group == NULL) { - /* Skip remote filesystems if we're not interested in them */ - if (mount_entry->me_remote && config.show_local_fs) { - if (config.stat_remote_fs) { - if (!stat_path(path, config.ignore_missing) && config.ignore_missing) { - result = STATE_OK; - xasprintf(&ignored, "%s %s;", ignored, path->name); - } - } - continue; - /* Skip pseudo fs's if we haven't asked for all fs's */ - } if (config.fs_exclude_list && np_find_regmatch(config.fs_exclude_list, mount_entry->me_type)) { + // Skip excluded fs's + path = mp_int_fs_list_del(&config.path_select_list, path); continue; - /* Skip excluded fs's */ } + if (config.device_path_exclude_list && (np_find_name(config.device_path_exclude_list, mount_entry->me_devname) || np_find_name(config.device_path_exclude_list, mount_entry->me_mountdir))) { + // Skip excluded device or mount paths + path = mp_int_fs_list_del(&config.path_select_list, path); continue; - /* Skip not included fstypes */ } + if (config.fs_include_list && !np_find_regmatch(config.fs_include_list, mount_entry->me_type)) { + // Skip not included fstypes + path = mp_int_fs_list_del(&config.path_select_list, path); continue; } - } - - if (!stat_path(path, config.ignore_missing)) { - if (config.ignore_missing) { - result = STATE_OK; - xasprintf(&ignored, "%s %s;", ignored, path->name); - } - continue; - } - struct fs_usage fsp = {0}; - get_fs_usage(mount_entry->me_mountdir, mount_entry->me_devname, &fsp); - - if (fsp.fsu_blocks && strcmp("none", mount_entry->me_mountdir)) { - get_stats(path, &fsp, config.ignore_missing, config.freespace_ignore_reserved, config.mult, config.path_select_list, - config.seen); - - if (verbose >= 3) { - printf("For %s, used_pct=%f free_pct=%f used_units=%lu free_units=%lu total_units=%lu used_inodes_pct=%f " - "free_inodes_pct=%f fsp.fsu_blocksize=%lu mult=%lu\n", - mount_entry->me_mountdir, path->dused_pct, path->dfree_pct, path->dused_units, path->dfree_units, path->dtotal_units, - path->dused_inodes_percent, path->dfree_inodes_percent, fsp.fsu_blocksize, config.mult); - } - - /* Threshold comparisons */ - - mp_state_enum temp_result = get_status(path->dfree_units, path->freespace_units); - if (verbose >= 3) { - printf("Freespace_units result=%d\n", temp_result); + /* Skip remote filesystems if we're not interested in them */ + if (mount_entry->me_remote && config.show_local_fs) { + if (config.stat_remote_fs) { + // TODO Stat here + if (!stat_path(path, config.ignore_missing) && config.ignore_missing) { + } + } + continue; } - filesystem_result = max_state(filesystem_result, temp_result); - temp_result = get_status(path->dfree_pct, path->freespace_percent); - if (verbose >= 3) { - printf("Freespace%% result=%d\n", temp_result); + // TODO why stat here? remove unstatable fs? + if (!stat_path(path, config.ignore_missing)) { + // if (config.ignore_missing) { + // xasprintf(&ignored, "%s %s;", ignored, path->name); + // } + // not accessible, remove from list + path = mp_int_fs_list_del(&config.path_select_list, path); + continue; } - filesystem_result = max_state(filesystem_result, temp_result); + } - temp_result = get_status(path->dused_units, path->usedspace_units); - if (verbose >= 3) { - printf("Usedspace_units result=%d\n", temp_result); - } - filesystem_result = max_state(filesystem_result, temp_result); + path = mp_int_fs_list_get_next(path); + } - temp_result = get_status(path->dused_pct, path->usedspace_percent); - if (verbose >= 3) { - printf("Usedspace_percent result=%d\n", temp_result); - } - filesystem_result = max_state(filesystem_result, temp_result); + // now get the actual measurements + for (parameter_list_elem *filesystem = config.path_select_list.first; filesystem;) { + // Get actual metrics here + struct mount_entry *mount_entry = filesystem->best_match; + struct fs_usage fsp = {0}; + get_fs_usage(mount_entry->me_mountdir, mount_entry->me_devname, &fsp); - temp_result = get_status(path->dused_inodes_percent, path->usedinodes_percent); - if (verbose >= 3) { - printf("Usedinodes_percent result=%d\n", temp_result); - } - filesystem_result = max_state(filesystem_result, temp_result); + if (fsp.fsu_blocks != 0 && strcmp("none", mount_entry->me_mountdir) != 0) { + *filesystem = get_path_stats(*filesystem, fsp, config.freespace_ignore_reserved); - temp_result = get_status(path->dfree_inodes_percent, path->freeinodes_percent); if (verbose >= 3) { - printf("Freeinodes_percent result=%d\n", temp_result); - } - filesystem_result = max_state(filesystem_result, temp_result); - - result = max_state(result, filesystem_result); - - /* What a mess of units. The output shows free space, the perf data shows used space. Yikes! - Hack here. Trying to get warn/crit levels from freespace_(units|percent) for perf - data. Assumption that start=0. Roll on new syntax... - */ - - /* *_high_tide must be reinitialized at each run */ - uint64_t warning_high_tide = UINT64_MAX; - - if (path->freespace_units->warning != NULL) { - warning_high_tide = (path->dtotal_units - path->freespace_units->warning->end) * config.mult; - } - if (path->freespace_percent->warning != NULL) { - warning_high_tide = min(warning_high_tide, (uint64_t)((1.0 - path->freespace_percent->warning->end / 100) * - (path->dtotal_units * config.mult))); - } - - uint64_t critical_high_tide = UINT64_MAX; - - if (path->freespace_units->critical != NULL) { - critical_high_tide = (path->dtotal_units - path->freespace_units->critical->end) * config.mult; - } - if (path->freespace_percent->critical != NULL) { - critical_high_tide = min(critical_high_tide, (uint64_t)((1.0 - path->freespace_percent->critical->end / 100) * - (path->dtotal_units * config.mult))); - } - - /* Nb: *_high_tide are unset when == UINT64_MAX */ - xasprintf(&perf, "%s %s", perf, - perfdata_uint64((!strcmp(mount_entry->me_mountdir, "none") || config.display_mntp) ? mount_entry->me_devname - : mount_entry->me_mountdir, - path->dused_units * config.mult, "B", (warning_high_tide != UINT64_MAX), warning_high_tide, - (critical_high_tide != UINT64_MAX), critical_high_tide, true, 0, true, - path->dtotal_units * config.mult)); - - if (config.display_inodes_perfdata) { - /* *_high_tide must be reinitialized at each run */ - warning_high_tide = UINT64_MAX; - critical_high_tide = UINT64_MAX; - - if (path->freeinodes_percent->warning != NULL) { - warning_high_tide = (uint64_t)fabs( - min((double)warning_high_tide, (double)(1.0 - path->freeinodes_percent->warning->end / 100) * path->inodes_total)); - } - if (path->freeinodes_percent->critical != NULL) { - critical_high_tide = (uint64_t)fabs(min( - (double)critical_high_tide, (double)(1.0 - path->freeinodes_percent->critical->end / 100) * path->inodes_total)); - } - - xasprintf(&perf_ilabel, "%s (inodes)", - (!strcmp(mount_entry->me_mountdir, "none") || config.display_mntp) ? mount_entry->me_devname - : mount_entry->me_mountdir); - /* Nb: *_high_tide are unset when == UINT64_MAX */ - xasprintf(&perf, "%s %s", perf, - perfdata_uint64(perf_ilabel, path->inodes_used, "", (warning_high_tide != UINT64_MAX), warning_high_tide, - (critical_high_tide != UINT64_MAX), critical_high_tide, true, 0, true, path->inodes_total)); + printf("For %s, used_units=%lu free_units=%lu total_units=%lu " + "fsp.fsu_blocksize=%lu\n", + mount_entry->me_mountdir, filesystem->used_bytes, filesystem->free_bytes, filesystem->total_bytes, + fsp.fsu_blocksize); } + } else { + // failed to retrieve file system data or not mounted? + filesystem = mp_int_fs_list_del(&config.path_select_list, filesystem); + continue; + } + filesystem = mp_int_fs_list_get_next(filesystem); + } - if (filesystem_result == STATE_OK && config.erronly && !verbose) { - continue; + if (verbose > 2) { + for (parameter_list_elem *filesystem = config.path_select_list.first; filesystem; + filesystem = mp_int_fs_list_get_next(filesystem)) { + assert(filesystem->best_match != NULL); + if (filesystem->best_match == NULL) { + printf("Filesystem path %s has no mount_entry!\n", filesystem->name); + } else { + // printf("Filesystem path %s has a mount_entry!\n", filesystem->name); } + } + } - char *flag_header = NULL; - if (filesystem_result && verbose >= 1) { - xasprintf(&flag_header, " %s [", state_text(filesystem_result)); + measurement_unit_list *measurements = NULL; + measurement_unit_list *current = NULL; + // create measuring units, because of groups + for (parameter_list_elem *filesystem = config.path_select_list.first; filesystem; filesystem = mp_int_fs_list_get_next(filesystem)) { + assert(filesystem->best_match != NULL); + + if (filesystem->group == NULL) { + // create a measurement unit for the fs + measurement_unit unit = create_measurement_unit_from_filesystem(*filesystem, config.display_mntp); + if (measurements == NULL) { + measurements = current = add_measurement_list(NULL, unit); } else { - xasprintf(&flag_header, ""); + current = add_measurement_list(measurements, unit); } - xasprintf(&output, "%s%s %s %llu%s (%.1f%%", output, flag_header, - (!strcmp(mount_entry->me_mountdir, "none") || config.display_mntp) ? mount_entry->me_devname - : mount_entry->me_mountdir, - path->dfree_units, config.units, path->dfree_pct); - if (path->dused_inodes_percent < 0) { - xasprintf(&output, "%s inode=-)%s;", output, (filesystem_result ? "]" : "")); + } else { + // Grouped elements are consecutive + if (measurements == NULL) { + // first entry + measurement_unit unit = create_measurement_unit_from_filesystem(*filesystem, config.display_mntp); + unit.name = strdup(filesystem->group); + measurements = current = add_measurement_list(NULL, unit); } else { - xasprintf(&output, "%s inode=%.0f%%)%s;", output, path->dfree_inodes_percent, - ((filesystem_result && verbose >= 1) ? "]" : "")); + // if this is the first element of a group, the name of the previos entry is different + if (strcmp(filesystem->group, current->unit.name) != 0) { + // so, this must be the first element of a group + measurement_unit unit = create_measurement_unit_from_filesystem(*filesystem, config.display_mntp); + unit.name = filesystem->group; + current = add_measurement_list(measurements, unit); + + } else { + // NOT the first entry of a group, add info to the other one + current->unit = add_filesystem_to_measurement_unit(current->unit, *filesystem); + } } - free(flag_header); } } - char *preamble = " - free space:"; - if (strcmp(output, "") == 0 && !config.erronly) { - preamble = ""; - xasprintf(&output, " - No disks were found for provided parameters"); + /* Process for every path in list */ + if (measurements != NULL) { + for (measurement_unit_list *unit = measurements; unit; unit = unit->next) { + mp_subcheck unit_sc = evaluate_filesystem(unit->unit, config.display_inodes_perfdata, config.display_unit); + mp_add_subcheck_to_check(&overall, unit_sc); + } + } else { + // Aparently no machting fs found + mp_subcheck none_sc = mp_subcheck_init(); + xasprintf(&none_sc.output, "No filesystems were found for the provided parameters"); + + if (config.ignore_missing) { + none_sc = mp_set_subcheck_state(none_sc, STATE_OK); + } else { + none_sc = mp_set_subcheck_state(none_sc, STATE_UNKNOWN); + } + mp_add_subcheck_to_check(&overall, none_sc); } - char *ignored_preamble = " - ignored paths:"; - printf("DISK %s%s%s%s%s|%s\n", state_text(result), (config.erronly && (result == STATE_OK)) ? "" : preamble, output, - (strcmp(ignored, "") == 0) ? "" : ignored_preamble, ignored, perf); - return result; + mp_exit(overall); } double calculate_percent(uintmax_t value, uintmax_t total) { double pct = -1; if (value <= DBL_MAX && total != 0) { - pct = (double)value / total * 100.0; + pct = (double)value / (double)total * 100.0; } + return pct; } @@ -409,11 +347,15 @@ check_disk_config_wrapper process_arguments(int argc, char **argv) { return result; } + enum { + output_format_index = CHAR_MAX + 1, + display_unit_index, + }; + static struct option longopts[] = {{"timeout", required_argument, 0, 't'}, {"warning", required_argument, 0, 'w'}, {"critical", required_argument, 0, 'c'}, {"iwarning", required_argument, 0, 'W'}, - /* Dang, -C is taken. We might want to reshuffle this. */ {"icritical", required_argument, 0, 'K'}, {"kilobytes", no_argument, 0, 'k'}, {"megabytes", no_argument, 0, 'm'}, @@ -446,6 +388,8 @@ check_disk_config_wrapper process_arguments(int argc, char **argv) { {"clear", no_argument, 0, 'C'}, {"version", no_argument, 0, 'V'}, {"help", no_argument, 0, 'h'}, + {"output-format", required_argument, 0, output_format_index}, + {"display-unit", required_argument, 0, display_unit_index}, {0, 0, 0, 0}}; for (int index = 1; index < argc; index++) { @@ -456,6 +400,17 @@ check_disk_config_wrapper process_arguments(int argc, char **argv) { int cflags = REG_NOSUB | REG_EXTENDED; int default_cflags = cflags; + char *warn_freespace_units = NULL; + char *crit_freespace_units = NULL; + char *warn_freespace_percent = NULL; + char *crit_freespace_percent = NULL; + char *warn_freeinodes_percent = NULL; + char *crit_freeinodes_percent = NULL; + + bool path_selected = false; + char *group = NULL; + byte_unit unit = MebiBytes; + result.config.mount_list = read_file_system_list(false); np_add_regex(&result.config.fs_exclude_list, "iso9660", REG_EXTENDED); @@ -485,24 +440,24 @@ check_disk_config_wrapper process_arguments(int argc, char **argv) { if (strstr(optarg, "%")) { if (*optarg == '@') { - result.config.warn_freespace_percent = optarg; + warn_freespace_percent = optarg; } else { - xasprintf(&result.config.warn_freespace_percent, "@%s", optarg); + xasprintf(&warn_freespace_percent, "@%s", optarg); } } else { if (*optarg == '@') { - result.config.warn_freespace_units = optarg; + warn_freespace_units = optarg; } else { - xasprintf(&result.config.warn_freespace_units, "@%s", optarg); + xasprintf(&warn_freespace_units, "@%s", optarg); } } break; /* Awful mistake where the range values do not make sense. Normally, - you alert if the value is within the range, but since we are using - freespace, we have to alert if outside the range. Thus we artificially - force @ at the beginning of the range, so that it is backwards compatible - */ + * you alert if the value is within the range, but since we are using + * freespace, we have to alert if outside the range. Thus we artificially + * force @ at the beginning of the range, so that it is backwards compatible + */ case 'c': /* critical threshold */ if (!is_percentage_expression(optarg) && !is_numeric(optarg)) { die(STATE_UNKNOWN, "Argument for --critical invalid or missing: %s\n", optarg); @@ -510,84 +465,92 @@ check_disk_config_wrapper process_arguments(int argc, char **argv) { if (strstr(optarg, "%")) { if (*optarg == '@') { - result.config.crit_freespace_percent = optarg; + crit_freespace_percent = optarg; } else { - xasprintf(&result.config.crit_freespace_percent, "@%s", optarg); + xasprintf(&crit_freespace_percent, "@%s", optarg); } } else { if (*optarg == '@') { - result.config.crit_freespace_units = optarg; + crit_freespace_units = optarg; } else { - xasprintf(&result.config.crit_freespace_units, "@%s", optarg); + xasprintf(&crit_freespace_units, "@%s", optarg); } } break; case 'W': /* warning inode threshold */ if (*optarg == '@') { - result.config.warn_freeinodes_percent = optarg; + warn_freeinodes_percent = optarg; } else { - xasprintf(&result.config.warn_freeinodes_percent, "@%s", optarg); + xasprintf(&warn_freeinodes_percent, "@%s", optarg); } break; case 'K': /* critical inode threshold */ if (*optarg == '@') { - result.config.crit_freeinodes_percent = optarg; + crit_freeinodes_percent = optarg; } else { - xasprintf(&result.config.crit_freeinodes_percent, "@%s", optarg); + xasprintf(&crit_freeinodes_percent, "@%s", optarg); } break; case 'u': - free(result.config.units); if (!strcasecmp(optarg, "bytes")) { - result.config.mult = (uintmax_t)1; - result.config.units = strdup("B"); + unit = Bytes; } else if (!strcmp(optarg, "KiB")) { - result.config.mult = (uintmax_t)1024; - result.config.units = strdup("KiB"); + unit = KibiBytes; } else if (!strcmp(optarg, "kB")) { - result.config.mult = (uintmax_t)1000; - result.config.units = strdup("kB"); + unit = KiloBytes; } else if (!strcmp(optarg, "MiB")) { - result.config.mult = (uintmax_t)1024 * 1024; - result.config.units = strdup("MiB"); + unit = MebiBytes; } else if (!strcmp(optarg, "MB")) { - result.config.mult = (uintmax_t)1000 * 1000; - result.config.units = strdup("MB"); + unit = MegaBytes; } else if (!strcmp(optarg, "GiB")) { - result.config.mult = (uintmax_t)1024 * 1024 * 1024; - result.config.units = strdup("GiB"); + unit = GibiBytes; } else if (!strcmp(optarg, "GB")) { - result.config.mult = (uintmax_t)1000 * 1000 * 1000; - result.config.units = strdup("GB"); + unit = GigaBytes; } else if (!strcmp(optarg, "TiB")) { - result.config.mult = (uintmax_t)1024 * 1024 * 1024 * 1024; - result.config.units = strdup("TiB"); + unit = TebiBytes; } else if (!strcmp(optarg, "TB")) { - result.config.mult = (uintmax_t)1000 * 1000 * 1000 * 1000; - result.config.units = strdup("TB"); + unit = TeraBytes; } else if (!strcmp(optarg, "PiB")) { - result.config.mult = (uintmax_t)1024 * 1024 * 1024 * 1024 * 1024; - result.config.units = strdup("PiB"); + unit = PebiBytes; } else if (!strcmp(optarg, "PB")) { - result.config.mult = (uintmax_t)1000 * 1000 * 1000 * 1000 * 1000; - result.config.units = strdup("PB"); + unit = PetaBytes; } else { die(STATE_UNKNOWN, _("unit type %s not known\n"), optarg); } - if (result.config.units == NULL) { - die(STATE_UNKNOWN, _("failed allocating storage for '%s'\n"), "units"); - } break; - case 'k': /* display mountpoint */ - result.config.mult = 1024; - free(result.config.units); - result.config.units = strdup("kiB"); + case 'k': + unit = KibiBytes; break; - case 'm': /* display mountpoint */ - result.config.mult = 1024 * 1024; - free(result.config.units); - result.config.units = strdup("MiB"); + case 'm': + unit = MebiBytes; + break; + case display_unit_index: + if (!strcasecmp(optarg, "bytes")) { + result.config.display_unit = Bytes; + } else if (!strcmp(optarg, "KiB")) { + result.config.display_unit = KibiBytes; + } else if (!strcmp(optarg, "kB")) { + result.config.display_unit = KiloBytes; + } else if (!strcmp(optarg, "MiB")) { + result.config.display_unit = MebiBytes; + } else if (!strcmp(optarg, "MB")) { + result.config.display_unit = MegaBytes; + } else if (!strcmp(optarg, "GiB")) { + result.config.display_unit = GibiBytes; + } else if (!strcmp(optarg, "GB")) { + result.config.display_unit = GigaBytes; + } else if (!strcmp(optarg, "TiB")) { + result.config.display_unit = TebiBytes; + } else if (!strcmp(optarg, "TB")) { + result.config.display_unit = TeraBytes; + } else if (!strcmp(optarg, "PiB")) { + result.config.display_unit = PebiBytes; + } else if (!strcmp(optarg, "PB")) { + result.config.display_unit = PetaBytes; + } else { + die(STATE_UNKNOWN, _("unit type %s not known\n"), optarg); + } break; case 'L': result.config.stat_remote_fs = true; @@ -599,43 +562,34 @@ check_disk_config_wrapper process_arguments(int argc, char **argv) { result.config.display_inodes_perfdata = true; break; case 'p': /* select path */ { - if (!(result.config.warn_freespace_units || result.config.crit_freespace_units || result.config.warn_freespace_percent || - result.config.crit_freespace_percent || result.config.warn_usedspace_units || result.config.crit_usedspace_units || - result.config.warn_usedspace_percent || result.config.crit_usedspace_percent || result.config.warn_usedinodes_percent || - result.config.crit_usedinodes_percent || result.config.warn_freeinodes_percent || - result.config.crit_freeinodes_percent)) { + if (!(warn_freespace_units || crit_freespace_units || warn_freespace_percent || crit_freespace_percent || + warn_freeinodes_percent || crit_freeinodes_percent)) { die(STATE_UNKNOWN, "DISK %s: %s", _("UNKNOWN"), _("Must set a threshold value before using -p\n")); } /* add parameter if not found. overwrite thresholds if path has already been added */ - struct parameter_list *se; - if (!(se = np_find_parameter(result.config.path_select_list, optarg))) { - se = np_add_parameter(&result.config.path_select_list, optarg); - - struct stat stat_buf = {}; - if (stat(optarg, &stat_buf) && result.config.ignore_missing) { - result.config.path_ignored = true; - break; - } + parameter_list_elem *search_entry; + if (!(search_entry = mp_int_fs_list_find(result.config.path_select_list, optarg))) { + search_entry = mp_int_fs_list_append(&result.config.path_select_list, optarg); + + // struct stat stat_buf = {}; + // if (stat(optarg, &stat_buf) && result.config.ignore_missing) { + // result.config.path_ignored = true; + // break; + // } } - se->group = result.config.group; - set_all_thresholds( - se, result.config.warn_freespace_units, result.config.crit_freespace_units, result.config.warn_freespace_percent, - result.config.crit_freespace_percent, result.config.warn_usedspace_units, result.config.crit_usedspace_units, - result.config.warn_usedspace_percent, result.config.crit_usedspace_percent, result.config.warn_usedinodes_percent, - result.config.crit_usedinodes_percent, result.config.warn_freeinodes_percent, result.config.crit_freeinodes_percent); + search_entry->group = group; + set_all_thresholds(search_entry, warn_freespace_units, crit_freespace_units, warn_freespace_percent, crit_freespace_percent, + + warn_freeinodes_percent, crit_freeinodes_percent); /* With autofs, it is required to stat() the path before re-populating the mount_list */ - if (!stat_path(se, result.config.ignore_missing)) { - break; - } - /* NB: We can't free the old mount_list "just like that": both list pointers and struct - * pointers are copied around. One of the reason it wasn't done yet is that other parts - * of check_disk need the same kind of cleanup so it'd better be done as a whole */ - result.config.mount_list = read_file_system_list(false); - np_set_best_match(se, result.config.mount_list, result.config.exact_match); + // if (!stat_path(se, result.config.ignore_missing)) { + // break; + // } + mp_int_fs_list_set_best_match(result.config.path_select_list, result.config.mount_list, result.config.exact_match); - result.config.path_selected = true; + path_selected = true; } break; case 'x': /* exclude path or partition */ np_add_name(&result.config.device_path_exclude_list, optarg); @@ -667,7 +621,7 @@ check_disk_config_wrapper process_arguments(int argc, char **argv) { result.config.erronly = true; break; case 'E': - if (result.config.path_selected) { + if (path_selected) { die(STATE_UNKNOWN, "DISK %s: %s", _("UNKNOWN"), _("Must set -E before selecting paths\n")); } result.config.exact_match = true; @@ -676,16 +630,16 @@ check_disk_config_wrapper process_arguments(int argc, char **argv) { result.config.freespace_ignore_reserved = true; break; case 'g': - if (result.config.path_selected) { + if (path_selected) { die(STATE_UNKNOWN, "DISK %s: %s", _("UNKNOWN"), _("Must set group value before selecting paths\n")); } - result.config.group = optarg; + group = optarg; break; case 'I': cflags |= REG_ICASE; // Intentional fallthrough case 'i': { - if (!result.config.path_selected) { + if (!path_selected) { die(STATE_UNKNOWN, "DISK %s: %s\n", _("UNKNOWN"), _("Paths need to be selected before using -i/-I. Use -A to select all paths explicitly")); } @@ -697,29 +651,20 @@ check_disk_config_wrapper process_arguments(int argc, char **argv) { die(STATE_UNKNOWN, "DISK %s: %s - %s\n", _("UNKNOWN"), _("Could not compile regular expression"), errbuf); } - struct parameter_list *temp_list = result.config.path_select_list; - struct parameter_list *previous = NULL; - while (temp_list) { - if (temp_list->best_match) { - if (np_regex_match_mount_entry(temp_list->best_match, ®ex)) { + for (parameter_list_elem *elem = result.config.path_select_list.first; elem;) { + if (elem->best_match) { + if (np_regex_match_mount_entry(elem->best_match, ®ex)) { if (verbose >= 3) { - printf("ignoring %s matching regex\n", temp_list->name); + printf("ignoring %s matching regex\n", elem->name); } - temp_list = np_del_parameter(temp_list, previous); - /* pointer to first element needs to be updated if first item gets deleted */ - if (previous == NULL) { - result.config.path_select_list = temp_list; - } - } else { - previous = temp_list; - temp_list = temp_list->name_next; + elem = mp_int_fs_list_del(&result.config.path_select_list, elem); + continue; } - } else { - previous = temp_list; - temp_list = temp_list->name_next; } + + elem = mp_int_fs_list_get_next(elem); } cflags = default_cflags; @@ -734,11 +679,8 @@ check_disk_config_wrapper process_arguments(int argc, char **argv) { cflags |= REG_ICASE; // Intentional fallthrough case 'r': { - if (!(result.config.warn_freespace_units || result.config.crit_freespace_units || result.config.warn_freespace_percent || - result.config.crit_freespace_percent || result.config.warn_usedspace_units || result.config.crit_usedspace_units || - result.config.warn_usedspace_percent || result.config.crit_usedspace_percent || result.config.warn_usedinodes_percent || - result.config.crit_usedinodes_percent || result.config.warn_freeinodes_percent || - result.config.crit_freeinodes_percent)) { + if (!(warn_freespace_units || crit_freespace_units || warn_freespace_percent || crit_freespace_percent || + warn_freeinodes_percent || crit_freeinodes_percent)) { die(STATE_UNKNOWN, "DISK %s: %s", _("UNKNOWN"), _("Must set a threshold value before using -r/-R/-A (--ereg-path/--eregi-path/--all)\n")); } @@ -760,31 +702,28 @@ check_disk_config_wrapper process_arguments(int argc, char **argv) { } /* add parameter if not found. overwrite thresholds if path has already been added */ - struct parameter_list *se = NULL; - if (!(se = np_find_parameter(result.config.path_select_list, me->me_mountdir))) { - se = np_add_parameter(&result.config.path_select_list, me->me_mountdir); + parameter_list_elem *se = NULL; + if (!(se = mp_int_fs_list_find(result.config.path_select_list, me->me_mountdir))) { + se = mp_int_fs_list_append(&result.config.path_select_list, me->me_mountdir); } - se->group = result.config.group; - set_all_thresholds(se, result.config.warn_freespace_units, result.config.crit_freespace_units, - result.config.warn_freespace_percent, result.config.crit_freespace_percent, - result.config.warn_usedspace_units, result.config.crit_usedspace_units, - result.config.warn_usedspace_percent, result.config.crit_usedspace_percent, - result.config.warn_usedinodes_percent, result.config.crit_usedinodes_percent, - result.config.warn_freeinodes_percent, result.config.crit_freeinodes_percent); + se->group = group; + set_all_thresholds(se, warn_freespace_units, crit_freespace_units, warn_freespace_percent, crit_freespace_percent, + warn_freeinodes_percent, crit_freeinodes_percent); } } - if (!found && result.config.ignore_missing) { - result.config.path_ignored = true; - result.config.path_selected = true; - break; - } if (!found) { + if (result.config.ignore_missing) { + result.config.path_ignored = true; + path_selected = true; + break; + } + die(STATE_UNKNOWN, "DISK %s: %s - %s\n", _("UNKNOWN"), _("Regular expression did not match any path or disk"), optarg); } - result.config.path_selected = true; - np_set_best_match(result.config.path_select_list, result.config.mount_list, result.config.exact_match); + path_selected = true; + mp_int_fs_list_set_best_match(result.config.path_select_list, result.config.mount_list, result.config.exact_match); cflags = default_cflags; } break; @@ -793,37 +732,28 @@ check_disk_config_wrapper process_arguments(int argc, char **argv) { break; case 'C': { /* add all mount entries to path_select list if no partitions have been explicitly defined using -p */ - if (!result.config.path_selected) { - struct parameter_list *path; + if (!path_selected) { + parameter_list_elem *path; for (struct mount_entry *me = result.config.mount_list; me; me = me->me_next) { - if (!(path = np_find_parameter(result.config.path_select_list, me->me_mountdir))) { - path = np_add_parameter(&result.config.path_select_list, me->me_mountdir); + if (!(path = mp_int_fs_list_find(result.config.path_select_list, me->me_mountdir))) { + path = mp_int_fs_list_append(&result.config.path_select_list, me->me_mountdir); } path->best_match = me; - path->group = result.config.group; - set_all_thresholds(path, result.config.warn_freespace_units, result.config.crit_freespace_units, - result.config.warn_freespace_percent, result.config.crit_freespace_percent, - result.config.warn_usedspace_units, result.config.crit_usedspace_units, - result.config.warn_usedspace_percent, result.config.crit_usedspace_percent, - result.config.warn_usedinodes_percent, result.config.crit_usedinodes_percent, - result.config.warn_freeinodes_percent, result.config.crit_freeinodes_percent); + path->group = group; + set_all_thresholds(path, warn_freespace_units, crit_freespace_units, warn_freespace_percent, crit_freespace_percent, + warn_freeinodes_percent, crit_freeinodes_percent); } } - result.config.warn_freespace_units = NULL; - result.config.crit_freespace_units = NULL; - result.config.warn_usedspace_units = NULL; - result.config.crit_usedspace_units = NULL; - result.config.warn_freespace_percent = NULL; - result.config.crit_freespace_percent = NULL; - result.config.warn_usedspace_percent = NULL; - result.config.crit_usedspace_percent = NULL; - result.config.warn_usedinodes_percent = NULL; - result.config.crit_usedinodes_percent = NULL; - result.config.warn_freeinodes_percent = NULL; - result.config.crit_freeinodes_percent = NULL; - - result.config.path_selected = false; - result.config.group = NULL; + + warn_freespace_units = NULL; + crit_freespace_units = NULL; + warn_freespace_percent = NULL; + crit_freespace_percent = NULL; + warn_freeinodes_percent = NULL; + crit_freeinodes_percent = NULL; + + path_selected = false; + group = NULL; } break; case 'V': /* version */ print_revision(progname, NP_VERSION); @@ -833,68 +763,145 @@ check_disk_config_wrapper process_arguments(int argc, char **argv) { exit(STATE_UNKNOWN); case '?': /* help */ usage(_("Unknown argument")); + 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; + } } } /* Support for "check_disk warn crit [fs]" with thresholds at used% level */ int index = optind; - if (result.config.warn_usedspace_percent == NULL && argc > index && is_intnonneg(argv[index])) { + if (argc > index && is_intnonneg(argv[index])) { if (verbose > 0) { printf("Got an positional warn threshold: %s\n", argv[index]); } - result.config.warn_usedspace_percent = argv[index++]; + char *range = argv[index++]; + mp_range_parsed tmp = mp_parse_range_string(range); + if (tmp.error != MP_PARSING_SUCCES) { + die(STATE_UNKNOWN, "failed to parse warning threshold"); + } + + mp_range tmp_range = tmp.range; + // Invert range to use it for free instead of used + // tmp_range.alert_on_inside_range = !tmp_range.alert_on_inside_range; + + warn_freespace_percent = mp_range_to_string(tmp_range); + + if (verbose > 0) { + printf("Positional warning threshold transformed to: %s\n", warn_freespace_percent); + } } - if (result.config.crit_usedspace_percent == NULL && argc > index && is_intnonneg(argv[index])) { + if (argc > index && is_intnonneg(argv[index])) { if (verbose > 0) { printf("Got an positional crit threshold: %s\n", argv[index]); } - result.config.crit_usedspace_percent = argv[index++]; + char *range = argv[index++]; + mp_range_parsed tmp = mp_parse_range_string(range); + if (tmp.error != MP_PARSING_SUCCES) { + die(STATE_UNKNOWN, "failed to parse warning threshold"); + } + + mp_range tmp_range = tmp.range; + // Invert range to use it for free instead of used + // tmp_range.alert_on_inside_range = !tmp_range.alert_on_inside_range; + + crit_freespace_percent = mp_range_to_string(tmp_range); + + if (verbose > 0) { + printf("Positional critical threshold transformed to: %s\n", crit_freespace_percent); + } } if (argc > index) { if (verbose > 0) { printf("Got an positional filesystem: %s\n", argv[index]); } - struct parameter_list *se = np_add_parameter(&result.config.path_select_list, strdup(argv[index++])); - result.config.path_selected = true; - set_all_thresholds(se, result.config.warn_freespace_units, result.config.crit_freespace_units, result.config.warn_freespace_percent, - result.config.crit_freespace_percent, result.config.warn_usedspace_units, result.config.crit_usedspace_units, - result.config.warn_usedspace_percent, result.config.crit_usedspace_percent, - result.config.warn_usedinodes_percent, result.config.crit_usedinodes_percent, - result.config.warn_freeinodes_percent, result.config.crit_freeinodes_percent); + struct parameter_list *se = mp_int_fs_list_append(&result.config.path_select_list, strdup(argv[index++])); + path_selected = true; + set_all_thresholds(se, warn_freespace_units, crit_freespace_units, warn_freespace_percent, crit_freespace_percent, + warn_freeinodes_percent, crit_freeinodes_percent); } - if (result.config.units == NULL) { - result.config.units = strdup("MiB"); - result.config.mult = (uintmax_t)1024 * 1024; + // If a list of paths has not been explicitely selected, find entire + // mount list and create list of paths + if (!path_selected && !result.config.path_ignored) { + for (struct mount_entry *me = result.config.mount_list; me; me = me->me_next) { + if (me->me_dummy != 0) { + // just do not add dummy filesystems + continue; + } + + parameter_list_elem *path = NULL; + if (!(path = mp_int_fs_list_find(result.config.path_select_list, me->me_mountdir))) { + path = mp_int_fs_list_append(&result.config.path_select_list, me->me_mountdir); + } + path->best_match = me; + path->group = group; + set_all_thresholds(path, warn_freespace_units, crit_freespace_units, warn_freespace_percent, crit_freespace_percent, + warn_freeinodes_percent, crit_freeinodes_percent); + } + } + + // Set thresholds to the appropriate unit + for (parameter_list_elem *tmp = result.config.path_select_list.first; tmp; tmp = mp_int_fs_list_get_next(tmp)) { + + mp_perfdata_value factor = mp_create_pd_value(unit); + + if (tmp->freespace_units.critical_is_set) { + tmp->freespace_units.critical = mp_range_multiply(tmp->freespace_units.critical, factor); + } + if (tmp->freespace_units.warning_is_set) { + tmp->freespace_units.warning = mp_range_multiply(tmp->freespace_units.warning, factor); + } } return result; } -void set_all_thresholds(struct parameter_list *path, char *warn_freespace_units, char *crit_freespace_units, char *warn_freespace_percent, - char *crit_freespace_percent, char *warn_usedspace_units, char *crit_usedspace_units, char *warn_usedspace_percent, - char *crit_usedspace_percent, char *warn_usedinodes_percent, char *crit_usedinodes_percent, - char *warn_freeinodes_percent, char *crit_freeinodes_percent) { - free(path->freespace_units); - set_thresholds(&path->freespace_units, warn_freespace_units, crit_freespace_units); +void set_all_thresholds(parameter_list_elem *path, char *warn_freespace_units, char *crit_freespace_units, char *warn_freespace_percent, + char *crit_freespace_percent, char *warn_freeinodes_percent, char *crit_freeinodes_percent) { + mp_range_parsed tmp; + + if (warn_freespace_units) { + tmp = mp_parse_range_string(warn_freespace_units); + path->freespace_units = mp_thresholds_set_warn(path->freespace_units, tmp.range); + } - free(path->freespace_percent); - set_thresholds(&path->freespace_percent, warn_freespace_percent, crit_freespace_percent); + if (crit_freespace_units) { + tmp = mp_parse_range_string(crit_freespace_units); + path->freespace_units = mp_thresholds_set_crit(path->freespace_units, tmp.range); + } - free(path->usedspace_units); - set_thresholds(&path->usedspace_units, warn_usedspace_units, crit_usedspace_units); + if (warn_freespace_percent) { + tmp = mp_parse_range_string(warn_freespace_percent); + path->freespace_percent = mp_thresholds_set_warn(path->freespace_percent, tmp.range); + } - free(path->usedspace_percent); - set_thresholds(&path->usedspace_percent, warn_usedspace_percent, crit_usedspace_percent); + if (crit_freespace_percent) { + tmp = mp_parse_range_string(crit_freespace_percent); + path->freespace_percent = mp_thresholds_set_crit(path->freespace_percent, tmp.range); + } - free(path->usedinodes_percent); - set_thresholds(&path->usedinodes_percent, warn_usedinodes_percent, crit_usedinodes_percent); + if (warn_freeinodes_percent) { + tmp = mp_parse_range_string(warn_freeinodes_percent); + path->freeinodes_percent = mp_thresholds_set_warn(path->freeinodes_percent, tmp.range); + } - free(path->freeinodes_percent); - set_thresholds(&path->freeinodes_percent, warn_freeinodes_percent, crit_freeinodes_percent); + if (crit_freeinodes_percent) { + tmp = mp_parse_range_string(crit_freeinodes_percent); + path->freeinodes_percent = mp_thresholds_set_crit(path->freeinodes_percent, tmp.range); + } } void print_help(void) { @@ -941,8 +948,6 @@ void print_help(void) { printf(" %s\n", _("Display inode usage in perfdata")); printf(" %s\n", "-g, --group=NAME"); printf(" %s\n", _("Group paths. Thresholds apply to (free-)space of all partitions together")); - printf(" %s\n", "-k, --kilobytes"); - printf(" %s\n", _("Same as '--units kB'")); printf(" %s\n", "-l, --local"); printf(" %s\n", _("Only check local filesystems")); printf(" %s\n", "-L, --stat-remote-fs"); @@ -950,8 +955,6 @@ void print_help(void) { printf(" %s\n", _("to test if they are accessible (e.g. to detect Stale NFS Handles)")); printf(" %s\n", "-M, --mountpoint"); printf(" %s\n", _("Display the (block) device instead of the mount point")); - printf(" %s\n", "-m, --megabytes"); - printf(" %s\n", _("Same as '--units MB'")); printf(" %s\n", "-A, --all"); printf(" %s\n", _("Explicitly select all paths. This is equivalent to -R '.*'")); printf(" %s\n", "-R, --eregi-path=PATH, --eregi-partition=PARTITION"); @@ -967,12 +970,25 @@ void print_help(void) { printf(" %s\n", _("(Provide this option before -p / -r / --ereg-path if used)")); printf(UT_PLUG_TIMEOUT, DEFAULT_SOCKET_TIMEOUT); printf(" %s\n", "-u, --units=STRING"); - printf(" %s\n", _("Choose bytes, kB, MB, GB, TB (default: MB)")); + printf(" %s\n", _("Select the unit used for the absolute value thresholds")); + printf( + " %s\n", + _("Choose one of \"bytes\", \"KiB\", \"kB\", \"MiB\", \"MB\", \"GiB\", \"GB\", \"TiB\", \"TB\", \"PiB\", \"PB\" (default: MiB)")); + printf(" %s\n", "-k, --kilobytes"); + printf(" %s\n", _("Same as '--units kB'")); + printf(" %s\n", "--display-unit"); + printf(" %s\n", _("Select the unit used for in the output")); + printf( + " %s\n", + _("Choose one of \"bytes\", \"KiB\", \"kB\", \"MiB\", \"MB\", \"GiB\", \"GB\", \"TiB\", \"TB\", \"PiB\", \"PB\" (default: MiB)")); + printf(" %s\n", "-m, --megabytes"); + printf(" %s\n", _("Same as '--units MB'")); printf(UT_VERBOSE); printf(" %s\n", "-X, --exclude-type=TYPE_REGEX"); printf(" %s\n", _("Ignore all filesystems of types matching given regex(7) (may be repeated)")); printf(" %s\n", "-N, --include-type=TYPE_REGEX"); printf(" %s\n", _("Check only filesystems where the type matches this given regex(7) (may be repeated)")); + printf(UT_OUTPUT_FORMAT); printf("\n"); printf("%s\n", _("General usage hints:")); @@ -1002,7 +1018,7 @@ void print_usage(void) { printf("[-t timeout] [-u unit] [-v] [-X type_regex] [-N type]\n"); } -bool stat_path(struct parameter_list *parameters, bool ignore_missing) { +bool stat_path(parameter_list_elem *parameters, bool ignore_missing) { /* Stat entry to check that dir exists and is accessible */ if (verbose >= 3) { printf("calling stat on %s\n", parameters->name); @@ -1023,97 +1039,166 @@ bool stat_path(struct parameter_list *parameters, bool ignore_missing) { return true; } -void get_stats(struct parameter_list *parameters, struct fs_usage *fsp, bool ignore_missing, bool freespace_ignore_reserved, uintmax_t mult, - struct parameter_list *path_select_list, struct name_list *seen) { - struct fs_usage tmpfsp; - bool first = true; - - if (parameters->group == NULL) { - get_path_stats(parameters, fsp, freespace_ignore_reserved, mult, seen); - } else { - /* find all group members */ - for (struct parameter_list *p_list = path_select_list; p_list; p_list = p_list->name_next) { - -#ifdef __CYGWIN__ - if (strncmp(p_list->name, "/cygdrive/", 10) != 0) { - continue; - } -#endif - - if (p_list->group && !(strcmp(p_list->group, parameters->group))) { - if (!stat_path(p_list, ignore_missing)) { - continue; - } - get_fs_usage(p_list->best_match->me_mountdir, p_list->best_match->me_devname, &tmpfsp); - get_path_stats(p_list, &tmpfsp, freespace_ignore_reserved, mult, seen); - if (verbose >= 3) { - printf("Group %s: adding %lu blocks sized %lu, (%s) used_units=%lu free_units=%lu total_units=%lu mult=%lu\n", - p_list->group, tmpfsp.fsu_blocks, tmpfsp.fsu_blocksize, p_list->best_match->me_mountdir, p_list->dused_units, - p_list->dfree_units, p_list->dtotal_units, mult); - } - - /* prevent counting the first FS of a group twice since its parameter_list entry - * is used to carry the information of all file systems of the entire group */ - if (!first) { - parameters->total += p_list->total; - parameters->available += p_list->available; - parameters->available_to_root += p_list->available_to_root; - parameters->used += p_list->used; - - parameters->dused_units += p_list->dused_units; - parameters->dfree_units += p_list->dfree_units; - parameters->dtotal_units += p_list->dtotal_units; - parameters->inodes_total += p_list->inodes_total; - parameters->inodes_free += p_list->inodes_free; - parameters->inodes_free_to_root += p_list->inodes_free_to_root; - parameters->inodes_used += p_list->inodes_used; - } - first = false; - } - if (verbose >= 3) { - printf("Group %s now has: used_units=%lu free_units=%lu total_units=%lu fsu_blocksize=%lu mult=%lu\n", parameters->group, - parameters->dused_units, parameters->dfree_units, parameters->dtotal_units, tmpfsp.fsu_blocksize, mult); - } - } - /* modify devname and mountdir for output */ - parameters->best_match->me_mountdir = parameters->best_match->me_devname = parameters->group; - } - /* finally calculate percentages for either plain FS or summed up group */ - parameters->dused_pct = - calculate_percent(parameters->used, parameters->used + parameters->available); /* used + available can never be > uintmax */ - parameters->dfree_pct = 100.0 - parameters->dused_pct; - parameters->dused_inodes_percent = calculate_percent(parameters->inodes_total - parameters->inodes_free, parameters->inodes_total); - parameters->dfree_inodes_percent = 100 - parameters->dused_inodes_percent; -} +static parameter_list_elem get_path_stats(parameter_list_elem parameters, const struct fs_usage fsp, bool freespace_ignore_reserved) { + uintmax_t available = fsp.fsu_bavail; + uintmax_t available_to_root = fsp.fsu_bfree; + uintmax_t used = fsp.fsu_blocks - fsp.fsu_bfree; + uintmax_t total; -void get_path_stats(struct parameter_list *parameters, struct fs_usage *fsp, bool freespace_ignore_reserved, uintmax_t mult, - struct name_list *seen) { - parameters->available = fsp->fsu_bavail; - parameters->available_to_root = fsp->fsu_bfree; - parameters->used = fsp->fsu_blocks - fsp->fsu_bfree; if (freespace_ignore_reserved) { /* option activated : we subtract the root-reserved space from the total */ - parameters->total = fsp->fsu_blocks - parameters->available_to_root + parameters->available; + total = fsp.fsu_blocks - available_to_root + available; } else { /* default behaviour : take all the blocks into account */ - parameters->total = fsp->fsu_blocks; + total = fsp.fsu_blocks; } - parameters->dused_units = parameters->used * fsp->fsu_blocksize / mult; - parameters->dfree_units = parameters->available * fsp->fsu_blocksize / mult; - parameters->dtotal_units = parameters->total * fsp->fsu_blocksize / mult; + parameters.used_bytes = used * fsp.fsu_blocksize; + parameters.free_bytes = available * fsp.fsu_blocksize; + parameters.total_bytes = total * fsp.fsu_blocksize; + /* Free file nodes. Not sure the workaround is required, but in case...*/ - parameters->inodes_free = fsp->fsu_ffree; - parameters->inodes_free_to_root = fsp->fsu_ffree; /* Free file nodes for root. */ - parameters->inodes_used = fsp->fsu_files - fsp->fsu_ffree; + parameters.inodes_free = fsp.fsu_ffree; + parameters.inodes_free_to_root = fsp.fsu_ffree; /* Free file nodes for root. */ + parameters.inodes_used = fsp.fsu_files - fsp.fsu_ffree; + if (freespace_ignore_reserved) { /* option activated : we subtract the root-reserved inodes from the total */ /* not all OS report fsp->fsu_favail, only the ones with statvfs syscall */ /* for others, fsp->fsu_ffree == fsp->fsu_favail */ - parameters->inodes_total = fsp->fsu_files - parameters->inodes_free_to_root + parameters->inodes_free; + parameters.inodes_total = fsp.fsu_files - parameters.inodes_free_to_root + parameters.inodes_free; } else { /* default behaviour : take all the inodes into account */ - parameters->inodes_total = fsp->fsu_files; + parameters.inodes_total = fsp.fsu_files; + } + + return parameters; +} + +mp_subcheck evaluate_filesystem(measurement_unit measurement_unit, bool display_inodes_perfdata, byte_unit unit) { + mp_subcheck result = mp_subcheck_init(); + result = mp_set_subcheck_default_state(result, STATE_UNKNOWN); + xasprintf(&result.output, "%s", measurement_unit.name); + + if (!measurement_unit.is_group && measurement_unit.filesystem_type) { + xasprintf(&result.output, "%s (%s)", result.output, measurement_unit.filesystem_type); + } + + /* Threshold comparisons */ + + // =============================== + // Free space absolute values test + mp_subcheck freespace_bytes_sc = mp_subcheck_init(); + freespace_bytes_sc = mp_set_subcheck_default_state(freespace_bytes_sc, STATE_OK); + + if (unit != Humanized) { + xasprintf(&freespace_bytes_sc.output, "Free space absolute: %ju%s (of %ju%s)", (uintmax_t)(measurement_unit.free_bytes / unit), + get_unit_string(unit), (uintmax_t)(measurement_unit.total_bytes / unit), get_unit_string(unit)); + } else { + xasprintf(&freespace_bytes_sc.output, "Free space absolute: %s (of %s)", humanize_byte_value(measurement_unit.free_bytes, false), + humanize_byte_value(measurement_unit.total_bytes, false)); } - np_add_name(&seen, parameters->best_match->me_mountdir); + + mp_perfdata used_space = perfdata_init(); + used_space.label = measurement_unit.name; + used_space.value = mp_create_pd_value(measurement_unit.free_bytes); + used_space = mp_set_pd_max_value(used_space, mp_create_pd_value(measurement_unit.total_bytes)); + used_space = mp_set_pd_min_value(used_space, mp_create_pd_value(0)); + used_space.uom = "B"; + used_space = mp_pd_set_thresholds(used_space, measurement_unit.freespace_bytes_thresholds); + freespace_bytes_sc = mp_set_subcheck_state(freespace_bytes_sc, mp_get_pd_status(used_space)); + + // special case for absolute space thresholds here: + // if absolute values are not set, compute the thresholds from percentage thresholds + mp_thresholds temp_thlds = measurement_unit.freespace_bytes_thresholds; + if (!temp_thlds.critical_is_set && measurement_unit.freespace_percent_thresholds.critical_is_set) { + mp_range tmp_range = measurement_unit.freespace_percent_thresholds.critical; + + if (!tmp_range.end_infinity) { + tmp_range.end = mp_create_pd_value(mp_get_pd_value(tmp_range.end) / 100 * measurement_unit.total_bytes); + } + + if (!tmp_range.start_infinity) { + tmp_range.start = mp_create_pd_value(mp_get_pd_value(tmp_range.start) / 100 * measurement_unit.total_bytes); + } + measurement_unit.freespace_bytes_thresholds = mp_thresholds_set_crit(measurement_unit.freespace_bytes_thresholds, tmp_range); + used_space = mp_pd_set_thresholds(used_space, measurement_unit.freespace_bytes_thresholds); + } + + if (!temp_thlds.warning_is_set && measurement_unit.freespace_percent_thresholds.warning_is_set) { + mp_range tmp_range = measurement_unit.freespace_percent_thresholds.warning; + if (!tmp_range.end_infinity) { + tmp_range.end = mp_create_pd_value(mp_get_pd_value(tmp_range.end) / 100 * measurement_unit.total_bytes); + } + if (!tmp_range.start_infinity) { + tmp_range.start = mp_create_pd_value(mp_get_pd_value(tmp_range.start) / 100 * measurement_unit.total_bytes); + } + measurement_unit.freespace_bytes_thresholds = mp_thresholds_set_warn(measurement_unit.freespace_bytes_thresholds, tmp_range); + used_space = mp_pd_set_thresholds(used_space, measurement_unit.freespace_bytes_thresholds); + } + + mp_add_perfdata_to_subcheck(&freespace_bytes_sc, used_space); + mp_add_subcheck_to_subcheck(&result, freespace_bytes_sc); + + // ========================== + // Free space percentage test + mp_subcheck freespace_percent_sc = mp_subcheck_init(); + freespace_percent_sc = mp_set_subcheck_default_state(freespace_percent_sc, STATE_OK); + + double free_percentage = calculate_percent(measurement_unit.free_bytes, measurement_unit.total_bytes); + xasprintf(&freespace_percent_sc.output, "Free space percentage: %g%%", free_percentage); + + // Using perfdata here just to get to the test result + mp_perfdata free_space_percent_pd = perfdata_init(); + free_space_percent_pd.value = mp_create_pd_value(free_percentage); + free_space_percent_pd = mp_pd_set_thresholds(free_space_percent_pd, measurement_unit.freespace_percent_thresholds); + + freespace_percent_sc = mp_set_subcheck_state(freespace_percent_sc, mp_get_pd_status(free_space_percent_pd)); + mp_add_subcheck_to_subcheck(&result, freespace_percent_sc); + + // ================ + // Free inodes test + // Only ever useful if the number of inodes is static (e.g. ext4), + // not when it is dynamic (e.g btrfs) + // Assumption: if the total number of inodes == 0, we have such a case and just skip the test + if (measurement_unit.inodes_total > 0) { + mp_subcheck freeindodes_percent_sc = mp_subcheck_init(); + freeindodes_percent_sc = mp_set_subcheck_default_state(freeindodes_percent_sc, STATE_OK); + + double free_inode_percentage = calculate_percent(measurement_unit.inodes_free, measurement_unit.inodes_total); + + if (verbose > 0) { + printf("free inode percentage computed: %g\n", free_inode_percentage); + } + + xasprintf(&freeindodes_percent_sc.output, "Inodes free: %g%% (%ju of %ju)", free_inode_percentage, measurement_unit.inodes_free, + measurement_unit.inodes_total); + + mp_perfdata inodes_pd = perfdata_init(); + xasprintf(&inodes_pd.label, "%s (inodes)", measurement_unit.name); + inodes_pd = mp_set_pd_value(inodes_pd, measurement_unit.inodes_used); + inodes_pd = mp_set_pd_max_value(inodes_pd, mp_create_pd_value(measurement_unit.inodes_total)); + inodes_pd = mp_set_pd_min_value(inodes_pd, mp_create_pd_value(0)); + + mp_thresholds absolut_inode_thresholds = measurement_unit.freeinodes_percent_thresholds; + + if (absolut_inode_thresholds.critical_is_set) { + absolut_inode_thresholds.critical = + mp_range_multiply(absolut_inode_thresholds.critical, mp_create_pd_value(measurement_unit.inodes_total / 100)); + } + if (absolut_inode_thresholds.warning_is_set) { + absolut_inode_thresholds.warning = + mp_range_multiply(absolut_inode_thresholds.warning, mp_create_pd_value(measurement_unit.inodes_total / 100)); + } + + inodes_pd = mp_pd_set_thresholds(inodes_pd, absolut_inode_thresholds); + + freeindodes_percent_sc = mp_set_subcheck_state(freeindodes_percent_sc, mp_get_pd_status(inodes_pd)); + if (display_inodes_perfdata) { + mp_add_perfdata_to_subcheck(&freeindodes_percent_sc, inodes_pd); + } + mp_add_subcheck_to_subcheck(&result, freeindodes_percent_sc); + } + + return result; } diff --git a/plugins/check_disk.d/config.h b/plugins/check_disk.d/config.h deleted file mode 100644 index d890fc1a..00000000 --- a/plugins/check_disk.d/config.h +++ /dev/null @@ -1,92 +0,0 @@ -#pragma once - -#include "../../config.h" -#include -#include - -typedef struct { - // Output options - bool erronly; - bool display_mntp; - /* show only local filesystems. */ - bool show_local_fs; - /* show only local filesystems but call stat() on remote ones. */ - bool stat_remote_fs; - bool display_inodes_perfdata; - - bool exact_match; - bool ignore_missing; - bool path_ignored; - bool path_selected; - bool freespace_ignore_reserved; - - char *warn_freespace_units; - char *crit_freespace_units; - char *warn_freespace_percent; - char *crit_freespace_percent; - char *warn_usedspace_units; - char *crit_usedspace_units; - char *warn_usedspace_percent; - char *crit_usedspace_percent; - char *warn_usedinodes_percent; - char *crit_usedinodes_percent; - char *warn_freeinodes_percent; - char *crit_freeinodes_percent; - - /* Linked list of filesystem types to omit. - If the list is empty, don't exclude any types. */ - struct regex_list *fs_exclude_list; - /* Linked list of filesystem types to check. - If the list is empty, include all types. */ - struct regex_list *fs_include_list; - struct name_list *device_path_exclude_list; - struct parameter_list *path_select_list; - /* Linked list of mounted filesystems. */ - struct mount_entry *mount_list; - struct name_list *seen; - - char *units; - uintmax_t mult; - char *group; -} check_disk_config; - -check_disk_config check_disk_config_init() { - check_disk_config tmp = { - .erronly = false, - .display_mntp = false, - .show_local_fs = false, - .stat_remote_fs = false, - .display_inodes_perfdata = false, - - .exact_match = false, - .ignore_missing = false, - .path_ignored = false, - .path_selected = false, - .freespace_ignore_reserved = false, - - .warn_freespace_units = NULL, - .crit_freespace_units = NULL, - .warn_freespace_percent = NULL, - .crit_freespace_percent = NULL, - .warn_usedspace_units = NULL, - .crit_usedspace_units = NULL, - .warn_usedspace_percent = NULL, - .crit_usedspace_percent = NULL, - .warn_usedinodes_percent = NULL, - .crit_usedinodes_percent = NULL, - .warn_freeinodes_percent = NULL, - .crit_freeinodes_percent = NULL, - - .fs_exclude_list = NULL, - .fs_include_list = NULL, - .device_path_exclude_list = NULL, - .path_select_list = NULL, - .mount_list = NULL, - .seen = NULL, - - .units = NULL, - .mult = 1024 * 1024, - .group = NULL, - }; - return tmp; -} diff --git a/plugins/check_disk.d/utils_disk.c b/plugins/check_disk.d/utils_disk.c index 369c85d5..3986a8a8 100644 --- a/plugins/check_disk.d/utils_disk.c +++ b/plugins/check_disk.d/utils_disk.c @@ -29,7 +29,12 @@ #include "../common.h" #include "utils_disk.h" #include "../../gl/fsusage.h" +#include "../../lib/thresholds.h" +#include "../../lib/states.h" +#include +#include #include +#include void np_add_name(struct name_list **list, const char *name) { struct name_list *new_entry; @@ -70,82 +75,367 @@ int np_add_regex(struct regex_list **list, const char *regex, int cflags) { return regcomp_result; } -struct parameter_list parameter_list_init(const char *name) { - struct parameter_list result = { +parameter_list_elem parameter_list_init(const char *name) { + parameter_list_elem result = { .name = strdup(name), .best_match = NULL, - .name_next = NULL, - .name_prev = NULL, - - .freespace_units = NULL, - .freespace_percent = NULL, - .usedspace_units = NULL, - .usedspace_percent = NULL, - .usedinodes_percent = NULL, - .freeinodes_percent = NULL, + .freespace_units = mp_thresholds_init(), + .freespace_percent = mp_thresholds_init(), + .freeinodes_percent = mp_thresholds_init(), .group = NULL, - .dfree_pct = -1, - .dused_pct = -1, - .total = 0, - .available = 0, - .available_to_root = 0, - .used = 0, - .dused_units = 0, - .dfree_units = 0, - .dtotal_units = 0, + .inodes_total = 0, .inodes_free = 0, .inodes_free_to_root = 0, .inodes_used = 0, - .dused_inodes_percent = 0, - .dfree_inodes_percent = 0, + + .used_bytes = 0, + .free_bytes = 0, + .total_bytes = 0, + + .next = NULL, + .prev = NULL, }; return result; } -/* Initialises a new parameter at the end of list */ -struct parameter_list *np_add_parameter(struct parameter_list **list, const char *name) { - struct parameter_list *current = *list; - struct parameter_list *new_path; - new_path = (struct parameter_list *)malloc(sizeof *new_path); +/* Returns true if name is in list */ +bool np_find_name(struct name_list *list, const char *name) { + if (list == NULL || name == NULL) { + return false; + } + for (struct name_list *iterator = list; iterator; iterator = iterator->next) { + if (!strcmp(name, iterator->name)) { + return true; + } + } + return false; +} + +/* Returns true if name is in list */ +bool np_find_regmatch(struct regex_list *list, const char *name) { + if (name == NULL) { + return false; + } + + size_t len = strlen(name); + + for (; list; list = list->next) { + /* Emulate a full match as if surrounded with ^( )$ + by checking whether the match spans the whole name */ + regmatch_t dummy_match; + if (!regexec(&list->regex, name, 1, &dummy_match, 0) && dummy_match.rm_so == 0 && dummy_match.rm_eo == len) { + return true; + } + } + + return false; +} + +bool np_seen_name(struct name_list *list, const char *name) { + for (struct name_list *iterator = list; iterator; iterator = iterator->next) { + if (!strcmp(iterator->name, name)) { + return true; + } + } + return false; +} + +bool np_regex_match_mount_entry(struct mount_entry *me, regex_t *re) { + return ((regexec(re, me->me_devname, (size_t)0, NULL, 0) == 0) || (regexec(re, me->me_mountdir, (size_t)0, NULL, 0) == 0)); +} + +check_disk_config check_disk_config_init() { + check_disk_config tmp = { + .erronly = false, + .display_mntp = false, + .show_local_fs = false, + .stat_remote_fs = false, + .display_inodes_perfdata = false, + + .exact_match = false, + .freespace_ignore_reserved = false, + .ignore_missing = false, + .path_ignored = false, + + // FS Filters + .fs_exclude_list = NULL, + .fs_include_list = NULL, + .device_path_exclude_list = NULL, + + // Actual filesystems paths to investigate + .path_select_list = filesystem_list_init(), + + .mount_list = NULL, + .seen = NULL, + + .display_unit = Humanized, + // .unit = MebiBytes, + + .output_format_is_set = false, + }; + return tmp; +} + +char *get_unit_string(byte_unit unit) { + switch (unit) { + case Bytes: + return "Bytes"; + case KibiBytes: + return "KiB"; + case MebiBytes: + return "MiB"; + case GibiBytes: + return "GiB"; + case TebiBytes: + return "TiB"; + case PebiBytes: + return "PiB"; + case ExbiBytes: + return "EiB"; + case KiloBytes: + return "KB"; + case MegaBytes: + return "MB"; + case GigaBytes: + return "GB"; + case TeraBytes: + return "TB"; + case PetaBytes: + return "PB"; + case ExaBytes: + return "EB"; + default: + assert(false); + } +} + +measurement_unit measurement_unit_init() { + measurement_unit tmp = { + .name = NULL, + .filesystem_type = NULL, + .is_group = false, + + .freeinodes_percent_thresholds = mp_thresholds_init(), + .freespace_percent_thresholds = mp_thresholds_init(), + .freespace_bytes_thresholds = mp_thresholds_init(), + + .free_bytes = 0, + .used_bytes = 0, + .total_bytes = 0, + + .inodes_total = 0, + .inodes_free = 0, + .inodes_free_to_root = 0, + .inodes_used = 0, + }; + return tmp; +} + +// Add a given element to the list, memory for the new element is freshly allocated +// Returns a pointer to new element +measurement_unit_list *add_measurement_list(measurement_unit_list *list, measurement_unit elem) { + // find last element + measurement_unit_list *new = NULL; + if (list == NULL) { + new = calloc(1, sizeof(measurement_unit_list)); + if (new == NULL) { + die(STATE_UNKNOWN, _("allocation failed")); + } + } else { + measurement_unit_list *list_elem = list; + while (list_elem->next != NULL) { + list_elem = list_elem->next; + } + + new = calloc(1, sizeof(measurement_unit_list)); + if (new == NULL) { + die(STATE_UNKNOWN, _("allocation failed")); + } + + list_elem->next = new; + } + + new->unit = elem; + new->next = NULL; + return new; +} + +measurement_unit add_filesystem_to_measurement_unit(measurement_unit unit, parameter_list_elem filesystem) { + + unit.free_bytes += filesystem.free_bytes; + unit.used_bytes += filesystem.used_bytes; + unit.total_bytes += filesystem.total_bytes; + + unit.inodes_total += filesystem.inodes_total; + unit.inodes_free += filesystem.inodes_free; + unit.inodes_free_to_root += filesystem.inodes_free_to_root; + unit.inodes_used += filesystem.inodes_used; + return unit; +} + +measurement_unit create_measurement_unit_from_filesystem(parameter_list_elem filesystem, bool display_mntp) { + measurement_unit result = measurement_unit_init(); + if (!display_mntp) { + result.name = strdup(filesystem.best_match->me_mountdir); + } else { + result.name = strdup(filesystem.best_match->me_devname); + } + + if (filesystem.group) { + result.is_group = true; + } else { + result.is_group = false; + if (filesystem.best_match) { + result.filesystem_type = filesystem.best_match->me_type; + } + } + + result.freeinodes_percent_thresholds = filesystem.freeinodes_percent; + result.freespace_percent_thresholds = filesystem.freespace_percent; + result.freespace_bytes_thresholds = filesystem.freespace_units; + result.free_bytes = filesystem.free_bytes; + result.total_bytes = filesystem.total_bytes; + result.used_bytes = filesystem.used_bytes; + result.inodes_total = filesystem.inodes_total; + result.inodes_used = filesystem.inodes_used; + result.inodes_free = filesystem.inodes_free; + result.inodes_free_to_root = filesystem.inodes_free_to_root; + return result; +} + +#define RANDOM_STRING_LENGTH 64 + +char *humanize_byte_value(uintmax_t value, bool use_si_units) { + // Idea: A reasonable output should have at most 3 orders of magnitude + // before the decimal separator + // 353GiB is ok, 2444 GiB should be 2.386 TiB + char *result = calloc(RANDOM_STRING_LENGTH, sizeof(char)); + if (result == NULL) { + die(STATE_UNKNOWN, _("allocation failed")); + } + + if (use_si_units) { + // SI units, powers of 10 + if (value < KiloBytes) { + snprintf(result, RANDOM_STRING_LENGTH, "%ju B", value); + } else if (value < MegaBytes) { + snprintf(result, RANDOM_STRING_LENGTH, "%ju KB", value / KiloBytes); + } else if (value < GigaBytes) { + snprintf(result, RANDOM_STRING_LENGTH, "%ju MB", value / MegaBytes); + } else if (value < TeraBytes) { + snprintf(result, RANDOM_STRING_LENGTH, "%ju GB", value / GigaBytes); + } else if (value < PetaBytes) { + snprintf(result, RANDOM_STRING_LENGTH, "%ju TB", value / TeraBytes); + } else { + snprintf(result, RANDOM_STRING_LENGTH, "%ju PB", value / PetaBytes); + } + } else { + // IEC units, powers of 2 ^ 10 + if (value < KibiBytes) { + snprintf(result, RANDOM_STRING_LENGTH, "%ju B", value); + } else if (value < MebiBytes) { + snprintf(result, RANDOM_STRING_LENGTH, "%ju KiB", value / KibiBytes); + } else if (value < GibiBytes) { + snprintf(result, RANDOM_STRING_LENGTH, "%ju MiB", value / MebiBytes); + } else if (value < TebiBytes) { + snprintf(result, RANDOM_STRING_LENGTH, "%ju GiB", value / GibiBytes); + } else if (value < PebiBytes) { + snprintf(result, RANDOM_STRING_LENGTH, "%ju TiB", value / TebiBytes); + } else { + snprintf(result, RANDOM_STRING_LENGTH, "%ju PiB", value / PebiBytes); + } + } + + return result; +} + +filesystem_list filesystem_list_init() { + filesystem_list tmp = { + .length = 0, + .first = NULL, + }; + return tmp; +} + +parameter_list_elem *mp_int_fs_list_append(filesystem_list *list, const char *name) { + parameter_list_elem *current = list->first; + parameter_list_elem *new_path = (struct parameter_list *)malloc(sizeof *new_path); *new_path = parameter_list_init(name); if (current == NULL) { - *list = new_path; - new_path->name_prev = NULL; + list->first = new_path; + new_path->prev = NULL; + list->length = 1; } else { - while (current->name_next) { - current = current->name_next; + while (current->next) { + current = current->next; } - current->name_next = new_path; - new_path->name_prev = current; + current->next = new_path; + new_path->prev = current; + list->length++; } return new_path; } -/* Delete a given parameter from list and return pointer to next element*/ -struct parameter_list *np_del_parameter(struct parameter_list *item, struct parameter_list *prev) { - if (item == NULL) { +parameter_list_elem *mp_int_fs_list_find(filesystem_list list, const char *name) { + if (list.length == 0) { return NULL; } - struct parameter_list *next; + for (parameter_list_elem *temp_list = list.first; temp_list; temp_list = temp_list->next) { + if (!strcmp(temp_list->name, name)) { + return temp_list; + } + } - if (item->name_next) { - next = item->name_next; - } else { - next = NULL; + return NULL; +} + +parameter_list_elem *mp_int_fs_list_del(filesystem_list *list, parameter_list_elem *item) { + if (list->length == 0) { + return NULL; } - if (next) { - next->name_prev = prev; + if (item == NULL) { + // Got NULL for item, interpret this as "delete first element" + // as a kind of compatibility to the old function + item = list->first; } - if (prev) { - prev->name_next = next; + if (list->first == item) { + list->length--; + + list->first = item->next; + if (list->first) { + list->first->prev = NULL; + } + return list->first; + } + + // Was not the first element, continue + parameter_list_elem *prev = list->first; + parameter_list_elem *current = list->first->next; + + while (current != item && current != NULL) { + prev = current; + current = current->next; + } + + if (current == NULL) { + // didn't find that element .... + return NULL; + } + + // remove the element + parameter_list_elem *next = current->next; + prev->next = next; + list->length--; + if (next) { + next->prev = prev; } if (item->name) { @@ -156,29 +446,23 @@ struct parameter_list *np_del_parameter(struct parameter_list *item, struct para return next; } -/* returns a pointer to the struct found in the list */ -struct parameter_list *np_find_parameter(struct parameter_list *list, const char *name) { - for (struct parameter_list *temp_list = list; temp_list; temp_list = temp_list->name_next) { - if (!strcmp(temp_list->name, name)) { - return temp_list; - } +parameter_list_elem *mp_int_fs_list_get_next(parameter_list_elem *current) { + if (!current) { + return NULL; } - - return NULL; + return current->next; } -void np_set_best_match(struct parameter_list *desired, struct mount_entry *mount_list, bool exact) { - for (struct parameter_list *d = desired; d; d = d->name_next) { - if (!d->best_match) { - struct mount_entry *mount_entry; - size_t name_len = strlen(d->name); - size_t best_match_len = 0; +void mp_int_fs_list_set_best_match(filesystem_list list, struct mount_entry *mount_list, bool exact) { + for (parameter_list_elem *elem = list.first; elem; elem = mp_int_fs_list_get_next(elem)) { + if (!elem->best_match) { + size_t name_len = strlen(elem->name); struct mount_entry *best_match = NULL; - struct fs_usage fsp; /* set best match if path name exactly matches a mounted device name */ - for (mount_entry = mount_list; mount_entry; mount_entry = mount_entry->me_next) { - if (strcmp(mount_entry->me_devname, d->name) == 0) { + for (struct mount_entry *mount_entry = mount_list; mount_entry; mount_entry = mount_entry->me_next) { + if (strcmp(mount_entry->me_devname, elem->name) == 0) { + struct fs_usage fsp; if (get_fs_usage(mount_entry->me_mountdir, mount_entry->me_devname, &fsp) >= 0) { best_match = mount_entry; } @@ -187,11 +471,15 @@ void np_set_best_match(struct parameter_list *desired, struct mount_entry *mount /* set best match by directory name if no match was found by devname */ if (!best_match) { - for (mount_entry = mount_list; mount_entry; mount_entry = mount_entry->me_next) { + size_t best_match_len = 0; + for (struct mount_entry *mount_entry = mount_list; mount_entry; mount_entry = mount_entry->me_next) { size_t len = strlen(mount_entry->me_mountdir); + if ((!exact && (best_match_len <= len && len <= name_len && - (len == 1 || strncmp(mount_entry->me_mountdir, d->name, len) == 0))) || - (exact && strcmp(mount_entry->me_mountdir, d->name) == 0)) { + (len == 1 || strncmp(mount_entry->me_mountdir, elem->name, len) == 0))) || + (exact && strcmp(mount_entry->me_mountdir, elem->name) == 0)) { + struct fs_usage fsp; + if (get_fs_usage(mount_entry->me_mountdir, mount_entry->me_devname, &fsp) >= 0) { best_match = mount_entry; best_match_len = len; @@ -201,56 +489,13 @@ void np_set_best_match(struct parameter_list *desired, struct mount_entry *mount } if (best_match) { - d->best_match = best_match; + elem->best_match = best_match; } else { - d->best_match = NULL; /* Not sure why this is needed as it should be null on initialisation */ + elem->best_match = NULL; /* Not sure why this is needed as it should be null on initialisation */ } - } - } -} -/* Returns true if name is in list */ -bool np_find_name(struct name_list *list, const char *name) { - if (list == NULL || name == NULL) { - return false; - } - for (struct name_list *n = list; n; n = n->next) { - if (!strcmp(name, n->name)) { - return true; + // No filesystem without a mount_entry! + // assert(elem->best_match != NULL); } } - return false; -} - -/* Returns true if name is in list */ -bool np_find_regmatch(struct regex_list *list, const char *name) { - if (name == NULL) { - return false; - } - - int len = strlen(name); - - for (; list; list = list->next) { - /* Emulate a full match as if surrounded with ^( )$ - by checking whether the match spans the whole name */ - regmatch_t m; - if (!regexec(&list->regex, name, 1, &m, 0) && m.rm_so == 0 && m.rm_eo == len) { - return true; - } - } - - return false; -} - -bool np_seen_name(struct name_list *list, const char *name) { - for (struct name_list *s = list; s; s = s->next) { - if (!strcmp(s->name, name)) { - return true; - } - } - return false; -} - -bool np_regex_match_mount_entry(struct mount_entry *me, regex_t *re) { - return ((regexec(re, me->me_devname, (size_t)0, NULL, 0) == 0) || (regexec(re, me->me_mountdir, (size_t)0, NULL, 0) == 0)); } diff --git a/plugins/check_disk.d/utils_disk.h b/plugins/check_disk.d/utils_disk.h index 0c69f987..a66453ea 100644 --- a/plugins/check_disk.d/utils_disk.h +++ b/plugins/check_disk.d/utils_disk.h @@ -1,14 +1,34 @@ +#pragma once /* Header file for utils_disk */ #include "../../config.h" #include "../../gl/mountlist.h" #include "../../lib/utils_base.h" +#include "../../lib/output.h" #include "regex.h" #include +typedef enum : unsigned long { + Humanized = 0, + Bytes = 1, + KibiBytes = 1024, + MebiBytes = 1024 * KibiBytes, + GibiBytes = 1024 * MebiBytes, + TebiBytes = 1024 * GibiBytes, + PebiBytes = 1024 * TebiBytes, + ExbiBytes = 1024 * PebiBytes, + KiloBytes = 1000, + MegaBytes = 1000 * KiloBytes, + GigaBytes = 1000 * MegaBytes, + TeraBytes = 1000 * GigaBytes, + PetaBytes = 1000 * TeraBytes, + ExaBytes = 1000 * PetaBytes +} byte_unit; + +typedef struct name_list string_list; struct name_list { char *name; - struct name_list *next; + string_list *next; }; struct regex_list { @@ -16,54 +36,120 @@ struct regex_list { struct regex_list *next; }; +typedef struct parameter_list parameter_list_elem; struct parameter_list { char *name; char *group; - thresholds *freespace_units; - thresholds *freespace_percent; - thresholds *usedspace_units; - thresholds *usedspace_percent; - - thresholds *usedinodes_percent; - thresholds *freeinodes_percent; + mp_thresholds freespace_units; + mp_thresholds freespace_percent; + mp_thresholds freeinodes_percent; struct mount_entry *best_match; - uintmax_t total; - uintmax_t available; - uintmax_t available_to_root; - uintmax_t used; - uintmax_t inodes_free; uintmax_t inodes_free_to_root; + uintmax_t inodes_free; uintmax_t inodes_used; uintmax_t inodes_total; - double dfree_pct; - double dused_pct; + uint64_t used_bytes; + uint64_t free_bytes; + uint64_t total_bytes; - uint64_t dused_units; - uint64_t dfree_units; - uint64_t dtotal_units; + parameter_list_elem *next; + parameter_list_elem *prev; +}; + +typedef struct { + size_t length; + parameter_list_elem *first; +} filesystem_list; - double dused_inodes_percent; - double dfree_inodes_percent; +filesystem_list filesystem_list_init(); - struct parameter_list *name_next; - struct parameter_list *name_prev; +typedef struct { + char *name; + char *filesystem_type; + bool is_group; + + mp_thresholds freespace_bytes_thresholds; + mp_thresholds freespace_percent_thresholds; + mp_thresholds freeinodes_percent_thresholds; + + uintmax_t inodes_free_to_root; + uintmax_t inodes_free; + uintmax_t inodes_used; + uintmax_t inodes_total; + + uintmax_t used_bytes; + uintmax_t free_bytes; + uintmax_t total_bytes; +} measurement_unit; + +typedef struct measurement_unit_list measurement_unit_list; +struct measurement_unit_list { + measurement_unit unit; + measurement_unit_list *next; }; +typedef struct { + // Output options + bool erronly; + bool display_mntp; + /* show only local filesystems. */ + bool show_local_fs; + /* show only local filesystems but call stat() on remote ones. */ + bool stat_remote_fs; + bool display_inodes_perfdata; + + bool exact_match; + bool freespace_ignore_reserved; + + bool ignore_missing; + bool path_ignored; + + /* Linked list of filesystem types to omit. + If the list is empty, don't exclude any types. */ + struct regex_list *fs_exclude_list; + /* Linked list of filesystem types to check. + If the list is empty, include all types. */ + struct regex_list *fs_include_list; + struct name_list *device_path_exclude_list; + filesystem_list path_select_list; + /* Linked list of mounted filesystems. */ + struct mount_entry *mount_list; + struct name_list *seen; + + byte_unit display_unit; + // byte_unit unit; + + bool output_format_is_set; + mp_output_format output_format; +} check_disk_config; + void np_add_name(struct name_list **list, const char *name); bool np_find_name(struct name_list *list, const char *name); bool np_seen_name(struct name_list *list, const char *name); int np_add_regex(struct regex_list **list, const char *regex, int cflags); bool np_find_regmatch(struct regex_list *list, const char *name); -struct parameter_list *np_add_parameter(struct parameter_list **list, const char *name); -struct parameter_list *np_find_parameter(struct parameter_list *list, const char *name); -struct parameter_list *np_del_parameter(struct parameter_list *item, struct parameter_list *prev); -struct parameter_list parameter_list_init(const char *); +parameter_list_elem parameter_list_init(const char *); + +parameter_list_elem *mp_int_fs_list_append(filesystem_list *list, const char *name); +parameter_list_elem *mp_int_fs_list_find(filesystem_list list, const char *name); +parameter_list_elem *mp_int_fs_list_del(filesystem_list *list, parameter_list_elem *item); +parameter_list_elem *mp_int_fs_list_get_next(parameter_list_elem *current); +void mp_int_fs_list_set_best_match(filesystem_list list, struct mount_entry *mount_list, bool exact); -int search_parameter_list(struct parameter_list *list, const char *name); -void np_set_best_match(struct parameter_list *desired, struct mount_entry *mount_list, bool exact); +measurement_unit measurement_unit_init(); +measurement_unit_list *add_measurement_list(measurement_unit_list *list, measurement_unit elem); +measurement_unit add_filesystem_to_measurement_unit(measurement_unit unit, parameter_list_elem filesystem); +measurement_unit create_measurement_unit_from_filesystem(parameter_list_elem filesystem, bool display_mntp); + +int search_parameter_list(parameter_list_elem *list, const char *name); bool np_regex_match_mount_entry(struct mount_entry *, regex_t *); + +char *get_unit_string(byte_unit); +check_disk_config check_disk_config_init(); + +char *humanize_byte_value(uintmax_t value, bool use_si_units); -- cgit v1.2.3-74-g34f1 From 76971dea753d52d3e177aa84605d9b239a3a793e Mon Sep 17 00:00:00 2001 From: Lorenz Kästle <12514511+RincewindsHat@users.noreply.github.com> Date: Sun, 30 Mar 2025 22:38:12 +0200 Subject: Address check_disk changes in tests --- plugins/t/check_disk.t | 205 +++++++++++++++++++++++----------------- plugins/tests/test_check_disk.c | 67 ++++++------- 2 files changed, 154 insertions(+), 118 deletions(-) (limited to 'plugins') diff --git a/plugins/t/check_disk.t b/plugins/t/check_disk.t index 9eb77ce4..16daee9a 100644 --- a/plugins/t/check_disk.t +++ b/plugins/t/check_disk.t @@ -10,6 +10,7 @@ use strict; use Test::More; use NPTest; use POSIX qw(ceil floor); +use Data::Dumper; my $successOutput = '/^DISK OK/'; my $failureOutput = '/^DISK CRITICAL/'; @@ -20,117 +21,148 @@ my $result; my $mountpoint_valid = getTestParameter( "NP_MOUNTPOINT_VALID", "Path to valid mountpoint", "/"); my $mountpoint2_valid = getTestParameter( "NP_MOUNTPOINT2_VALID", "Path to another valid mountpoint. Must be different from 1st one", "/var"); +my $output_format = "--output-format mp-test-json"; + if ($mountpoint_valid eq "" or $mountpoint2_valid eq "") { plan skip_all => "Need 2 mountpoints to test"; } else { - plan tests => 94; + plan tests => 96; } $result = NPTest->testCmd( - "./check_disk -w 1% -c 1% -p $mountpoint_valid -w 1% -c 1% -p $mountpoint2_valid" + "./check_disk -w 1% -c 1% -p $mountpoint_valid -w 1% -c 1% -P -p $mountpoint2_valid $output_format" ); cmp_ok( $result->return_code, "==", 0, "Checking two mountpoints (must have at least 1% free in space and inodes)"); -my $c = 0; -$_ = $result->output; -$c++ while /\(/g; # counts number of "(" - should be two -cmp_ok( $c, '==', 2, "Got two mountpoints in output"); +like($result->{'mp_test_result'}->{'state'}, "/OK/", "Main result is OK"); +like($result->{'mp_test_result'}->{'checks'}->[0]->{'state'}, "/OK/", "First sub result is OK"); +like($result->{'mp_test_result'}->{'checks'}->[1]->{'state'}, "/OK/", "Second sub result is OK"); + +my $absolut_space_mp1 = $result->{'mp_test_result'}->{'checks'}->[1]->{'checks'}->[0]->{'perfdata'}->[0]->{'max'}->{'value'}; +# print("absolut space on mp1: ". $absolut_space_mp1 . "\n"); + +my $free_percent_on_mp1 = ($result->{'mp_test_result'}->{'checks'}->[1]->{'checks'}->[0]->{'perfdata'}->[0]->{'value'}->{'value'} / ($absolut_space_mp1/100)); +print("free percent on mp1: ". $free_percent_on_mp1 . "\n"); + +my $absolut_space_mp2 = $result->{'mp_test_result'}->{'checks'}->[0]->{'checks'}->[0]->{'perfdata'}->[0]->{'max'}->{'value'}; +# print("absolut space on mp2: ". $absolut_space_mp2 . "\n"); -# Get perf data -# Should use Monitoring::Plugin -my @perf_data = sort(split(/ /, $result->perf_output)); +my $free_percent_on_mp2 = ($result->{'mp_test_result'}->{'checks'}->[0]->{'checks'}->[0]->{'perfdata'}->[0]->{'value'}->{'value'}/ ($absolut_space_mp2/100)); +print("free percent on mp2: ". $free_percent_on_mp2 . "\n"); +my @perfdata; +@perfdata[0] = $result->{'mp_test_result'}->{'checks'}->[0]->{'checks'}->[0]->{'perfdata'}->[0]; +@perfdata[1] = $result->{'mp_test_result'}->{'checks'}->[1]->{'checks'}->[0]->{'perfdata'}->[0]; # Calculate avg_free free on mountpoint1 and mountpoint2 # because if you check in the middle, you should get different errors -$_ = $result->output; -my ($free_on_mp1, $free_on_mp2) = (m/\((\d+\.\d+)%.*\((\d+\.\d+)%/); -die "Cannot parse output: $_" unless ($free_on_mp1 && $free_on_mp2); -my $avg_free = ceil(($free_on_mp1+$free_on_mp2)/2); +my $avg_free_percent = ceil(($free_percent_on_mp1+$free_percent_on_mp2)/2); +# print("avg_free: " . $avg_free_percent . "\n"); my ($more_free, $less_free); -if ($free_on_mp1 > $free_on_mp2) { +if ($free_percent_on_mp1 > $free_percent_on_mp2) { $more_free = $mountpoint_valid; $less_free = $mountpoint2_valid; -} elsif ($free_on_mp1 < $free_on_mp2) { +} elsif ($free_percent_on_mp1 < $free_percent_on_mp2) { $more_free = $mountpoint2_valid; $less_free = $mountpoint_valid; } else { die "Two mountpoints are the same - cannot do rest of test"; } -if($free_on_mp1 == $avg_free || $free_on_mp2 == $avg_free) { + +print("less free: " . $less_free . "\n"); +print("more free: " . $more_free . "\n"); + +if($free_percent_on_mp1 == $avg_free_percent || $free_percent_on_mp2 == $avg_free_percent) { die "One mountpoints has average space free - cannot do rest of test"; } +my $free_inodes_on_mp1 = $result->{'mp_test_result'}->{'checks'}->[1]->{'checks'}[2]->{'perfdata'}->[0]->{'value'}->{'value'}; +my $total_inodes_on_mp1 = $result->{'mp_test_result'}->{'checks'}->[1]->{'checks'}[2]->{'perfdata'}->[0]->{'max'}->{'value'}; +my $free_inode_percentage_on_mp1 = $free_inodes_on_mp1 / ($total_inodes_on_mp1 / 100); -# Do same for inodes -$_ = $result->output; -my ($free_inode_on_mp1, $free_inode_on_mp2) = (m/inode=(\d+)%.*inode=(\d+)%/); -die "Cannot parse free inodes: $_" unless ($free_inode_on_mp1 && $free_inode_on_mp2); -my $avg_inode_free = ceil(($free_inode_on_mp1 + $free_inode_on_mp2)/2); +my $free_inodes_on_mp2 = $result->{'mp_test_result'}->{'checks'}->[0]->{'checks'}[2]->{'perfdata'}->[0]->{'value'}->{'value'}; +my $total_inodes_on_mp2 = $result->{'mp_test_result'}->{'checks'}->[0]->{'checks'}[2]->{'perfdata'}->[0]->{'max'}->{'value'}; +my $free_inode_percentage_on_mp2 = $free_inodes_on_mp2 / ($total_inodes_on_mp2 / 100); + +my $avg_inode_free_percentage = ceil(($free_inode_percentage_on_mp1 + $free_inode_percentage_on_mp2)/2); my ($more_inode_free, $less_inode_free); -if ($free_inode_on_mp1 > $free_inode_on_mp2) { +if ($free_inode_percentage_on_mp1 > $free_inode_percentage_on_mp2) { $more_inode_free = $mountpoint_valid; $less_inode_free = $mountpoint2_valid; -} elsif ($free_inode_on_mp1 < $free_inode_on_mp2) { +} elsif ($free_inode_percentage_on_mp1 < $free_inode_percentage_on_mp2) { $more_inode_free = $mountpoint2_valid; $less_inode_free = $mountpoint_valid; } else { die "Two mountpoints with same inodes free - cannot do rest of test"; } -if($free_inode_on_mp1 == $avg_inode_free || $free_inode_on_mp2 == $avg_inode_free) { +if($free_inode_percentage_on_mp1 == $avg_inode_free_percentage || $free_inode_percentage_on_mp2 == $avg_inode_free_percentage) { die "One mountpoints has average inodes free - cannot do rest of test"; } # Verify performance data # First check absolute thresholds... $result = NPTest->testCmd( - "./check_disk -w 20 -c 10 -p $mountpoint_valid" + "./check_disk -w 20 -c 10 -p $mountpoint_valid $output_format" ); -$_ = $result->perf_output; -my ($warn_absth_data, $crit_absth_data, $total_absth_data) = (m/=.[^;]*;(\d+);(\d+);\d+;(\d+)/); -# default unit is MiB, but perfdata is always bytes -is ($warn_absth_data, $total_absth_data - (20 * (2 ** 20)), "Wrong warning in perf data using absolute thresholds"); -is ($crit_absth_data, $total_absth_data - (10 * (2 ** 20)), "Wrong critical in perf data using absolute thresholds"); + +cmp_ok( $result->return_code, "==", 0, "with JSON test format result should always be OK"); + +my $warn_absth_data = $result->{'mp_test_result'}->{'checks'}->[0]->{'checks'}[0]->{'perfdata'}->[0]->{'warn'}->{'end'}->{'value'}; +my $crit_absth_data = $result->{'mp_test_result'}->{'checks'}->[0]->{'checks'}[0]->{'perfdata'}->[0]->{'crit'}->{'end'}->{'value'}; +my $total_absth_data= $result->{'mp_test_result'}->{'checks'}->[0]->{'checks'}[0]->{'perfdata'}->[0]->{'max'}->{'value'}; + +# print("warn: " .$warn_absth_data . "\n"); +# print("crit: " .$crit_absth_data . "\n"); +# print("total: " .$total_absth_data . "\n"); + +is ($warn_absth_data <=> (20 * (2 ** 20)), 0, "Wrong warning in perf data using absolute thresholds"); +is ($crit_absth_data <=> (10 * (2 ** 20)), 0, "Wrong critical in perf data using absolute thresholds"); # Then check percent thresholds. $result = NPTest->testCmd( - "./check_disk -w 20% -c 10% -p $mountpoint_valid" + "./check_disk -w 20% -c 10% -p $mountpoint_valid $output_format" ); -$_ = $result->perf_output; -my ($warn_percth_data, $crit_percth_data, $total_percth_data) = (m/=.[^;]*;(\d+);(\d+);\d+;(\d+)/); -is ($warn_percth_data, int((1-20/100)*$total_percth_data), "Wrong warning in perf data using percent thresholds"); -is ($crit_percth_data, int((1-10/100)*$total_percth_data), "Wrong critical in perf data using percent thresholds"); + +cmp_ok( $result->return_code, "==", 0, "with JSON test format result should always be OK"); + +my $warn_percth_data = $result->{'mp_test_result'}->{'checks'}->[0]->{'checks'}[0]->{'perfdata'}->[0]->{'warn'}->{'end'}->{'value'}; +my $crit_percth_data = $result->{'mp_test_result'}->{'checks'}->[0]->{'checks'}[0]->{'perfdata'}->[0]->{'crit'}->{'end'}->{'value'}; +my $total_percth_data = $result->{'mp_test_result'}->{'checks'}->[0]->{'checks'}[0]->{'perfdata'}->[0]->{'max'}->{'value'}; + +is ($warn_percth_data <=> int((20/100)*$total_percth_data), 0, "Wrong warning in perf data using percent thresholds"); +is ($crit_percth_data <=> int((10/100)*$total_percth_data), 0, "Wrong critical in perf data using percent thresholds"); # Check when order of mount points are reversed, that perf data remains same $result = NPTest->testCmd( - "./check_disk -w 1% -c 1% -p $mountpoint2_valid -w 1% -c 1% -p $mountpoint_valid" + "./check_disk -w 1% -c 1% -p $mountpoint2_valid -w 1% -c 1% -p $mountpoint_valid $output_format" ); -@_ = sort(split(/ /, $result->perf_output)); -is_deeply( \@perf_data, \@_, "perf data for both filesystems same when reversed"); +cmp_ok( $result->return_code, "==", 0, "with JSON test format result should always be OK"); +# write comparison set for perfdata here, but in reversed order, maybe there is a smarter way +my @perfdata2; +@perfdata2[1] = $result->{'mp_test_result'}->{'checks'}->[0]->{'checks'}->[0]->{'perfdata'}->[0]; +@perfdata2[0] = $result->{'mp_test_result'}->{'checks'}->[1]->{'checks'}->[0]->{'perfdata'}->[0]; +is_deeply(\@perfdata, \@perfdata2, "perf data for both filesystems same when reversed"); # Basic filesystem checks for sizes -$result = NPTest->testCmd( "./check_disk -w 1 -c 1 -p $more_free" ); -cmp_ok( $result->return_code, '==', 0, "At least 1 MB available on $more_free"); -like ( $result->output, $successOutput, "OK output" ); -like ( $result->only_output, qr/free space/, "Have free space text"); -like ( $result->only_output, qr/$more_free/, "Have disk name in text"); +$result = NPTest->testCmd( "./check_disk -w 1 -c 1 -p $more_free $output_format"); +cmp_ok( $result->return_code, "==", 0, "with JSON test format result should always be OK"); +like($result->{'mp_test_result'}->{'state'}, "/OK/", "At least 1 MB available on $more_free"); -$result = NPTest->testCmd( "./check_disk -w 1 -c 1 -p $more_free -p $less_free" ); -cmp_ok( $result->return_code, '==', 0, "At least 1 MB available on $more_free and $less_free"); +$result = NPTest->testCmd( "./check_disk -w 1 -c 1 -p $more_free -p $less_free $output_format" ); +cmp_ok( $result->return_code, "==", 0, "with JSON test format result should always be OK"); +like($result->{'mp_test_result'}->{'state'}, "/OK/", "At least 1 MB available on $more_free and $less_free"); -$_ = $result->output; - -my ($free_mb_on_mp1, $free_mb_on_mp2) = (m/(\d+)MiB .* (\d+)MiB /g); +my $free_mb_on_mp1 =$result->{'mp_test_result'}->{'checks'}->[0]->{'checks'}->[0]->{'perfdata'}->[0]->{'value'}->{'value'} / (1024 * 1024); +my $free_mb_on_mp2 = $result->{'mp_test_result'}->{'checks'}->[1]->{'checks'}->[0]->{'perfdata'}->[0]->{'value'}->{'value'}/ (1024 * 1024); die "Cannot parse output: $_" unless ($free_mb_on_mp1 && $free_mb_on_mp2); my $free_mb_on_all = $free_mb_on_mp1 + $free_mb_on_mp2; - -$result = NPTest->testCmd( "./check_disk -e -w 1 -c 1 -p $more_free" ); -is( $result->only_output, "DISK OK", "No print out of disks with -e for OKs"); +$result = NPTest->testCmd( "./check_disk -e -w 1 -c 1 -p $more_free $output_format" ); +cmp_ok( $result->return_code, "==", 0, "with JSON test format result should always be OK"); $result = NPTest->testCmd( "./check_disk 100 100 $more_free" ); cmp_ok( $result->return_code, '==', 0, "Old syntax okay" ); @@ -139,54 +171,55 @@ $result = NPTest->testCmd( "./check_disk -w 1% -c 1% -p $more_free" ); cmp_ok( $result->return_code, "==", 0, "At least 1% free" ); $result = NPTest->testCmd( - "./check_disk -w 1% -c 1% -p $more_free -w 100% -c 100% -p $less_free" + "./check_disk -w 1% -c 1% -p $more_free -w 100% -c 100% -p $less_free $output_format" ); -cmp_ok( $result->return_code, "==", 2, "Get critical on less_free mountpoint $less_free" ); -like( $result->output, $failureOutput, "Right output" ); +cmp_ok( $result->return_code, "==", 0, "with JSON test format result should always be OK"); +like($result->{'mp_test_result'}->{'state'}, "/CRITICAL/", "Get critical on less_free mountpoint $less_free"); $result = NPTest->testCmd( - "./check_disk -w $avg_free% -c 0% -p $less_free" + "./check_disk -w $avg_free_percent% -c 0% -p $less_free $output_format" ); -cmp_ok( $result->return_code, '==', 1, "Get warning on less_free mountpoint, when checking avg_free"); +cmp_ok( $result->return_code, "==", 0, "with JSON test format result should always be OK"); +like($result->{'mp_test_result'}->{'state'}, "/WARNING/", "Get warning on less_free mountpoint, when checking avg_free"); $result = NPTest->testCmd( - "./check_disk -w $avg_free% -c $avg_free% -p $more_free" + "./check_disk -w $avg_free_percent% -c $avg_free_percent% -p $more_free" ); cmp_ok( $result->return_code, '==', 0, "Get ok on more_free mountpoint, when checking avg_free"); $result = NPTest->testCmd( - "./check_disk -w $avg_free% -c 0% -p $less_free -w $avg_free% -c $avg_free% -p $more_free" + "./check_disk -w $avg_free_percent% -c 0% -p $less_free -w $avg_free_percent% -c $avg_free_percent% -p $more_free" ); cmp_ok( $result->return_code, "==", 1, "Combining above two tests, get warning"); my $all_disks = $result->output; $result = NPTest->testCmd( - "./check_disk -e -w $avg_free% -c 0% -p $less_free -w $avg_free% -c $avg_free% -p $more_free" + "./check_disk -e -w $avg_free_percent% -c 0% -p $less_free -w $avg_free_percent% -c $avg_free_percent% -p $more_free" ); isnt( $result->output, $all_disks, "-e gives different output"); # Need spaces around filesystem name in case less_free and more_free are nested like( $result->output, qr/ $less_free /, "Found problem $less_free"); unlike( $result->only_output, qr/ $more_free /, "Has ignored $more_free as not a problem"); -like( $result->perf_output, qr/ $more_free=/, "But $more_free is still in perf data"); +like( $result->perf_output, qr/'$more_free'=/, "But $more_free is still in perf data"); $result = NPTest->testCmd( - "./check_disk -w $avg_free% -c 0% -p $more_free" + "./check_disk -w $avg_free_percent% -c 0% -p $more_free" ); cmp_ok( $result->return_code, '==', 0, "Get ok on more_free mountpoint, checking avg_free"); $result = NPTest->testCmd( - "./check_disk -w $avg_free% -c $avg_free% -p $less_free" + "./check_disk -w $avg_free_percent% -c $avg_free_percent% -p $less_free" ); cmp_ok( $result->return_code, '==', 2, "Get critical on less_free, checking avg_free"); $result = NPTest->testCmd( - "./check_disk -w $avg_free% -c 0% -p $more_free -w $avg_free% -c $avg_free% -p $less_free" + "./check_disk -w $avg_free_percent% -c 0% -p $more_free -w $avg_free_percent% -c $avg_free_percent% -p $less_free" ); cmp_ok( $result->return_code, '==', 2, "Combining above two tests, get critical"); $result = NPTest->testCmd( - "./check_disk -w $avg_free% -c $avg_free% -p $less_free -w $avg_free% -c 0% -p $more_free" + "./check_disk -w $avg_free_percent% -c $avg_free_percent% -p $less_free -w $avg_free_percent% -c 0% -p $more_free" ); cmp_ok( $result->return_code, '==', 2, "And reversing arguments should not make a difference"); @@ -203,32 +236,32 @@ is( $result->return_code, 2, "Critical requesting 100% free inodes for both moun $result = NPTest->testCmd( "./check_disk --iwarning 1% --icritical 1% -p $more_inode_free -K 100% -W 100% -p $less_inode_free" ); is( $result->return_code, 2, "Get critical on less_inode_free mountpoint $less_inode_free"); -$result = NPTest->testCmd( "./check_disk -W $avg_inode_free% -K 0% -p $less_inode_free" ); +$result = NPTest->testCmd( "./check_disk -W $avg_inode_free_percentage% -K 0% -p $less_inode_free" ); is( $result->return_code, 1, "Get warning on less_inode_free, when checking average"); -$result = NPTest->testCmd( "./check_disk -W $avg_inode_free% -K $avg_inode_free% -p $more_inode_free "); +$result = NPTest->testCmd( "./check_disk -W $avg_inode_free_percentage% -K $avg_inode_free_percentage% -p $more_inode_free "); is( $result->return_code, 0, "Get ok on more_inode_free when checking average"); -$result = NPTest->testCmd( "./check_disk -W $avg_inode_free% -K 0% -p $less_inode_free -W $avg_inode_free% -K $avg_inode_free% -p $more_inode_free" ); +$result = NPTest->testCmd( "./check_disk -W $avg_inode_free_percentage% -K 0% -p $less_inode_free -W $avg_inode_free_percentage% -K $avg_inode_free_percentage% -p $more_inode_free" ); is ($result->return_code, 1, "Combine above two tests, get warning"); $all_disks = $result->output; -$result = NPTest->testCmd( "./check_disk -e -W $avg_inode_free% -K 0% -p $less_inode_free -W $avg_inode_free% -K $avg_inode_free% -p $more_inode_free" ); +$result = NPTest->testCmd( "./check_disk -e -W $avg_inode_free_percentage% -K 0% -p $less_inode_free -W $avg_inode_free_percentage% -K $avg_inode_free_percentage% -p $more_inode_free" ); isnt( $result->output, $all_disks, "-e gives different output"); like( $result->output, qr/$less_inode_free/, "Found problem $less_inode_free"); unlike( $result->only_output, qr/$more_inode_free\s/, "Has ignored $more_inode_free as not a problem"); like( $result->perf_output, qr/$more_inode_free/, "But $more_inode_free is still in perf data"); -$result = NPTest->testCmd( "./check_disk -W $avg_inode_free% -K 0% -p $more_inode_free" ); +$result = NPTest->testCmd( "./check_disk -W $avg_inode_free_percentage% -K 0% -p $more_inode_free" ); is( $result->return_code, 0, "Get ok on more_inode_free mountpoint, checking average"); -$result = NPTest->testCmd( "./check_disk -W $avg_inode_free% -K $avg_inode_free% -p $less_inode_free" ); +$result = NPTest->testCmd( "./check_disk -W $avg_inode_free_percentage% -K $avg_inode_free_percentage% -p $less_inode_free" ); is( $result->return_code, 2, "Get critical on less_inode_free, checking average"); -$result = NPTest->testCmd( "./check_disk -W $avg_inode_free% -K 0% -p $more_inode_free -W $avg_inode_free% -K $avg_inode_free% -p $less_inode_free" ); +$result = NPTest->testCmd( "./check_disk -W $avg_inode_free_percentage% -K 0% -p $more_inode_free -W $avg_inode_free_percentage% -K $avg_inode_free_percentage% -p $less_inode_free" ); is( $result->return_code, 2, "Combining above two tests, get critical"); -$result = NPTest->testCmd( "./check_disk -W $avg_inode_free% -K $avg_inode_free% -p $less_inode_free -W $avg_inode_free% -K 0% -p $more_inode_free" ); +$result = NPTest->testCmd( "./check_disk -W $avg_inode_free_percentage% -K $avg_inode_free_percentage% -p $less_inode_free -W $avg_inode_free_percentage% -K 0% -p $more_inode_free" ); cmp_ok( $result->return_code, '==', 2, "And reversing arguments should not make a difference"); @@ -249,9 +282,9 @@ $result = NPTest->testCmd( ); cmp_ok( $result->return_code, "==", 3, "Invalid options: -p must come after thresholds" ); -$result = NPTest->testCmd( "./check_disk -w 100% -c 100% ".${mountpoint_valid} ); # 100% empty -cmp_ok( $result->return_code, "==", 2, "100% empty" ); -like( $result->output, $failureOutput, "Right output" ); +$result = NPTest->testCmd( "./check_disk -w 100% -c 100% $output_format ".${mountpoint_valid} ); # 100% empty +cmp_ok( $result->return_code, "==", 0, "100% empty" ); +like($result->{'mp_test_result'}->{'state'}, "/CRITICAL/", "100% empty"); $result = NPTest->testCmd( "./check_disk -w 100000000 -c 100000000 $mountpoint_valid" ); cmp_ok( $result->return_code, '==', 2, "Check for 100TB free" ); @@ -263,7 +296,8 @@ cmp_ok( $result->return_code, "==", 2, "100 TB empty" ); # Checking old syntax of check_disk warn crit [fs], with warn/crit at USED% thresholds $result = NPTest->testCmd( "./check_disk 0 0 ".${mountpoint_valid} ); cmp_ok( $result->return_code, "==", 2, "Old syntax: 0% used"); -like ( $result->only_output, qr(^[^;]*;[^;]*$), "Select only one path with positional arguments"); +# like ( $result->only_output, qr(^[^;]*;[^;]*$), "Select only one path with positional arguments"); +# TODO not sure what the above should test, taking it out $result = NPTest->testCmd( "./check_disk 100 100 $mountpoint_valid" ); cmp_ok( $result->return_code, '==', 0, "Old syntax: 100% used" ); @@ -311,8 +345,9 @@ $result = NPTest->testCmd( "./check_disk -w 0% -c 0% -p / -p /" ); unlike( $result->output, '/ \/ .* \/ /', "Should not show same filesystem twice"); # are partitions added if -C is given without path selection -p ? -$result = NPTest->testCmd( "./check_disk -w 0% -c 0% -C -w 0% -c 0% -p $mountpoint_valid" ); -like( $result->output, '/;.*;\|/', "-C selects partitions if -p is not given"); +$result = NPTest->testCmd( "./check_disk -w 0% -c 0% -C -w 0% -c 0% -p $mountpoint_valid $output_format" ); +cmp_ok( $result->return_code, "==", 0, "with JSON test format result should always be OK"); +cmp_ok(scalar $result->{'mp_test_result'}->{'checks'}, '>', 1, "-C invokes matchall logic again"); # grouping: exit crit if the sum of free megs on mp1+mp2 is less than warn/crit $result = NPTest->testCmd( "./check_disk -w ". ($free_mb_on_all + 1) ." -c ". ($free_mb_on_all + 1) ." -g group -p $mountpoint_valid -p $mountpoint2_valid" ); @@ -359,39 +394,37 @@ like( $result->output, qr/$mountpoint2_valid/,"ignore: output data does have $mo # ignore-missing: exit okay, when fs is not accessible $result = NPTest->testCmd( "./check_disk --ignore-missing -w 0% -c 0% -p /bob"); cmp_ok( $result->return_code, '==', 0, "ignore-missing: return okay for not existing filesystem /bob"); -like( $result->output, '/^DISK OK - No disks were found for provided parameters - ignored paths: /bob;.*$/', 'Output OK'); +like( $result->output, '/No filesystems were found for the provided parameters.*$/', 'Output OK'); # ignore-missing: exit okay, when regex does not match $result = NPTest->testCmd( "./check_disk --ignore-missing -w 0% -c 0% -r /bob"); cmp_ok( $result->return_code, '==', 0, "ignore-missing: return okay for regular expression not matching"); -like( $result->output, '/^DISK OK - No disks were found for provided parameters.*$/', 'Output OK'); +like( $result->output, '/No filesystems were found for the provided parameters.*$/', 'Output OK'); # ignore-missing: exit okay, when fs with exact match (-E) is not found $result = NPTest->testCmd( "./check_disk --ignore-missing -w 0% -c 0% -E -p /etc"); cmp_ok( $result->return_code, '==', 0, "ignore-missing: return okay when exact match does not find fs"); -like( $result->output, '/^DISK OK - No disks were found for provided parameters - ignored paths: /etc;.*$/', 'Output OK'); +like( $result->output, '/No filesystems were found for the provided parameters.*$/', 'Output OK'); # ignore-missing: exit okay, when checking one existing fs and one non-existing fs (regex) $result = NPTest->testCmd( "./check_disk --ignore-missing -w 0% -c 0% -r '/bob' -r '^/\$'"); cmp_ok( $result->return_code, '==', 0, "ignore-missing: return okay for regular expression not matching"); -like( $result->output, '/^DISK OK - free space: \/ .*$/', 'Output OK'); # ignore-missing: exit okay, when checking one existing fs and one non-existing fs (path) $result = NPTest->testCmd( "./check_disk --ignore-missing -w 0% -c 0% -p '/bob' -p '/'"); cmp_ok( $result->return_code, '==', 0, "ignore-missing: return okay for regular expression not matching"); -like( $result->output, '/^DISK OK - free space: / .*; - ignored paths: /bob;.*$/', 'Output OK'); +# like( $result->output, '/^DISK OK - free space: / .*; - ignored paths: /bob;.*$/', 'Output OK'); # ignore-missing: exit okay, when checking one non-existing fs (path) and one ignored $result = NPTest->testCmd( "./check_disk -n -w 0% -c 0% -r /dummy -i /dummy2"); cmp_ok( $result->return_code, '==', 0, "ignore-missing: return okay for regular expression not matching"); -like( $result->output, '/^DISK OK - No disks were found for provided parameters\|$/', 'Output OK'); +like( $result->output, '/No filesystems were found for the provided parameters.*$/', 'Output OK'); # ignore-missing: exit okay, when regex match does not find anything $result = NPTest->testCmd( "./check_disk -n -e -l -w 10% -c 5% -W 10% -K 5% -r /dummy"); cmp_ok( $result->return_code, '==', 0, "ignore-missing: return okay for regular expression not matching"); -like( $result->output, '/^DISK OK\|$/', 'Output OK'); # ignore-missing: exit okay, when regex match does not find anything $result = NPTest->testCmd( "./check_disk -n -l -w 10% -c 5% -W 10% -K 5% -r /dummy"); cmp_ok( $result->return_code, '==', 0, "ignore-missing: return okay for regular expression not matching"); -like( $result->output, '/^DISK OK - No disks were found for provided parameters\|$/', 'Output OK'); +like( $result->output, '/No filesystems were found for the provided parameters.*$/', 'Output OK'); diff --git a/plugins/tests/test_check_disk.c b/plugins/tests/test_check_disk.c index 963a9413..35c57bce 100644 --- a/plugins/tests/test_check_disk.c +++ b/plugins/tests/test_check_disk.c @@ -24,7 +24,7 @@ void np_test_mount_entry_regex(struct mount_entry *dummy_mount_list, char *regstr, int cflags, int expect, char *desc); int main(int argc, char **argv) { - plan_tests(33); + plan_tests(35); struct name_list *exclude_filesystem = NULL; ok(np_find_name(exclude_filesystem, "/var/log") == false, "/var/log not in list"); @@ -81,15 +81,16 @@ int main(int argc, char **argv) { np_test_mount_entry_regex(dummy_mount_list, strdup("(/home)|(/var)"), cflags, 2, strdup("grouped regex pathname match:")); np_test_mount_entry_regex(dummy_mount_list, strdup("(/homE)|(/Var)"), cflags | REG_ICASE, 2, strdup("grouped regi pathname match:")); - struct parameter_list *paths = NULL; - np_add_parameter(&paths, "/home/groups"); - np_add_parameter(&paths, "/var"); - np_add_parameter(&paths, "/tmp"); - np_add_parameter(&paths, "/home/tonvoon"); - np_add_parameter(&paths, "/dev/c2t0d0s0"); + filesystem_list test_paths = filesystem_list_init(); + mp_int_fs_list_append(&test_paths, "/home/groups"); + mp_int_fs_list_append(&test_paths, "/var"); + mp_int_fs_list_append(&test_paths, "/tmp"); + mp_int_fs_list_append(&test_paths, "/home/tonvoon"); + mp_int_fs_list_append(&test_paths, "/dev/c2t0d0s0"); + ok(test_paths.length == 5, "List counter works correctly with appends"); - np_set_best_match(paths, dummy_mount_list, false); - for (struct parameter_list *p = paths; p; p = p->name_next) { + mp_int_fs_list_set_best_match(test_paths, dummy_mount_list, false); + for (parameter_list_elem *p = test_paths.first; p; p = mp_int_fs_list_get_next(p)) { struct mount_entry *temp_me; temp_me = p->best_match; if (!strcmp(p->name, "/home/groups")) { @@ -105,15 +106,19 @@ int main(int argc, char **argv) { } } - paths = NULL; /* Bad boy - should free, but this is a test suite */ - np_add_parameter(&paths, "/home/groups"); - np_add_parameter(&paths, "/var"); - np_add_parameter(&paths, "/tmp"); - np_add_parameter(&paths, "/home/tonvoon"); - np_add_parameter(&paths, "/home"); + for (parameter_list_elem *p = test_paths.first; p; p = mp_int_fs_list_get_next(p)) { + mp_int_fs_list_del(&test_paths, p); + } + ok(test_paths.length == 0, "List delete sets counter properly"); + + mp_int_fs_list_append(&test_paths, "/home/groups"); + mp_int_fs_list_append(&test_paths, "/var"); + mp_int_fs_list_append(&test_paths, "/tmp"); + mp_int_fs_list_append(&test_paths, "/home/tonvoon"); + mp_int_fs_list_append(&test_paths, "/home"); - np_set_best_match(paths, dummy_mount_list, true); - for (struct parameter_list *p = paths; p; p = p->name_next) { + mp_int_fs_list_set_best_match(test_paths, dummy_mount_list, true); + for (parameter_list_elem *p = test_paths.first; p; p = mp_int_fs_list_get_next(p)) { if (!strcmp(p->name, "/home/groups")) { ok(!p->best_match, "/home/groups correctly not found"); } else if (!strcmp(p->name, "/var")) { @@ -129,8 +134,8 @@ int main(int argc, char **argv) { bool found = false; /* test deleting first element in paths */ - paths = np_del_parameter(paths, NULL); - for (struct parameter_list *p = paths; p; p = p->name_next) { + mp_int_fs_list_del(&test_paths, NULL); + for (parameter_list_elem *p = test_paths.first; p; p = mp_int_fs_list_get_next(p)) { if (!strcmp(p->name, "/home/groups")) { found = true; } @@ -138,23 +143,21 @@ int main(int argc, char **argv) { ok(!found, "first element successfully deleted"); found = false; - struct parameter_list *prev = NULL; - struct parameter_list *p = paths; - while (p) { - if (!strcmp(p->name, "/tmp")) { - p = np_del_parameter(p, prev); - } else { - prev = p; - p = p->name_next; + parameter_list_elem *prev = NULL; + parameter_list_elem *p = NULL; + for (parameter_list_elem *path = test_paths.first; path; path = mp_int_fs_list_get_next(path)) { + if (!strcmp(path->name, "/tmp")) { + mp_int_fs_list_del(&test_paths, path); } + p = path; } - struct parameter_list *last = NULL; - for (struct parameter_list *path = paths; path; path = path->name_next) { + parameter_list_elem *last = NULL; + for (parameter_list_elem *path = test_paths.first; path; path = mp_int_fs_list_get_next(path)) { if (!strcmp(path->name, "/tmp")) { found = true; } - if (path->name_next) { + if (path->next) { prev = path; } else { last = path; @@ -163,8 +166,8 @@ int main(int argc, char **argv) { ok(!found, "/tmp element successfully deleted"); int count = 0; - p = np_del_parameter(last, prev); - for (p = paths; p; p = p->name_next) { + mp_int_fs_list_del(&test_paths, p); + for (p = test_paths.first; p; p = p->next) { if (!strcmp(p->name, "/home")) { found = true; } -- cgit v1.2.3-74-g34f1 From c4fd34ed7966a197e596f3e766f58423fe9c5ddc Mon Sep 17 00:00:00 2001 From: Lorenz Kästle <12514511+RincewindsHat@users.noreply.github.com> Date: Sun, 30 Mar 2025 22:46:09 +0200 Subject: Codespell fixes --- plugins/check_disk.c | 6 +++--- plugins/t/check_disk.t | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) (limited to 'plugins') diff --git a/plugins/check_disk.c b/plugins/check_disk.c index 3cab816d..ddb9ee49 100644 --- a/plugins/check_disk.c +++ b/plugins/check_disk.c @@ -288,7 +288,7 @@ int main(int argc, char **argv) { unit.name = strdup(filesystem->group); measurements = current = add_measurement_list(NULL, unit); } else { - // if this is the first element of a group, the name of the previos entry is different + // if this is the first element of a group, the name of the previous entry is different if (strcmp(filesystem->group, current->unit.name) != 0) { // so, this must be the first element of a group measurement_unit unit = create_measurement_unit_from_filesystem(*filesystem, config.display_mntp); @@ -310,7 +310,7 @@ int main(int argc, char **argv) { mp_add_subcheck_to_check(&overall, unit_sc); } } else { - // Aparently no machting fs found + // Apparently no machting fs found mp_subcheck none_sc = mp_subcheck_init(); xasprintf(&none_sc.output, "No filesystems were found for the provided parameters"); @@ -833,7 +833,7 @@ check_disk_config_wrapper process_arguments(int argc, char **argv) { warn_freeinodes_percent, crit_freeinodes_percent); } - // If a list of paths has not been explicitely selected, find entire + // If a list of paths has not been explicitly selected, find entire // mount list and create list of paths if (!path_selected && !result.config.path_ignored) { for (struct mount_entry *me = result.config.mount_list; me; me = me->me_next) { diff --git a/plugins/t/check_disk.t b/plugins/t/check_disk.t index 16daee9a..019cc9fe 100644 --- a/plugins/t/check_disk.t +++ b/plugins/t/check_disk.t @@ -39,13 +39,13 @@ like($result->{'mp_test_result'}->{'checks'}->[0]->{'state'}, "/OK/", "First sub like($result->{'mp_test_result'}->{'checks'}->[1]->{'state'}, "/OK/", "Second sub result is OK"); my $absolut_space_mp1 = $result->{'mp_test_result'}->{'checks'}->[1]->{'checks'}->[0]->{'perfdata'}->[0]->{'max'}->{'value'}; -# print("absolut space on mp1: ". $absolut_space_mp1 . "\n"); +# print("absolute space on mp1: ". $absolut_space_mp1 . "\n"); my $free_percent_on_mp1 = ($result->{'mp_test_result'}->{'checks'}->[1]->{'checks'}->[0]->{'perfdata'}->[0]->{'value'}->{'value'} / ($absolut_space_mp1/100)); print("free percent on mp1: ". $free_percent_on_mp1 . "\n"); my $absolut_space_mp2 = $result->{'mp_test_result'}->{'checks'}->[0]->{'checks'}->[0]->{'perfdata'}->[0]->{'max'}->{'value'}; -# print("absolut space on mp2: ". $absolut_space_mp2 . "\n"); +# print("absolute space on mp2: ". $absolut_space_mp2 . "\n"); my $free_percent_on_mp2 = ($result->{'mp_test_result'}->{'checks'}->[0]->{'checks'}->[0]->{'perfdata'}->[0]->{'value'}->{'value'}/ ($absolut_space_mp2/100)); print("free percent on mp2: ". $free_percent_on_mp2 . "\n"); -- cgit v1.2.3-74-g34f1 From a4cf2e79f75dce3828be21726f10c755f652f710 Mon Sep 17 00:00:00 2001 From: Lorenz Kästle <12514511+RincewindsHat@users.noreply.github.com> Date: Sun, 30 Mar 2025 23:30:51 +0200 Subject: Remove cool, comfy c23 functionality for some dirty old hacks --- plugins/check_disk.c | 42 +++++++++++++++++++++++++++------------ plugins/check_disk.d/utils_disk.c | 2 +- plugins/check_disk.d/utils_disk.h | 38 ++++++++++++++++++----------------- 3 files changed, 50 insertions(+), 32 deletions(-) (limited to 'plugins') diff --git a/plugins/check_disk.c b/plugins/check_disk.c index ddb9ee49..ac3933a6 100644 --- a/plugins/check_disk.c +++ b/plugins/check_disk.c @@ -96,6 +96,22 @@ static void print_help(void); static int verbose = 0; +// This would not be necessary in C23!! +const byte_unit Bytes_Factor = 1; +const byte_unit KibiBytes_factor = 1024; +const byte_unit MebiBytes_factor = 1048576; +const byte_unit GibiBytes_factor = 1073741824; +const byte_unit TebiBytes_factor = 1099511627776; +const byte_unit PebiBytes_factor = 1125899906842624; +const byte_unit ExbiBytes_factor = 1152921504606846976; +const byte_unit KiloBytes_factor = 1000; +const byte_unit MegaBytes_factor = 1000000; +const byte_unit GigaBytes_factor = 1000000000; +const byte_unit TeraBytes_factor = 1000000000000; +const byte_unit PetaBytes_factor = 1000000000000000; +const byte_unit ExaBytes_factor = 1000000000000000000; + + int main(int argc, char **argv) { setlocale(LC_ALL, ""); bindtextdomain(PACKAGE, LOCALEDIR); @@ -409,7 +425,7 @@ check_disk_config_wrapper process_arguments(int argc, char **argv) { bool path_selected = false; char *group = NULL; - byte_unit unit = MebiBytes; + byte_unit unit = MebiBytes_factor; result.config.mount_list = read_file_system_list(false); @@ -494,25 +510,25 @@ check_disk_config_wrapper process_arguments(int argc, char **argv) { break; case 'u': if (!strcasecmp(optarg, "bytes")) { - unit = Bytes; + unit = Bytes_Factor; } else if (!strcmp(optarg, "KiB")) { - unit = KibiBytes; + unit = KibiBytes_factor; } else if (!strcmp(optarg, "kB")) { - unit = KiloBytes; + unit = KiloBytes_factor; } else if (!strcmp(optarg, "MiB")) { - unit = MebiBytes; + unit = MebiBytes_factor; } else if (!strcmp(optarg, "MB")) { - unit = MegaBytes; + unit = MegaBytes_factor; } else if (!strcmp(optarg, "GiB")) { - unit = GibiBytes; + unit = MegaBytes_factor; } else if (!strcmp(optarg, "GB")) { - unit = GigaBytes; + unit = MegaBytes_factor; } else if (!strcmp(optarg, "TiB")) { - unit = TebiBytes; + unit = MegaBytes_factor; } else if (!strcmp(optarg, "TB")) { - unit = TeraBytes; + unit = MegaBytes_factor; } else if (!strcmp(optarg, "PiB")) { - unit = PebiBytes; + unit = MegaBytes_factor; } else if (!strcmp(optarg, "PB")) { unit = PetaBytes; } else { @@ -520,10 +536,10 @@ check_disk_config_wrapper process_arguments(int argc, char **argv) { } break; case 'k': - unit = KibiBytes; + unit = KibiBytes_factor; break; case 'm': - unit = MebiBytes; + unit = MebiBytes_factor; break; case display_unit_index: if (!strcasecmp(optarg, "bytes")) { diff --git a/plugins/check_disk.d/utils_disk.c b/plugins/check_disk.d/utils_disk.c index 3986a8a8..a78b4eae 100644 --- a/plugins/check_disk.d/utils_disk.c +++ b/plugins/check_disk.d/utils_disk.c @@ -180,7 +180,7 @@ check_disk_config check_disk_config_init() { return tmp; } -char *get_unit_string(byte_unit unit) { +char *get_unit_string(byte_unit_enum unit) { switch (unit) { case Bytes: return "Bytes"; diff --git a/plugins/check_disk.d/utils_disk.h b/plugins/check_disk.d/utils_disk.h index a66453ea..1f574695 100644 --- a/plugins/check_disk.d/utils_disk.h +++ b/plugins/check_disk.d/utils_disk.h @@ -8,22 +8,24 @@ #include "regex.h" #include -typedef enum : unsigned long { - Humanized = 0, - Bytes = 1, - KibiBytes = 1024, - MebiBytes = 1024 * KibiBytes, - GibiBytes = 1024 * MebiBytes, - TebiBytes = 1024 * GibiBytes, - PebiBytes = 1024 * TebiBytes, - ExbiBytes = 1024 * PebiBytes, - KiloBytes = 1000, - MegaBytes = 1000 * KiloBytes, - GigaBytes = 1000 * MegaBytes, - TeraBytes = 1000 * GigaBytes, - PetaBytes = 1000 * TeraBytes, - ExaBytes = 1000 * PetaBytes -} byte_unit; +typedef unsigned long long byte_unit; + +typedef enum { + Humanized, + Bytes, + KibiBytes, + MebiBytes, + GibiBytes, + TebiBytes, + PebiBytes, + ExbiBytes, + KiloBytes, + MegaBytes, + GigaBytes, + TeraBytes, + PetaBytes, + ExaBytes, +} byte_unit_enum; typedef struct name_list string_list; struct name_list { @@ -120,7 +122,7 @@ typedef struct { struct mount_entry *mount_list; struct name_list *seen; - byte_unit display_unit; + byte_unit_enum display_unit; // byte_unit unit; bool output_format_is_set; @@ -149,7 +151,7 @@ measurement_unit create_measurement_unit_from_filesystem(parameter_list_elem fil int search_parameter_list(parameter_list_elem *list, const char *name); bool np_regex_match_mount_entry(struct mount_entry *, regex_t *); -char *get_unit_string(byte_unit); +char *get_unit_string(byte_unit_enum); check_disk_config check_disk_config_init(); char *humanize_byte_value(uintmax_t value, bool use_si_units); -- cgit v1.2.3-74-g34f1 From d1d6ba67065c0b1a8a61d59522e19a94eb647c94 Mon Sep 17 00:00:00 2001 From: Lorenz Kästle <12514511+RincewindsHat@users.noreply.github.com> Date: Sun, 30 Mar 2025 23:42:50 +0200 Subject: Add debugging to tests for CI --- plugins/t/check_disk.t | 3 +++ 1 file changed, 3 insertions(+) (limited to 'plugins') diff --git a/plugins/t/check_disk.t b/plugins/t/check_disk.t index 019cc9fe..1d0b9838 100644 --- a/plugins/t/check_disk.t +++ b/plugins/t/check_disk.t @@ -129,6 +129,9 @@ my $warn_percth_data = $result->{'mp_test_result'}->{'checks'}->[0]->{'checks'}[ my $crit_percth_data = $result->{'mp_test_result'}->{'checks'}->[0]->{'checks'}[0]->{'perfdata'}->[0]->{'crit'}->{'end'}->{'value'}; my $total_percth_data = $result->{'mp_test_result'}->{'checks'}->[0]->{'checks'}[0]->{'perfdata'}->[0]->{'max'}->{'value'}; +print("warn_percth_data: " . $warn_percth_data . "\n"); +print("crit_percth_data: " . $crit_percth_data . "\n"); + is ($warn_percth_data <=> int((20/100)*$total_percth_data), 0, "Wrong warning in perf data using percent thresholds"); is ($crit_percth_data <=> int((10/100)*$total_percth_data), 0, "Wrong critical in perf data using percent thresholds"); -- cgit v1.2.3-74-g34f1 From d6d394fb0e1d04bbdb9304dcedad933878846266 Mon Sep 17 00:00:00 2001 From: Lorenz Kästle <12514511+RincewindsHat@users.noreply.github.com> Date: Mon, 31 Mar 2025 00:10:56 +0200 Subject: Fix some typos with units --- plugins/check_disk.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'plugins') diff --git a/plugins/check_disk.c b/plugins/check_disk.c index ac3933a6..e53ec87f 100644 --- a/plugins/check_disk.c +++ b/plugins/check_disk.c @@ -520,17 +520,17 @@ check_disk_config_wrapper process_arguments(int argc, char **argv) { } else if (!strcmp(optarg, "MB")) { unit = MegaBytes_factor; } else if (!strcmp(optarg, "GiB")) { - unit = MegaBytes_factor; + unit = GibiBytes_factor; } else if (!strcmp(optarg, "GB")) { - unit = MegaBytes_factor; + unit = GigaBytes_factor; } else if (!strcmp(optarg, "TiB")) { - unit = MegaBytes_factor; + unit = TebiBytes_factor; } else if (!strcmp(optarg, "TB")) { - unit = MegaBytes_factor; + unit = TeraBytes_factor; } else if (!strcmp(optarg, "PiB")) { - unit = MegaBytes_factor; + unit = PebiBytes_factor; } else if (!strcmp(optarg, "PB")) { - unit = PetaBytes; + unit = PetaBytes_factor; } else { die(STATE_UNKNOWN, _("unit type %s not known\n"), optarg); } -- cgit v1.2.3-74-g34f1 From 1b0085c2e7196aa77d605e8cb1863064a8e5189c Mon Sep 17 00:00:00 2001 From: Lorenz Kästle <12514511+RincewindsHat@users.noreply.github.com> Date: Mon, 31 Mar 2025 00:46:10 +0200 Subject: Fixes problems after a4cf2e79f75dce3828be21726f10c755f652f710 --- plugins/check_disk.c | 2 +- plugins/check_disk.d/utils_disk.c | 62 ++++++++++++++++++++++++--------------- plugins/check_disk.d/utils_disk.h | 2 +- 3 files changed, 41 insertions(+), 25 deletions(-) (limited to 'plugins') diff --git a/plugins/check_disk.c b/plugins/check_disk.c index e53ec87f..515ddff0 100644 --- a/plugins/check_disk.c +++ b/plugins/check_disk.c @@ -1112,7 +1112,7 @@ mp_subcheck evaluate_filesystem(measurement_unit measurement_unit, bool display_ get_unit_string(unit), (uintmax_t)(measurement_unit.total_bytes / unit), get_unit_string(unit)); } else { xasprintf(&freespace_bytes_sc.output, "Free space absolute: %s (of %s)", humanize_byte_value(measurement_unit.free_bytes, false), - humanize_byte_value(measurement_unit.total_bytes, false)); + humanize_byte_value((unsigned long long)measurement_unit.total_bytes, false)); } mp_perfdata used_space = perfdata_init(); diff --git a/plugins/check_disk.d/utils_disk.c b/plugins/check_disk.d/utils_disk.c index a78b4eae..eec1282b 100644 --- a/plugins/check_disk.d/utils_disk.c +++ b/plugins/check_disk.d/utils_disk.c @@ -309,7 +309,7 @@ measurement_unit create_measurement_unit_from_filesystem(parameter_list_elem fil #define RANDOM_STRING_LENGTH 64 -char *humanize_byte_value(uintmax_t value, bool use_si_units) { +char *humanize_byte_value(unsigned long long value, bool use_si_units) { // Idea: A reasonable output should have at most 3 orders of magnitude // before the decimal separator // 353GiB is ok, 2444 GiB should be 2.386 TiB @@ -317,36 +317,52 @@ char *humanize_byte_value(uintmax_t value, bool use_si_units) { if (result == NULL) { die(STATE_UNKNOWN, _("allocation failed")); } + const byte_unit KibiBytes_factor = 1024; + const byte_unit MebiBytes_factor = 1048576; + const byte_unit GibiBytes_factor = 1073741824; + const byte_unit TebiBytes_factor = 1099511627776; + const byte_unit PebiBytes_factor = 1125899906842624; + const byte_unit ExbiBytes_factor = 1152921504606846976; + const byte_unit KiloBytes_factor = 1000; + const byte_unit MegaBytes_factor = 1000000; + const byte_unit GigaBytes_factor = 1000000000; + const byte_unit TeraBytes_factor = 1000000000000; + const byte_unit PetaBytes_factor = 1000000000000000; + const byte_unit ExaBytes_factor = 1000000000000000000; if (use_si_units) { // SI units, powers of 10 - if (value < KiloBytes) { - snprintf(result, RANDOM_STRING_LENGTH, "%ju B", value); - } else if (value < MegaBytes) { - snprintf(result, RANDOM_STRING_LENGTH, "%ju KB", value / KiloBytes); - } else if (value < GigaBytes) { - snprintf(result, RANDOM_STRING_LENGTH, "%ju MB", value / MegaBytes); - } else if (value < TeraBytes) { - snprintf(result, RANDOM_STRING_LENGTH, "%ju GB", value / GigaBytes); - } else if (value < PetaBytes) { - snprintf(result, RANDOM_STRING_LENGTH, "%ju TB", value / TeraBytes); + if (value < KiloBytes_factor) { + snprintf(result, RANDOM_STRING_LENGTH, "%llu B", value); + } else if (value < MegaBytes_factor) { + snprintf(result, RANDOM_STRING_LENGTH, "%llu KB", value / KiloBytes_factor); + } else if (value < GigaBytes_factor) { + snprintf(result, RANDOM_STRING_LENGTH, "%llu MB", value / MegaBytes_factor); + } else if (value < TeraBytes_factor) { + snprintf(result, RANDOM_STRING_LENGTH, "%llu GB", value / GigaBytes_factor); + } else if (value < PetaBytes_factor) { + snprintf(result, RANDOM_STRING_LENGTH, "%llu TB", value / TeraBytes_factor); + } else if (value < ExaBytes_factor) { + snprintf(result, RANDOM_STRING_LENGTH, "%llu PB", value / PetaBytes_factor); } else { - snprintf(result, RANDOM_STRING_LENGTH, "%ju PB", value / PetaBytes); + snprintf(result, RANDOM_STRING_LENGTH, "%llu EB", value / ExaBytes_factor); } } else { // IEC units, powers of 2 ^ 10 - if (value < KibiBytes) { - snprintf(result, RANDOM_STRING_LENGTH, "%ju B", value); - } else if (value < MebiBytes) { - snprintf(result, RANDOM_STRING_LENGTH, "%ju KiB", value / KibiBytes); - } else if (value < GibiBytes) { - snprintf(result, RANDOM_STRING_LENGTH, "%ju MiB", value / MebiBytes); - } else if (value < TebiBytes) { - snprintf(result, RANDOM_STRING_LENGTH, "%ju GiB", value / GibiBytes); - } else if (value < PebiBytes) { - snprintf(result, RANDOM_STRING_LENGTH, "%ju TiB", value / TebiBytes); + if (value < KibiBytes_factor) { + snprintf(result, RANDOM_STRING_LENGTH, "%llu B", value); + } else if (value < MebiBytes_factor) { + snprintf(result, RANDOM_STRING_LENGTH, "%llu KiB", value / KibiBytes_factor); + } else if (value < GibiBytes_factor) { + snprintf(result, RANDOM_STRING_LENGTH, "%llu MiB", value / MebiBytes_factor); + } else if (value < TebiBytes_factor) { + snprintf(result, RANDOM_STRING_LENGTH, "%llu GiB", value / GibiBytes_factor); + } else if (value < PebiBytes_factor) { + snprintf(result, RANDOM_STRING_LENGTH, "%llu TiB", value / TebiBytes_factor); + } else if (value < ExbiBytes_factor) { + snprintf(result, RANDOM_STRING_LENGTH, "%llu PiB", value / PebiBytes_factor); } else { - snprintf(result, RANDOM_STRING_LENGTH, "%ju PiB", value / PebiBytes); + snprintf(result, RANDOM_STRING_LENGTH, "%llu EiB", value / ExbiBytes_factor); } } diff --git a/plugins/check_disk.d/utils_disk.h b/plugins/check_disk.d/utils_disk.h index 1f574695..6831d1fd 100644 --- a/plugins/check_disk.d/utils_disk.h +++ b/plugins/check_disk.d/utils_disk.h @@ -154,4 +154,4 @@ bool np_regex_match_mount_entry(struct mount_entry *, regex_t *); char *get_unit_string(byte_unit_enum); check_disk_config check_disk_config_init(); -char *humanize_byte_value(uintmax_t value, bool use_si_units); +char *humanize_byte_value(unsigned long long value, bool use_si_units); -- cgit v1.2.3-74-g34f1 From 24a50b9421050b3c49dd07eddc942934f66685ca Mon Sep 17 00:00:00 2001 From: Lorenz Kästle <12514511+RincewindsHat@users.noreply.github.com> Date: Mon, 31 Mar 2025 22:18:19 +0200 Subject: check_disk: decrease precision to avoid false negatives with small measurement changes --- plugins/t/check_disk.t | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) (limited to 'plugins') diff --git a/plugins/t/check_disk.t b/plugins/t/check_disk.t index 1d0b9838..f07b2303 100644 --- a/plugins/t/check_disk.t +++ b/plugins/t/check_disk.t @@ -54,6 +54,10 @@ my @perfdata; @perfdata[0] = $result->{'mp_test_result'}->{'checks'}->[0]->{'checks'}->[0]->{'perfdata'}->[0]; @perfdata[1] = $result->{'mp_test_result'}->{'checks'}->[1]->{'checks'}->[0]->{'perfdata'}->[0]; +# Decrease precision of numbers since the the fs might be modified between the two runs +$perfdata[0]->{'value'}->{'value'} = int($perfdata[0]->{'value'}->{'value'} / 1000000); +$perfdata[0]->{'value'}->{'value'} = int($perfdata[0]->{'value'}->{'value'} / 1000000); + # Calculate avg_free free on mountpoint1 and mountpoint2 # because if you check in the middle, you should get different errors my $avg_free_percent = ceil(($free_percent_on_mp1+$free_percent_on_mp2)/2); @@ -144,8 +148,11 @@ cmp_ok( $result->return_code, "==", 0, "with JSON test format result should alwa # write comparison set for perfdata here, but in reversed order, maybe there is a smarter way my @perfdata2; -@perfdata2[1] = $result->{'mp_test_result'}->{'checks'}->[0]->{'checks'}->[0]->{'perfdata'}->[0]; @perfdata2[0] = $result->{'mp_test_result'}->{'checks'}->[1]->{'checks'}->[0]->{'perfdata'}->[0]; +@perfdata2[1] = $result->{'mp_test_result'}->{'checks'}->[0]->{'checks'}->[0]->{'perfdata'}->[0]; +# Decrease precision of numbers since the the fs might be modified between the two runs +$perfdata2[0]->{'value'}->{'value'} = int($perfdata[0]->{'value'}->{'value'} / 1000000); +$perfdata2[0]->{'value'}->{'value'} = int($perfdata[0]->{'value'}->{'value'} / 1000000); is_deeply(\@perfdata, \@perfdata2, "perf data for both filesystems same when reversed"); # Basic filesystem checks for sizes -- cgit v1.2.3-74-g34f1 From 13c9de8c77477e78014622f5c4ff31226aeb286d Mon Sep 17 00:00:00 2001 From: Lorenz Kästle <12514511+RincewindsHat@users.noreply.github.com> Date: Mon, 31 Mar 2025 22:29:49 +0200 Subject: Try fixing some tests --- plugins/t/check_disk.t | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) (limited to 'plugins') diff --git a/plugins/t/check_disk.t b/plugins/t/check_disk.t index f07b2303..0f62fb2b 100644 --- a/plugins/t/check_disk.t +++ b/plugins/t/check_disk.t @@ -26,7 +26,7 @@ my $output_format = "--output-format mp-test-json"; if ($mountpoint_valid eq "" or $mountpoint2_valid eq "") { plan skip_all => "Need 2 mountpoints to test"; } else { - plan tests => 96; + plan tests => 97; } $result = NPTest->testCmd( @@ -56,7 +56,7 @@ my @perfdata; # Decrease precision of numbers since the the fs might be modified between the two runs $perfdata[0]->{'value'}->{'value'} = int($perfdata[0]->{'value'}->{'value'} / 1000000); -$perfdata[0]->{'value'}->{'value'} = int($perfdata[0]->{'value'}->{'value'} / 1000000); +$perfdata[1]->{'value'}->{'value'} = int($perfdata[1]->{'value'}->{'value'} / 1000000); # Calculate avg_free free on mountpoint1 and mountpoint2 # because if you check in the middle, you should get different errors @@ -136,8 +136,8 @@ my $total_percth_data = $result->{'mp_test_result'}->{'checks'}->[0]->{'checks'} print("warn_percth_data: " . $warn_percth_data . "\n"); print("crit_percth_data: " . $crit_percth_data . "\n"); -is ($warn_percth_data <=> int((20/100)*$total_percth_data), 0, "Wrong warning in perf data using percent thresholds"); -is ($crit_percth_data <=> int((10/100)*$total_percth_data), 0, "Wrong critical in perf data using percent thresholds"); +is (int($warn_percth_data), int((20/100)*$total_percth_data), "Wrong warning in perf data using percent thresholds. Got " . $warn_percth_data . " with total " . $total_percth_data); +is (int($crit_percth_data), int((10/100)*$total_percth_data), "Wrong critical in perf data using percent thresholds. Got " . $crit_percth_data . " with total " . $total_percth_data); # Check when order of mount points are reversed, that perf data remains same @@ -151,8 +151,8 @@ my @perfdata2; @perfdata2[0] = $result->{'mp_test_result'}->{'checks'}->[1]->{'checks'}->[0]->{'perfdata'}->[0]; @perfdata2[1] = $result->{'mp_test_result'}->{'checks'}->[0]->{'checks'}->[0]->{'perfdata'}->[0]; # Decrease precision of numbers since the the fs might be modified between the two runs -$perfdata2[0]->{'value'}->{'value'} = int($perfdata[0]->{'value'}->{'value'} / 1000000); -$perfdata2[0]->{'value'}->{'value'} = int($perfdata[0]->{'value'}->{'value'} / 1000000); +$perfdata2[0]->{'value'}->{'value'} = int($perfdata2[0]->{'value'}->{'value'} / 1000000); +$perfdata2[1]->{'value'}->{'value'} = int($perfdata2[1]->{'value'}->{'value'} / 1000000); is_deeply(\@perfdata, \@perfdata2, "perf data for both filesystems same when reversed"); # Basic filesystem checks for sizes @@ -174,8 +174,9 @@ my $free_mb_on_all = $free_mb_on_mp1 + $free_mb_on_mp2; $result = NPTest->testCmd( "./check_disk -e -w 1 -c 1 -p $more_free $output_format" ); cmp_ok( $result->return_code, "==", 0, "with JSON test format result should always be OK"); -$result = NPTest->testCmd( "./check_disk 100 100 $more_free" ); -cmp_ok( $result->return_code, '==', 0, "Old syntax okay" ); +$result = NPTest->testCmd( "./check_disk 101 101 $more_free" ); +like($result->output, "/OK/", "OK in Output"); +cmp_ok( $result->return_code, '==', 0, "Old syntax okay, output was: ". $result->output . "\n" ); $result = NPTest->testCmd( "./check_disk -w 1% -c 1% -p $more_free" ); cmp_ok( $result->return_code, "==", 0, "At least 1% free" ); -- cgit v1.2.3-74-g34f1 From 14169fe5a11b94a9f9ab44336fdb5170ee98be66 Mon Sep 17 00:00:00 2001 From: Jan Wagner Date: Sat, 19 Apr 2025 14:37:46 +0200 Subject: check_http: Adding deprecation text --- plugins/check_http.c | 10 ++++++++++ 1 file changed, 10 insertions(+) (limited to 'plugins') diff --git a/plugins/check_http.c b/plugins/check_http.c index baff682a..8e0c15ec 100644 --- a/plugins/check_http.c +++ b/plugins/check_http.c @@ -1724,6 +1724,16 @@ print_help (void) printf ("%s\n", _("strings and regular expressions, check connection times, and report on")); printf ("%s\n", _("certificate expiration times.")); + printf ("\n"); + printf ("%s\n", _("ATTENTION!")); + printf ("\n"); + printf ("%s\n", _("THIS PLUGIN IS DEPRECATED. The functionality was reimplemented by the")); + printf ("%s\n", _("check_curl plugin, which can be used as a drop-in replacement. You should")); + printf ("%s\n", _("migrate your checks over to check_curl, because check_http is going to be")); + printf ("%s\n", _("removed sooner than later. Just replace check_http with check_curl in your")); + printf ("%s\n", _("check command definitions.")); + printf ("%s\n", _("Report issues to: https://github.com/monitoring-plugins/monitoring-plugins/issues")); + printf ("\n\n"); print_usage (); -- cgit v1.2.3-74-g34f1 From 4acba2b3ecef7c1482b3cd25e35773947d80e2c6 Mon Sep 17 00:00:00 2001 From: William Date: Thu, 27 Mar 2025 11:20:36 +1000 Subject: Improve handling of -4/-6 If fping is used with a target that has dual stack v4/v6, then due to the logic during command construction, ipv4 will never be checked as v6 is preferred by fping. This explicitly flags -4/-6 when it is requested by the user. --- plugins/check_fping.c | 33 ++++++++++++++++++++++----------- 1 file changed, 22 insertions(+), 11 deletions(-) (limited to 'plugins') diff --git a/plugins/check_fping.c b/plugins/check_fping.c index ec7abb67..1c2b7689 100644 --- a/plugins/check_fping.c +++ b/plugins/check_fping.c @@ -79,7 +79,29 @@ int main(int argc, char **argv) { server = strscpy(server, config.server_name); char *option_string = ""; + char *fping_prog = NULL; + /* compose the command */ +#ifdef PATH_TO_FPING6 + if (address_family != AF_INET && is_inet6_addr(server)) { + fping_prog = strdup(PATH_TO_FPING6); + } else { + xasprintf(&option_string, "%s-4 ", option_string); + fping_prog = strdup(PATH_TO_FPING); + } +#else + if (address_family != AF_INET) { + // -4 / -6 must be set explicitly as when a host has dual stack + // if we don't specify -4 then fping selects ipv6 which can mess + // with some checks. + xasprintf(&option_string, "%s-6 ", option_string); + } else { + xasprintf(&option_string, "%s-4 ", option_string); + } + + fping_prog = strdup(PATH_TO_FPING); +#endif + if (config.target_timeout) { xasprintf(&option_string, "%s-t %d ", option_string, config.target_timeout); } @@ -99,17 +121,6 @@ int main(int argc, char **argv) { 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); - } else { - fping_prog = strdup(PATH_TO_FPING); - } -#else - fping_prog = strdup(PATH_TO_FPING); -#endif - 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); -- cgit v1.2.3-74-g34f1 From a1472be88322140cf1f2fc39b9e1b654a86f8155 Mon Sep 17 00:00:00 2001 From: William Date: Fri, 28 Mar 2025 12:40:35 +1000 Subject: Harden check with unspec --- plugins/check_fping.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'plugins') diff --git a/plugins/check_fping.c b/plugins/check_fping.c index 1c2b7689..cf9c2d1c 100644 --- a/plugins/check_fping.c +++ b/plugins/check_fping.c @@ -83,14 +83,14 @@ int main(int argc, char **argv) { /* compose the command */ #ifdef PATH_TO_FPING6 - if (address_family != AF_INET && is_inet6_addr(server)) { + if (address_family == AF_INET6 || (address_family == AF_UNSPEC && is_inet6_addr(server))) { fping_prog = strdup(PATH_TO_FPING6); } else { xasprintf(&option_string, "%s-4 ", option_string); fping_prog = strdup(PATH_TO_FPING); } #else - if (address_family != AF_INET) { + if (address_family == AF_INET6 || (address_family == AF_UNSPEC && is_inet6_addr(server))) { // -4 / -6 must be set explicitly as when a host has dual stack // if we don't specify -4 then fping selects ipv6 which can mess // with some checks. -- cgit v1.2.3-74-g34f1 From 58a34245110f12192d3b3e99198086c119a57418 Mon Sep 17 00:00:00 2001 From: William Date: Wed, 2 Apr 2025 10:50:56 +1000 Subject: Improve logic --- plugins/check_fping.c | 48 +++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 41 insertions(+), 7 deletions(-) (limited to 'plugins') diff --git a/plugins/check_fping.c b/plugins/check_fping.c index cf9c2d1c..9dadcec7 100644 --- a/plugins/check_fping.c +++ b/plugins/check_fping.c @@ -81,27 +81,61 @@ int main(int argc, char **argv) { char *option_string = ""; char *fping_prog = NULL; - /* compose the command */ + /* First determine if the target is dualstack or ipv6 only. */ +#ifdef USE_IPV6 + bool server_is_inet6_addr = is_inet6_addr(server); +#else + bool server_is_inet6_addr = false; +#endif + + /* PATH_TO_FPING6 implies USE_IPV6 */ #ifdef PATH_TO_FPING6 - if (address_family == AF_INET6 || (address_family == AF_UNSPEC && is_inet6_addr(server))) { + /* + * If the user requested -6 OR the user made no assertion and the address is v6 or dualstack + * -> we use ipv6 + * If the user requested -4 OR the user made no assertion and the address is v4 ONLY + * -> we use ipv4 + */ + if (address_family == AF_INET6 || (address_family == AF_UNSPEC && server_is_inet6_addr)) { fping_prog = strdup(PATH_TO_FPING6); } else { xasprintf(&option_string, "%s-4 ", option_string); fping_prog = strdup(PATH_TO_FPING); } #else - if (address_family == AF_INET6 || (address_family == AF_UNSPEC && is_inet6_addr(server))) { - // -4 / -6 must be set explicitly as when a host has dual stack - // if we don't specify -4 then fping selects ipv6 which can mess - // with some checks. +#ifdef USE_IPV6 + /* + * If the user requested -6 OR the user made no assertion and the address is v6 or dualstack + * -> we use ipv6 + * If the user requested -4 OR the user made no assertion and the address is v4 ONLY + * -> we use ipv4 + */ + if (address_family == AF_INET6 || (address_family == AF_UNSPEC && server_is_inet6_addr)) { xasprintf(&option_string, "%s-6 ", option_string); } else { xasprintf(&option_string, "%s-4 ", option_string); } - +#else + /* + * If the user requested -6 + * -> warn that v6 is not available + * -> we use ipv4 + */ + if (address_family == AF_INET6) { + usage4(_("IPv6 support not available")); + } + /* + * Note here we still have to call with -4, else in the case of a dual stacked target + * we could potentially silently use ipv6 despite having just warned that it is not available + */ + xasprintf(&option_string, "%s-4 ", option_string); + /* end USE_IPV6 */ +#endif fping_prog = strdup(PATH_TO_FPING); + /* end PATH_TO_FPING6 */ #endif + /* compose the command */ if (config.target_timeout) { xasprintf(&option_string, "%s-t %d ", option_string, config.target_timeout); } -- cgit v1.2.3-74-g34f1 From 1fb9300a2f10d5c649df484e1b8d7550f9a5f846 Mon Sep 17 00:00:00 2001 From: William Date: Wed, 7 May 2025 13:17:47 +1000 Subject: Remove un-needed flags --- configure.ac | 7 ------- plugins/check_fping.c | 42 ------------------------------------------ 2 files changed, 49 deletions(-) (limited to 'plugins') diff --git a/configure.ac b/configure.ac index fdc9b699..bd3de196 100644 --- a/configure.ac +++ b/configure.ac @@ -1524,17 +1524,10 @@ AC_PATH_PROG(PATH_TO_FPING6,fping6) AC_ARG_WITH(fping_command, ACX_HELP_STRING([--with-fping-command=PATH], [Path to fping command]), PATH_TO_FPING=$withval) -AC_ARG_WITH(fping6_command, - ACX_HELP_STRING([--with-fping6-command=PATH], - [Path to fping6 command]), PATH_TO_FPING6=$withval) - if test -n "$PATH_TO_FPING" then AC_DEFINE_UNQUOTED(PATH_TO_FPING,"$PATH_TO_FPING",[path to fping]) EXTRAS="$EXTRAS check_fping\$(EXEEXT)" - if test x"$with_ipv6" != xno && test -n "$PATH_TO_FPING6"; then - AC_DEFINE_UNQUOTED(PATH_TO_FPING6,"$PATH_TO_FPING6",[path to fping6]) - fi else AC_MSG_WARN([Get fping from http://www.fping.com in order to make check_fping plugin]) fi diff --git a/plugins/check_fping.c b/plugins/check_fping.c index 9dadcec7..e05056b2 100644 --- a/plugins/check_fping.c +++ b/plugins/check_fping.c @@ -82,28 +82,8 @@ int main(int argc, char **argv) { char *fping_prog = NULL; /* First determine if the target is dualstack or ipv6 only. */ -#ifdef USE_IPV6 bool server_is_inet6_addr = is_inet6_addr(server); -#else - bool server_is_inet6_addr = false; -#endif - /* PATH_TO_FPING6 implies USE_IPV6 */ -#ifdef PATH_TO_FPING6 - /* - * If the user requested -6 OR the user made no assertion and the address is v6 or dualstack - * -> we use ipv6 - * If the user requested -4 OR the user made no assertion and the address is v4 ONLY - * -> we use ipv4 - */ - if (address_family == AF_INET6 || (address_family == AF_UNSPEC && server_is_inet6_addr)) { - fping_prog = strdup(PATH_TO_FPING6); - } else { - xasprintf(&option_string, "%s-4 ", option_string); - fping_prog = strdup(PATH_TO_FPING); - } -#else -#ifdef USE_IPV6 /* * If the user requested -6 OR the user made no assertion and the address is v6 or dualstack * -> we use ipv6 @@ -115,25 +95,7 @@ int main(int argc, char **argv) { } else { xasprintf(&option_string, "%s-4 ", option_string); } -#else - /* - * If the user requested -6 - * -> warn that v6 is not available - * -> we use ipv4 - */ - if (address_family == AF_INET6) { - usage4(_("IPv6 support not available")); - } - /* - * Note here we still have to call with -4, else in the case of a dual stacked target - * we could potentially silently use ipv6 despite having just warned that it is not available - */ - xasprintf(&option_string, "%s-4 ", option_string); - /* end USE_IPV6 */ -#endif fping_prog = strdup(PATH_TO_FPING); - /* end PATH_TO_FPING6 */ -#endif /* compose the command */ if (config.target_timeout) { @@ -385,11 +347,7 @@ check_fping_config_wrapper process_arguments(int argc, char **argv) { address_family = AF_INET; break; case '6': /* IPv6 only */ -#ifdef USE_IPV6 address_family = AF_INET6; -#else - usage(_("IPv6 support not available\n")); -#endif break; case 'c': get_threshold(optarg, rv); -- cgit v1.2.3-74-g34f1 From dd93b1403ad28064b0d444189d8aa938dc25365d Mon Sep 17 00:00:00 2001 From: Lorenz Kästle <12514511+RincewindsHat@users.noreply.github.com> Date: Sun, 18 May 2025 19:19:23 +0200 Subject: utils: Make fmt function for compiler --- plugins/utils.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'plugins') diff --git a/plugins/utils.h b/plugins/utils.h index 92a6c115..1d3c153c 100644 --- a/plugins/utils.h +++ b/plugins/utils.h @@ -76,7 +76,7 @@ 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, ...); +int xasprintf(char **strp, const char *fmt, ...)__attribute__ ((format (printf, 2, 3))); void usage(const char *) __attribute__((noreturn)); void usage2(const char *, const char *) __attribute__((noreturn)); -- cgit v1.2.3-74-g34f1 From 7247fc656a1f475159b7879cc3c3b798e03c1a33 Mon Sep 17 00:00:00 2001 From: Lorenz Kästle Date: Thu, 12 Jun 2025 11:13:59 +0200 Subject: Implement new fping options for fping 5.2 and 5.3 fping 5.2 and 5.3 add some new useful command line options which this commit add to check_fping. These are: * --fwmark - sets a firewall mark in the packages to make them identifiable (fping 5.2) * --icmp-timestamp - fping uses ICMP timestamp instead of ICMP Echo (fping 5.2) * --check-source - fping discards replies which originate not from the target address (fping 5.2) The fping release notes describe theses options ( https://github.com/schweikert/fping/releases ) in a little bit more detail. Currently the help display for those options is only shown when fping was available in the appropriate version during compilation. --- plugins/check_fping.c | 80 +++++++++++++++++++++++++++++++++++++----- plugins/check_fping.d/config.h | 24 +++++++++++++ 2 files changed, 96 insertions(+), 8 deletions(-) (limited to 'plugins') diff --git a/plugins/check_fping.c b/plugins/check_fping.c index e05056b2..4d328a01 100644 --- a/plugins/check_fping.c +++ b/plugins/check_fping.c @@ -117,8 +117,26 @@ int main(int argc, char **argv) { xasprintf(&option_string, "%s-R ", option_string); } + if (config.fwmark_set) { + xasprintf(&option_string, "%s--fwmark %u ", option_string, config.fwmark); + } + + if (config.icmp_timestamp) { + xasprintf(&option_string, "%s--icmp-timestamp ", option_string); + } + + if (config.check_source) { + xasprintf(&option_string, "%s--check-source ", option_string); + } + 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 (config.icmp_timestamp) { + // no paket size settable for ICMP timestamp + xasprintf(&command_line, "%s %s -c %d %s", fping_prog, option_string, config.packet_count, server); + } else { + 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); @@ -275,13 +293,35 @@ mp_state_enum textscan(char *buf, const char *server_name, bool crta_p, double c /* process command-line arguments */ 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'}, - {"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}}; + enum { + FWMARK_OPT = CHAR_MAX + 1, + ICMP_TIMESTAMP_OPT, + CHECK_SOURCE_OPT, + }; + 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'}, + // only available with fping version >= 5.3 + {"fwmark", required_argument, NULL, FWMARK_OPT}, + // only available with fping version >= 5.3 + {"icmp-timestamp", no_argument, NULL, ICMP_TIMESTAMP_OPT}, + {"check-source", no_argument, NULL, CHECK_SOURCE_OPT}, + + {0, 0, 0, 0}}; char *rv[2]; rv[PL] = NULL; @@ -409,6 +449,20 @@ check_fping_config_wrapper process_arguments(int argc, char **argv) { case 'M': result.config.dontfrag = true; break; + case FWMARK_OPT: + if (is_intpos(optarg)) { + result.config.fwmark = (unsigned int)atol(optarg); + result.config.fwmark_set = true; + } else { + usage(_("fwmark must be a positive integer")); + } + break; + case ICMP_TIMESTAMP_OPT: + result.config.icmp_timestamp = true; + break; + case CHECK_SOURCE_OPT: + result.config.check_source = true; + break; } } @@ -496,6 +550,16 @@ void print_help(void) { printf(" %s\n", _("set the Don't Fragment flag")); printf(" %s\n", "-R, --random"); printf(" %s\n", _("random packet data (to foil link data compression)")); +#ifdef FPING_VERSION_5_2_OR_HIGHER + printf(" %s\n", "--fwmark=INTEGER"); + printf(" %s\n", _("set the routing mark to INTEGER (fping option)")); +# ifdef FPING_VERSION_5_3_OR_HIGHER + printf(" %s\n", "--icmp-timestamp"); + printf(" %s\n", _("use ICMP Timestamp instead of ICMP Echo (fping option)")); + printf(" %s\n", "--check-source"); + printf(" %s\n", _("discard replies not from target address (fping option)")); +# endif +#endif printf(UT_VERBOSE); printf("\n"); printf(" %s\n", _("THRESHOLD is ,%% where is the round trip average travel time (ms)")); diff --git a/plugins/check_fping.d/config.h b/plugins/check_fping.d/config.h index a0697bf3..6d28382a 100644 --- a/plugins/check_fping.d/config.h +++ b/plugins/check_fping.d/config.h @@ -29,6 +29,21 @@ typedef struct { bool cpl_p; int wpl; bool wpl_p; + + // only available with fping version >= 5.2 + // for a given uint _fwmark_ fping sets _fwmark_ as a firewall mark + // in the pakets + unsigned int fwmark; + bool fwmark_set; + + + // only available with fping version >= 5.3 + // Setting icmp_timestamp tells fping to use ICMP Timestamp (ICMP type 13) instead + // of ICMP Echo + bool icmp_timestamp; + + // Setting check_source lets fping discard replies which are not from the target address + bool check_source; } check_fping_config; check_fping_config check_fping_config_init() { @@ -53,6 +68,15 @@ check_fping_config check_fping_config_init() { .cpl_p = false, .wpl = 0, .wpl_p = false, + + // only available with fping version >= 5.2 + .fwmark = 0, + .fwmark_set = false, // just to be deterministic + + // only available with fping version >= 5.3 + .icmp_timestamp = false, + .check_source = false, + }; return tmp; } -- cgit v1.2.3-74-g34f1 From f2c6ce08e3da320d044564352faedd78eb76f1a1 Mon Sep 17 00:00:00 2001 From: Lorenz Kästle Date: Thu, 12 Jun 2025 11:19:42 +0200 Subject: check_fping: small style improvement --- plugins/check_fping.c | 4 ++-- plugins/check_fping.d/config.h | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) (limited to 'plugins') diff --git a/plugins/check_fping.c b/plugins/check_fping.c index 4d328a01..c1e7dd17 100644 --- a/plugins/check_fping.c +++ b/plugins/check_fping.c @@ -132,7 +132,7 @@ int main(int argc, char **argv) { char *command_line = NULL; if (config.icmp_timestamp) { - // no paket size settable for ICMP timestamp + // no packet size settable for ICMP timestamp xasprintf(&command_line, "%s %s -c %d %s", fping_prog, option_string, config.packet_count, server); } else { xasprintf(&command_line, "%s %s-b %d -c %d %s", fping_prog, option_string, config.packet_size, config.packet_count, server); @@ -346,7 +346,7 @@ check_fping_config_wrapper process_arguments(int argc, char **argv) { argc--; } - while (1) { + while (true) { int option_index = getopt_long(argc, argv, "+hVvaH:S:c:w:b:n:T:i:I:M:R:46", longopts, &option); if (option_index == -1 || option_index == EOF || option_index == 1) { diff --git a/plugins/check_fping.d/config.h b/plugins/check_fping.d/config.h index 6d28382a..d95e9ded 100644 --- a/plugins/check_fping.d/config.h +++ b/plugins/check_fping.d/config.h @@ -32,7 +32,7 @@ typedef struct { // only available with fping version >= 5.2 // for a given uint _fwmark_ fping sets _fwmark_ as a firewall mark - // in the pakets + // in the packets unsigned int fwmark; bool fwmark_set; -- cgit v1.2.3-74-g34f1 From 19f409ac559278cd8623e2d5875818938f648996 Mon Sep 17 00:00:00 2001 From: Lorenz Kästle Date: Thu, 12 Jun 2025 13:26:55 +0200 Subject: Remove unnecessary newline --- plugins/check_fping.c | 1 - 1 file changed, 1 deletion(-) (limited to 'plugins') diff --git a/plugins/check_fping.c b/plugins/check_fping.c index c1e7dd17..5db6b9aa 100644 --- a/plugins/check_fping.c +++ b/plugins/check_fping.c @@ -320,7 +320,6 @@ check_fping_config_wrapper process_arguments(int argc, char **argv) { // only available with fping version >= 5.3 {"icmp-timestamp", no_argument, NULL, ICMP_TIMESTAMP_OPT}, {"check-source", no_argument, NULL, CHECK_SOURCE_OPT}, - {0, 0, 0, 0}}; char *rv[2]; -- cgit v1.2.3-74-g34f1 From a669b2531d3b01aeb5b3e39c28bf2e6816fb14af Mon Sep 17 00:00:00 2001 From: Lorenz Kästle Date: Thu, 12 Jun 2025 13:33:50 +0200 Subject: Remove options if fping version is too low and die directly --- plugins/check_fping.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'plugins') diff --git a/plugins/check_fping.c b/plugins/check_fping.c index 5db6b9aa..8018e06d 100644 --- a/plugins/check_fping.c +++ b/plugins/check_fping.c @@ -315,11 +315,15 @@ check_fping_config_wrapper process_arguments(int argc, char **argv) { {"use-ipv6", no_argument, 0, '6'}, {"dontfrag", no_argument, 0, 'M'}, {"random", no_argument, 0, 'R'}, - // only available with fping version >= 5.3 +#ifdef FPING_VERSION_5_2_OR_HIGHER + // only available with fping version >= 5.2 {"fwmark", required_argument, NULL, FWMARK_OPT}, +# ifdef FPING_VERSION_5_3_OR_HIGHER // only available with fping version >= 5.3 {"icmp-timestamp", no_argument, NULL, ICMP_TIMESTAMP_OPT}, {"check-source", no_argument, NULL, CHECK_SOURCE_OPT}, +# endif +#endif {0, 0, 0, 0}}; char *rv[2]; -- cgit v1.2.3-74-g34f1 From 4ef8af0d9a2acb2e199b613af2d85af86fed24b2 Mon Sep 17 00:00:00 2001 From: Lorenz Kästle <12514511+RincewindsHat@users.noreply.github.com> Date: Sun, 6 Jul 2025 21:46:54 +0200 Subject: check_load: remove useless code and do some formatting --- plugins/check_load.c | 36 +++++++++++++++++++++++------------- 1 file changed, 23 insertions(+), 13 deletions(-) (limited to 'plugins') diff --git a/plugins/check_load.c b/plugins/check_load.c index bf3c89d8..f7e80fdb 100644 --- a/plugins/check_load.c +++ b/plugins/check_load.c @@ -58,7 +58,6 @@ typedef struct { check_load_config config; } check_load_config_wrapper; static check_load_config_wrapper process_arguments(int argc, char **argv); -static check_load_config_wrapper validate_arguments(check_load_config_wrapper /*config_wrapper*/); void print_help(void); void print_usage(void); @@ -78,9 +77,12 @@ static parsed_thresholds get_threshold(char *arg) { bool valid = false; parsed_thresholds result = { - .load[0] = mp_range_init(), - .load[1] = mp_range_init(), - .load[2] = mp_range_init(), + .load = + { + mp_range_init(), + mp_range_init(), + mp_range_init(), + }, }; size_t arg_length = strlen(arg); @@ -148,10 +150,11 @@ int main(int argc, char **argv) { if (config.take_into_account_cpus && ((numcpus = GET_NUMBER_OF_CPUS()) > 0)) { is_using_scaled_load_values = true; - double scaled_la[3] = {0.0, 0.0, 0.0}; - scaled_la[0] = load_values[0] / numcpus; - scaled_la[1] = load_values[1] / numcpus; - scaled_la[2] = load_values[2] / numcpus; + double scaled_la[3] = { + load_values[0] / numcpus, + load_values[1] / numcpus, + load_values[2] / numcpus, + }; mp_subcheck scaled_load_sc = mp_subcheck_init(); scaled_load_sc = mp_set_subcheck_default_state(scaled_load_sc, STATE_OK); @@ -292,7 +295,6 @@ static check_load_config_wrapper process_arguments(int argc, char **argv) { 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); } @@ -305,8 +307,10 @@ static check_load_config_wrapper process_arguments(int argc, char **argv) { parsed_thresholds warning_range = get_threshold(optarg); result.config.th_load[0].warning = warning_range.load[0]; result.config.th_load[0].warning_is_set = true; + result.config.th_load[1].warning = warning_range.load[1]; result.config.th_load[1].warning_is_set = true; + result.config.th_load[2].warning = warning_range.load[2]; result.config.th_load[2].warning_is_set = true; } break; @@ -314,8 +318,10 @@ static check_load_config_wrapper process_arguments(int argc, char **argv) { parsed_thresholds critical_range = get_threshold(optarg); result.config.th_load[0].critical = critical_range.load[0]; result.config.th_load[0].critical_is_set = true; + result.config.th_load[1].critical = critical_range.load[1]; result.config.th_load[1].critical_is_set = true; + result.config.th_load[2].critical = critical_range.load[2]; result.config.th_load[2].critical_is_set = true; } break; @@ -338,7 +344,7 @@ static check_load_config_wrapper process_arguments(int argc, char **argv) { int index = optind; if (index == argc) { - return validate_arguments(result); + return result; } /* handle the case if both arguments are missing, @@ -347,32 +353,36 @@ static check_load_config_wrapper process_arguments(int argc, char **argv) { parsed_thresholds warning_range = get_threshold(argv[index++]); result.config.th_load[0].warning = warning_range.load[0]; result.config.th_load[0].warning_is_set = true; + result.config.th_load[1].warning = warning_range.load[1]; result.config.th_load[1].warning_is_set = true; + result.config.th_load[2].warning = warning_range.load[2]; result.config.th_load[2].warning_is_set = true; parsed_thresholds critical_range = get_threshold(argv[index++]); result.config.th_load[0].critical = critical_range.load[0]; result.config.th_load[0].critical_is_set = true; + result.config.th_load[1].critical = critical_range.load[1]; result.config.th_load[1].critical_is_set = true; + result.config.th_load[2].critical = critical_range.load[2]; result.config.th_load[2].critical_is_set = true; } else if (index - argc == 1) { parsed_thresholds critical_range = get_threshold(argv[index++]); result.config.th_load[0].critical = critical_range.load[0]; result.config.th_load[0].critical_is_set = true; + result.config.th_load[1].critical = critical_range.load[1]; result.config.th_load[1].critical_is_set = true; + result.config.th_load[2].critical = critical_range.load[2]; result.config.th_load[2].critical_is_set = true; } - return validate_arguments(result); + return result; } -static check_load_config_wrapper validate_arguments(check_load_config_wrapper config_wrapper) { return config_wrapper; } - void print_help(void) { print_revision(progname, NP_VERSION); -- cgit v1.2.3-74-g34f1 From b002a6870b6ef9333d3234cec58b8c2fc1acfeec Mon Sep 17 00:00:00 2001 From: Lorenz Kästle <12514511+RincewindsHat@users.noreply.github.com> Date: Sun, 6 Jul 2025 21:58:55 +0200 Subject: check_load: Add top x functionality to output --- plugins/check_load.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'plugins') diff --git a/plugins/check_load.c b/plugins/check_load.c index f7e80fdb..78daa945 100644 --- a/plugins/check_load.c +++ b/plugins/check_load.c @@ -245,13 +245,15 @@ int main(int argc, char **argv) { mp_subcheck top_proc_sc = mp_subcheck_init(); top_proc_sc = mp_set_subcheck_state(top_proc_sc, STATE_OK); top_processes_result top_proc = print_top_consuming_processes(config.n_procs_to_show); - top_proc_sc.output = ""; + xasprintf(&top_proc_sc.output, "Top %lu CPU time consuming processes", config.n_procs_to_show); if (top_proc.errorcode == OK) { for (int i = 0; i < config.n_procs_to_show; i++) { xasprintf(&top_proc_sc.output, "%s\n%s", top_proc_sc.output, top_proc.top_processes[i]); } } + + mp_add_subcheck_to_check(&overall, top_proc_sc); } mp_exit(overall); -- cgit v1.2.3-74-g34f1 From 351b104894fd52e634d60d79f573be682a2da8d4 Mon Sep 17 00:00:00 2001 From: Lorenz Kästle <12514511+RincewindsHat@users.noreply.github.com> Date: Sun, 6 Jul 2025 21:59:12 +0200 Subject: check_load some number type fixes --- plugins/check_load.c | 12 ++++++------ plugins/check_load.d/config.h | 2 +- 2 files changed, 7 insertions(+), 7 deletions(-) (limited to 'plugins') diff --git a/plugins/check_load.c b/plugins/check_load.c index 78daa945..2925bff3 100644 --- a/plugins/check_load.c +++ b/plugins/check_load.c @@ -65,7 +65,7 @@ typedef struct { int errorcode; char **top_processes; } top_processes_result; -static top_processes_result print_top_consuming_processes(int /*n_procs_to_show*/); +static top_processes_result print_top_consuming_processes(unsigned long n_procs_to_show); typedef struct { mp_range load[3]; @@ -248,7 +248,7 @@ int main(int argc, char **argv) { xasprintf(&top_proc_sc.output, "Top %lu CPU time consuming processes", config.n_procs_to_show); if (top_proc.errorcode == OK) { - for (int i = 0; i < config.n_procs_to_show; i++) { + for (unsigned long i = 0; i < config.n_procs_to_show; i++) { xasprintf(&top_proc_sc.output, "%s\n%s", top_proc_sc.output, top_proc.top_processes[i]); } } @@ -337,7 +337,7 @@ static check_load_config_wrapper process_arguments(int argc, char **argv) { print_help(); exit(STATE_UNKNOWN); case 'n': - result.config.n_procs_to_show = atoi(optarg); + result.config.n_procs_to_show = (unsigned long)atol(optarg); break; case '?': /* help */ usage5(); @@ -441,7 +441,7 @@ int cmpstringp(const void *p1, const void *p2) { } #endif /* PS_USES_PROCPCPU */ -static top_processes_result print_top_consuming_processes(int n_procs_to_show) { +static top_processes_result print_top_consuming_processes(unsigned long n_procs_to_show) { top_processes_result result = { .errorcode = OK, }; @@ -462,7 +462,7 @@ static top_processes_result print_top_consuming_processes(int n_procs_to_show) { #ifdef PS_USES_PROCPCPU qsort(chld_out.line + 1, chld_out.lines - 1, sizeof(char *), cmpstringp); #endif /* PS_USES_PROCPCPU */ - int lines_to_show = chld_out.lines < (size_t)(n_procs_to_show + 1) ? (int)chld_out.lines : n_procs_to_show + 1; + unsigned long lines_to_show = chld_out.lines < (size_t)(n_procs_to_show + 1) ? chld_out.lines : n_procs_to_show + 1; result.top_processes = calloc(lines_to_show, sizeof(char *)); if (result.top_processes == NULL) { @@ -471,7 +471,7 @@ static top_processes_result print_top_consuming_processes(int n_procs_to_show) { return result; } - for (int i = 0; i < lines_to_show; i += 1) { + for (unsigned long i = 0; i < lines_to_show; i += 1) { xasprintf(&result.top_processes[i], "%s", chld_out.line[i]); } diff --git a/plugins/check_load.d/config.h b/plugins/check_load.d/config.h index d399c19c..fd735455 100644 --- a/plugins/check_load.d/config.h +++ b/plugins/check_load.d/config.h @@ -6,7 +6,7 @@ typedef struct { mp_thresholds th_load[3]; bool take_into_account_cpus; - int n_procs_to_show; + unsigned long n_procs_to_show; mp_output_format output_format; bool output_format_set; -- cgit v1.2.3-74-g34f1 From b191a8a05543b22bf8e3255d74d358dd42ef1a89 Mon Sep 17 00:00:00 2001 From: Lorenz Kästle <12514511+RincewindsHat@users.noreply.github.com> Date: Sun, 6 Jul 2025 23:16:34 +0200 Subject: check_load: fix tests --- plugins/t/check_load.t | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'plugins') diff --git a/plugins/t/check_load.t b/plugins/t/check_load.t index 3e453703..fc26bb35 100644 --- a/plugins/t/check_load.t +++ b/plugins/t/check_load.t @@ -33,9 +33,9 @@ cmp_ok( $res->return_code, 'eq', 2, "Load over 0 with per cpu division"); $res = NPTest->testCmd( "./check_load -w 100 -c 100,110" ); cmp_ok( $res->return_code, 'eq', 0, "Plugin can handle non-triplet-arguments"); # like( $res->output, $successOutput, "Output OK"); -like( $res->perf_output, "/load1=$loadValue;~:100.0+;~:100.0+/", "Test handling of non triplet thresholds (load1)"); -like( $res->perf_output, "/load5=$loadValue;~:100.0+;~:110.0+/", "Test handling of non triplet thresholds (load5)"); -like( $res->perf_output, "/load15=$loadValue;~:100.0+;~:110.0+/", "Test handling of non triplet thresholds (load15)"); +like( $res->perf_output, "/'load1'=$loadValue;~:100.0+;~:100.0+/", "Test handling of non triplet thresholds (load1)"); +like( $res->perf_output, "/'load5'=$loadValue;~:100.0+;~:110.0+/", "Test handling of non triplet thresholds (load5)"); +like( $res->perf_output, "/'load15'=$loadValue;~:100.0+;~:110.0+/", "Test handling of non triplet thresholds (load15)"); $res = NPTest->testCmd( "./check_load -w 100,100,100 -c 100,100,100 -r" ); -- cgit v1.2.3-74-g34f1