diff --git a/lib/utils_disk.c b/lib/utils_disk.c index 582d3ea1..f5ac0b30 100644 --- a/lib/utils_disk.c +++ b/lib/utils_disk.c @@ -29,6 +29,7 @@ #include "common.h" #include "utils_disk.h" #include "gl/fsusage.h" +#include void np_add_name (struct name_list **list, const char *name) @@ -40,6 +41,42 @@ np_add_name (struct name_list **list, const char *name) *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) @@ -196,6 +233,30 @@ np_find_name (struct name_list *list, const char *name) 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; +} + int np_seen_name(struct name_list *list, const char *name) { diff --git a/lib/utils_disk.h b/lib/utils_disk.h index 3b5a45f8..6b83ac74 100644 --- a/lib/utils_disk.h +++ b/lib/utils_disk.h @@ -10,6 +10,12 @@ struct name_list struct name_list *next; }; +struct regex_list +{ + regex_t regex; + struct regex_list *next; +}; + struct parameter_list { char *name; @@ -35,6 +41,8 @@ struct parameter_list 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); +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); diff --git a/plugins/check_disk.c b/plugins/check_disk.c index 7dc1c4b1..2f066c7b 100644 --- a/plugins/check_disk.c +++ b/plugins/check_disk.c @@ -93,11 +93,11 @@ static int stat_remote_fs = 0; /* Linked list of filesystem types to omit. If the list is empty, don't exclude any types. */ -static struct name_list *fs_exclude_list; +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 name_list *fs_include_list; +static struct regex_list *fs_include_list; static struct name_list *dp_exclude_list; @@ -300,7 +300,7 @@ main (int argc, char **argv) } else if (me->me_dummy && !show_all_fs) { continue; /* Skip excluded fstypes */ - } else if (fs_exclude_list && np_find_name (fs_exclude_list, me->me_type)) { + } else if (fs_exclude_list && np_find_regmatch (fs_exclude_list, me->me_type)) { continue; /* Skip excluded fs's */ } else if (dp_exclude_list && @@ -308,7 +308,7 @@ main (int argc, char **argv) np_find_name (dp_exclude_list, me->me_mountdir))) { continue; /* Skip not included fstypes */ - } else if (fs_include_list && !np_find_name (fs_include_list, me->me_type)) { + } else if (fs_include_list && !np_find_regmatch(fs_include_list, me->me_type)) { continue; } } @@ -543,7 +543,7 @@ process_arguments (int argc, char **argv) if (argc < 2) return ERROR; - np_add_name(&fs_exclude_list, "iso9660"); + np_add_regex(&fs_exclude_list, "iso9660", REG_EXTENDED); for (c = 1; c < argc; c++) if (strcmp ("-to", argv[c]) == 0) @@ -716,10 +716,18 @@ process_arguments (int argc, char **argv) np_add_name(&dp_exclude_list, optarg); break; case 'X': /* exclude file system type */ - np_add_name(&fs_exclude_list, optarg); + err = np_add_regex(&fs_exclude_list, optarg, REG_EXTENDED); + if (err != 0) { + 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; case 'N': /* include file system type */ - np_add_name(&fs_include_list, optarg); + err = np_add_regex(&fs_include_list, optarg, REG_EXTENDED); + if (err != 0) { + 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; case 'v': /* verbose */ verbose++; @@ -1003,10 +1011,10 @@ print_help (void) printf (" %s\n", "-u, --units=STRING"); printf (" %s\n", _("Choose bytes, kB, MB, GB, TB (default: MB)")); printf (UT_VERBOSE); - printf (" %s\n", "-X, --exclude-type=TYPE"); - printf (" %s\n", _("Ignore all filesystems of indicated type (may be repeated)")); - printf (" %s\n", "-N, --include-type=TYPE"); - printf (" %s\n", _("Check only filesystems of indicated type (may be repeated)")); + 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 ("\n"); printf ("%s\n", _("General usage hints:")); @@ -1037,7 +1045,7 @@ print_usage (void) printf ("%s\n", _("Usage:")); printf (" %s {-w absolute_limit |-w percentage_limit%% | -W inode_percentage_limit } {-c absolute_limit|-c percentage_limit%% | -K inode_percentage_limit } {-p path | -x device}\n", progname); printf ("[-C] [-E] [-e] [-f] [-g group ] [-k] [-l] [-M] [-m] [-R path ] [-r path ]\n"); - printf ("[-t timeout] [-u unit] [-v] [-X type] [-N type]\n"); + printf ("[-t timeout] [-u unit] [-v] [-X type_regex] [-N type]\n"); } bool diff --git a/po/de.po b/po/de.po index 9ea32df9..c25a2b47 100644 --- a/po/de.po +++ b/po/de.po @@ -9,7 +9,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: devel@monitoring-plugins.org\n" -"POT-Creation-Date: 2023-09-22 15:36+0200\n" +"POT-Creation-Date: 2023-10-01 00:46+0200\n" "PO-Revision-Date: 2004-12-23 17:46+0100\n" "Last-Translator: \n" "Language-Team: Monitoring Plugin Development Team \n" "Language-Team: LANGUAGE \n" @@ -291,6 +291,9 @@ msgstr "" msgid "Must set a threshold value before using -p\n" msgstr "" +msgid "Could not compile regular expression" +msgstr "" + msgid "Must set -E before selecting paths\n" msgstr "" @@ -302,9 +305,6 @@ msgid "" "explicitly" msgstr "" -msgid "Could not compile regular expression" -msgstr "" - msgid "" "Must set a threshold value before using -r/-R/-A (--ereg-path/--eregi-path/--" "all)\n" @@ -423,10 +423,13 @@ msgstr "" msgid "Choose bytes, kB, MB, GB, TB (default: MB)" msgstr "" -msgid "Ignore all filesystems of indicated type (may be repeated)" +msgid "" +"Ignore all filesystems of types matching given regex(7) (may be repeated)" msgstr "" -msgid "Check only filesystems of indicated type (may be repeated)" +msgid "" +"Check only filesystems where the type matches this given regex(7) (may be " +"repeated)" msgstr "" msgid "General usage hints:"