From 5912398b9723545ecd061650667cbb238be85743 Mon Sep 17 00:00:00 2001 From: Ton Voon Date: Thu, 13 Jul 2006 23:58:00 +0000 Subject: Major fixes to check_disk. Now should return same data as df git-svn-id: https://nagiosplug.svn.sourceforge.net/svnroot/nagiosplug/nagiosplug/trunk@1452 f882894a-f735-0410-b71e-b25c423dba1c --- lib/tests/test_utils.c | 15 +++- lib/utils_base.c | 225 +++++++++++++++++++++++++++++++++++++++++++++++++ lib/utils_base.h | 37 ++++++++ lib/utils_disk.c | 140 ++++++++++++++++++++++++++++++ lib/utils_disk.h | 32 +++++++ 5 files changed, 448 insertions(+), 1 deletion(-) create mode 100644 lib/utils_base.c create mode 100644 lib/utils_base.h create mode 100644 lib/utils_disk.c create mode 100644 lib/utils_disk.h (limited to 'lib') diff --git a/lib/tests/test_utils.c b/lib/tests/test_utils.c index aedc2a58..96b5333d 100644 --- a/lib/tests/test_utils.c +++ b/lib/tests/test_utils.c @@ -31,7 +31,7 @@ main (int argc, char **argv) thresholds *thresholds = NULL; int rc; - plan_tests(74); + plan_tests(82); range = parse_range_string("6"); ok( range != NULL, "'6' is valid range"); @@ -41,6 +41,14 @@ main (int argc, char **argv) ok( range->end_infinity == FALSE, "Not using infinity"); free(range); + range = parse_range_string("1:12%%"); + ok( range != NULL, "'1:12%%' is valid - percentages are ignored"); + ok( range->start == 1, "Start correct"); + ok( range->start_infinity == FALSE, "Not using negative infinity"); + ok( range->end == 12, "End correct"); + ok( range->end_infinity == FALSE, "Not using infinity"); + free(range); + range = parse_range_string("-7:23"); ok( range != NULL, "'-7:23' is valid range"); ok( range->start == -7, "Start correct"); @@ -114,6 +122,11 @@ main (int argc, char **argv) range = parse_range_string("2:1"); ok( range == NULL, "'2:1' rejected"); + rc = _set_thresholds(&thresholds, NULL, NULL); + ok( rc == 0, "Thresholds (NULL, NULL) set"); + ok( thresholds->warning == NULL, "Warning not set"); + ok( thresholds->critical == NULL, "Critical not set"); + rc = _set_thresholds(&thresholds, NULL, "80"); ok( rc == 0, "Thresholds (NULL, '80') set"); ok( thresholds->warning == NULL, "Warning not set"); diff --git a/lib/utils_base.c b/lib/utils_base.c new file mode 100644 index 00000000..5a45f84a --- /dev/null +++ b/lib/utils_base.c @@ -0,0 +1,225 @@ +/***************************************************************************** + * + * utils_base.c + * + * Library of useful functions for plugins + * These functions are tested with libtap. See tests/ directory + * + * Copyright (c) 2006 Nagios Plugin Development Team + * License: GPL + * + * $Revision$ + * $Date$ + ****************************************************************************/ + +#include "common.h" +#include "utils_base.h" + +void +die (int result, const char *fmt, ...) +{ + va_list ap; + va_start (ap, fmt); + vprintf (fmt, ap); + va_end (ap); + exit (result); +} + +void set_range_start (range *this, double value) { + this->start = value; + this->start_infinity = FALSE; +} + +void set_range_end (range *this, double value) { + this->end = value; + this->end_infinity = FALSE; +} + +range +*parse_range_string (char *str) { + range *temp_range; + double start; + double end; + char *end_str; + + temp_range = (range *) malloc(sizeof(range)); + + /* Set defaults */ + temp_range->start = 0; + temp_range->start_infinity = FALSE; + temp_range->end = 0; + temp_range->end_infinity = TRUE; + temp_range->alert_on = OUTSIDE; + + if (str[0] == '@') { + temp_range->alert_on = INSIDE; + str++; + } + + end_str = index(str, ':'); + if (end_str != NULL) { + if (str[0] == '~') { + temp_range->start_infinity = TRUE; + } else { + start = strtod(str, NULL); /* Will stop at the ':' */ + set_range_start(temp_range, start); + } + end_str++; /* Move past the ':' */ + } else { + end_str = str; + } + end = strtod(end_str, NULL); + if (strcmp(end_str, "") != 0) { + set_range_end(temp_range, end); + } + + if (temp_range->start_infinity == TRUE || + temp_range->end_infinity == TRUE || + temp_range->start <= temp_range->end) { + return temp_range; + } + free(temp_range); + return NULL; +} + +/* returns 0 if okay, otherwise 1 */ +int +_set_thresholds(thresholds **my_thresholds, char *warn_string, char *critical_string) +{ + thresholds *temp_thresholds = NULL; + + temp_thresholds = malloc(sizeof(temp_thresholds)); + + temp_thresholds->warning = NULL; + temp_thresholds->critical = NULL; + + if (warn_string != NULL) { + if ((temp_thresholds->warning = parse_range_string(warn_string)) == NULL) { + return 1; + } + } + if (critical_string != NULL) { + if ((temp_thresholds->critical = parse_range_string(critical_string)) == NULL) { + return 1; + } + } + + if (*my_thresholds > 0) { /* Not sure why, but sometimes could be -1 */ + /* printf("Freeing here: %d\n", *my_thresholds); */ + free(*my_thresholds); + } + *my_thresholds = temp_thresholds; + + return 0; +} + +void +set_thresholds(thresholds **my_thresholds, char *warn_string, char *critical_string) +{ + if (_set_thresholds(my_thresholds, warn_string, critical_string) == 0) { + return; + } else { + die(STATE_UNKNOWN, _("Range format incorrect")); + } +} + +void print_thresholds(const char *threshold_name, thresholds *my_threshold) { + printf("%s - ", threshold_name); + if (! my_threshold) { + printf("Threshold not set"); + } else { + if (my_threshold->warning) { + printf("Warning: start=%g end=%g; ", my_threshold->warning->start, my_threshold->warning->end); + } else { + printf("Warning not set; "); + } + if (my_threshold->critical) { + printf("Critical: start=%g end=%g", my_threshold->critical->start, my_threshold->critical->end); + } else { + printf("Critical not set"); + } + } + printf("\n"); +} + +/* Returns TRUE if alert should be raised based on the range */ +int +check_range(double value, range *my_range) +{ + int false = FALSE; + int true = TRUE; + + if (my_range->alert_on == INSIDE) { + false = TRUE; + true = FALSE; + } + + if (my_range->end_infinity == FALSE && my_range->start_infinity == FALSE) { + if ((my_range->start <= value) && (value <= my_range->end)) { + return false; + } else { + return true; + } + } else if (my_range->start_infinity == FALSE && my_range->end_infinity == TRUE) { + if (my_range->start <= value) { + return false; + } else { + return true; + } + } else if (my_range->start_infinity == TRUE && my_range->end_infinity == FALSE) { + if (value <= my_range->end) { + return false; + } else { + return true; + } + } else { + return false; + } +} + +/* Returns status */ +int +get_status(double value, thresholds *my_thresholds) +{ + if (my_thresholds->critical != NULL) { + if (check_range(value, my_thresholds->critical) == TRUE) { + return STATE_CRITICAL; + } + } + if (my_thresholds->warning != NULL) { + if (check_range(value, my_thresholds->warning) == TRUE) { + return STATE_WARNING; + } + } + return STATE_OK; +} + +char *np_escaped_string (const char *string) { + char *data; + int i, j=0; + data = strdup(string); + for (i=0; data[i]; i++) { + if (data[i] == '\\') { + switch(data[++i]) { + case 'n': + data[j++] = '\n'; + break; + case 'r': + data[j++] = '\r'; + break; + case 't': + data[j++] = '\t'; + break; + case '\\': + data[j++] = '\\'; + break; + default: + data[j++] = data[i]; + } + } else { + data[j++] = data[i]; + } + } + data[j] = '\0'; + return data; +} diff --git a/lib/utils_base.h b/lib/utils_base.h new file mode 100644 index 00000000..ca27f169 --- /dev/null +++ b/lib/utils_base.h @@ -0,0 +1,37 @@ +/* Header file for nagios plugins utils_base.c */ + +/* This file holds header information for thresholds - use this in preference to + individual plugin logic */ + +/* This has not been merged with utils.h because of problems with + timeout_interval when other utils_*.h files use utils.h */ + +/* Long term, add new functions to utils_base.h for common routines + and utils_*.h for specific to plugin routines. If routines are + placed in utils_*.h, then these can be tested with libtap */ + +#define OUTSIDE 0 +#define INSIDE 1 + +typedef struct range_struct { + double start; + int start_infinity; /* FALSE (default) or TRUE */ + double end; + int end_infinity; + int alert_on; /* OUTSIDE (default) or INSIDE */ + } range; + +typedef struct thresholds_struct { + range *warning; + range *critical; + } thresholds; + +range *parse_range_string (char *); +int _set_thresholds(thresholds **, char *, char *); +void set_thresholds(thresholds **, char *, char *); +int check_range(double, range *); +int get_status(double, thresholds *); + +char *np_escaped_string (const char *); + +void die (int, const char *, ...) __attribute__((noreturn,format(printf, 2, 3))); diff --git a/lib/utils_disk.c b/lib/utils_disk.c new file mode 100644 index 00000000..fdbeaf1e --- /dev/null +++ b/lib/utils_disk.c @@ -0,0 +1,140 @@ +/**************************************************************************** +* Utils for check_disk +* +* License: GPL +* Copyright (c) 1999-2006 nagios-plugins team +* +* Last Modified: $Date$ +* +* Description: +* +* This file contains utilities for check_disk. These are tested by libtap +* +* License 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 2 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, write to the Free Software +* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +* +* $Id$ +* +*****************************************************************************/ + +#include "common.h" +#include "utils_disk.h" + +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; +} + +/* 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 *) name; + new_path->best_match = NULL; + new_path->name_next = 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; + + if (current == NULL) { + *list = new_path; + } else { + while (current->name_next) { + current = current->name_next; + } + current->name_next = new_path; + } + return new_path; +} + +void +np_set_best_match(struct parameter_list *desired, struct mount_entry *mount_list, int exact) +{ + struct parameter_list *d; + for (d = desired; d; d= d->name_next) { + struct mount_entry *me; + size_t name_len = strlen(d->name); + size_t best_match_len = 0; + struct mount_entry *best_match = NULL; + + for (me = mount_list; me; me = me->me_next) { + size_t len = strlen (me->me_mountdir); + if ((exact == FALSE && (best_match_len <= len && len <= name_len && + (len == 1 || strncmp (me->me_mountdir, d->name, len) == 0))) + || (exact == TRUE && strcmp(me->me_mountdir, d->name)==0)) + { + best_match = me; + best_match_len = len; + } else { + len = strlen (me->me_devname); + if ((exact == FALSE && (best_match_len <= len && len <= name_len && + (len == 1 || strncmp (me->me_devname, d->name, len) == 0))) + || (exact == TRUE && strcmp(me->me_devname, d->name)==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 */ +int +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; +} + +int +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; +} + diff --git a/lib/utils_disk.h b/lib/utils_disk.h new file mode 100644 index 00000000..928fdbe5 --- /dev/null +++ b/lib/utils_disk.h @@ -0,0 +1,32 @@ +/* Header file for utils_disk */ + +#include "mountlist.h" +#include "utils_base.h" + +struct name_list +{ + char *name; + struct name_list *next; +}; + +struct parameter_list +{ + char *name; + int found; + thresholds *freespace_bytes; + thresholds *freespace_units; + thresholds *freespace_percent; + thresholds *usedspace_bytes; + thresholds *usedspace_units; + thresholds *usedspace_percent; + thresholds *usedinodes_percent; + struct mount_entry *best_match; + struct parameter_list *name_next; +}; + +void np_add_name (struct name_list **list, const char *name); +int np_find_name (struct name_list *list, const char *name); +int np_seen_name (struct name_list *list, const char *name); +struct parameter_list *np_add_parameter(struct parameter_list **list, const char *name); +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, int exact); -- cgit v1.2.3-74-g34f1