diff options
| author | Lorenz Kästle <12514511+RincewindsHat@users.noreply.github.com> | 2025-07-06 22:49:04 +0200 |
|---|---|---|
| committer | Lorenz Kästle <12514511+RincewindsHat@users.noreply.github.com> | 2025-07-06 22:49:04 +0200 |
| commit | 92c7b91002b64187a67463e79ae3d306f5de923c (patch) | |
| tree | 0a167d65d488fd07641789e45c6863e2b982fe43 /lib | |
| parent | bb4ce15997a3023c5c4f2bb434b37699797272da (diff) | |
| parent | e63acdb83d9edcc8c1e244fc34043b4876b74f16 (diff) | |
| download | monitoring-plugins-92c7b91002b64187a67463e79ae3d306f5de923c.tar.gz | |
Merge branch 'master' into refactor/check_load
Diffstat (limited to 'lib')
| -rw-r--r-- | lib/Makefile.am | 3 | ||||
| -rw-r--r-- | lib/output.c | 91 | ||||
| -rw-r--r-- | lib/output.h | 47 | ||||
| -rw-r--r-- | lib/perfdata.c | 91 | ||||
| -rw-r--r-- | lib/perfdata.h | 16 | ||||
| -rw-r--r-- | lib/tests/Makefile.am | 6 | ||||
| -rw-r--r-- | lib/tests/test_disk.c | 192 | ||||
| -rwxr-xr-x | lib/tests/test_disk.t | 6 | ||||
| -rw-r--r-- | lib/thresholds.c | 14 | ||||
| -rw-r--r-- | lib/thresholds.h | 3 | ||||
| -rw-r--r-- | lib/utils_base.c | 18 | ||||
| -rw-r--r-- | lib/utils_cmd.c | 2 | ||||
| -rw-r--r-- | lib/utils_cmd.h | 2 | ||||
| -rw-r--r-- | lib/utils_disk.c | 255 | ||||
| -rw-r--r-- | lib/utils_disk.h | 48 |
15 files changed, 244 insertions, 550 deletions
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 | |||
| 7 | AM_CPPFLAGS = -DNP_STATE_DIR_PREFIX=\"$(localstatedir)\" \ | 7 | AM_CPPFLAGS = -DNP_STATE_DIR_PREFIX=\"$(localstatedir)\" \ |
| 8 | -I$(srcdir) -I$(top_srcdir)/gl -I$(top_srcdir)/intl -I$(top_srcdir)/plugins | 8 | -I$(srcdir) -I$(top_srcdir)/gl -I$(top_srcdir)/intl -I$(top_srcdir)/plugins |
| 9 | 9 | ||
| 10 | 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 | 10 | 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 |
| 11 | 11 | ||
| 12 | EXTRA_DIST = utils_base.h \ | 12 | EXTRA_DIST = utils_base.h \ |
| 13 | utils_disk.h \ | ||
| 14 | utils_tcp.h \ | 13 | utils_tcp.h \ |
| 15 | utils_cmd.h \ | 14 | utils_cmd.h \ |
| 16 | parse_ini.h \ | 15 | parse_ini.h \ |
diff --git a/lib/output.c b/lib/output.c index fbde490e..34ff7dab 100644 --- a/lib/output.c +++ b/lib/output.c | |||
| @@ -13,9 +13,11 @@ | |||
| 13 | 13 | ||
| 14 | // == Global variables | 14 | // == Global variables |
| 15 | static mp_output_format output_format = MP_FORMAT_DEFAULT; | 15 | static mp_output_format output_format = MP_FORMAT_DEFAULT; |
| 16 | static mp_output_detail_level level_of_detail = MP_DETAIL_ALL; | ||
| 16 | 17 | ||
| 17 | // == Prototypes == | 18 | // == Prototypes == |
| 18 | static char *fmt_subcheck_output(mp_output_format output_format, mp_subcheck check, unsigned int indentation); | 19 | static char *fmt_subcheck_output(mp_output_format output_format, mp_subcheck check, |
| 20 | unsigned int indentation); | ||
| 19 | static inline cJSON *json_serialize_subcheck(mp_subcheck subcheck); | 21 | static inline cJSON *json_serialize_subcheck(mp_subcheck subcheck); |
| 20 | 22 | ||
| 21 | // == Implementation == | 23 | // == Implementation == |
| @@ -57,7 +59,9 @@ static inline char *fmt_subcheck_perfdata(mp_subcheck check) { | |||
| 57 | * It sets useful defaults | 59 | * It sets useful defaults |
| 58 | */ | 60 | */ |
| 59 | mp_check mp_check_init(void) { | 61 | mp_check mp_check_init(void) { |
| 60 | mp_check check = {0}; | 62 | mp_check check = { |
| 63 | .evaluation_function = &mp_eval_check_default, | ||
| 64 | }; | ||
| 61 | return check; | 65 | return check; |
| 62 | } | 66 | } |
| 63 | 67 | ||
| @@ -120,7 +124,8 @@ void mp_add_perfdata_to_subcheck(mp_subcheck check[static 1], const mp_perfdata | |||
| 120 | */ | 124 | */ |
| 121 | int mp_add_subcheck_to_subcheck(mp_subcheck check[static 1], mp_subcheck subcheck) { | 125 | int mp_add_subcheck_to_subcheck(mp_subcheck check[static 1], mp_subcheck subcheck) { |
| 122 | if (subcheck.output == NULL) { | 126 | if (subcheck.output == NULL) { |
| 123 | die(STATE_UNKNOWN, "%s - %s #%d: %s", __FILE__, __func__, __LINE__, "Sub check output is NULL"); | 127 | die(STATE_UNKNOWN, "%s - %s #%d: %s", __FILE__, __func__, __LINE__, |
| 128 | "Sub check output is NULL"); | ||
| 124 | } | 129 | } |
| 125 | 130 | ||
| 126 | mp_subcheck_list *tmp = NULL; | 131 | mp_subcheck_list *tmp = NULL; |
| @@ -193,16 +198,33 @@ char *get_subcheck_summary(mp_check check) { | |||
| 193 | return result; | 198 | return result; |
| 194 | } | 199 | } |
| 195 | 200 | ||
| 201 | mp_state_enum mp_compute_subcheck_state(const mp_subcheck subcheck) { | ||
| 202 | if (subcheck.evaluation_function == NULL) { | ||
| 203 | return mp_eval_subcheck_default(subcheck); | ||
| 204 | } | ||
| 205 | return subcheck.evaluation_function(subcheck); | ||
| 206 | } | ||
| 207 | |||
| 196 | /* | 208 | /* |
| 197 | * Generate the result state of a mp_subcheck object based on it's own state and it's subchecks states | 209 | * Generate the result state of a mp_subcheck object based on its own state and its subchecks |
| 210 | * states | ||
| 198 | */ | 211 | */ |
| 199 | mp_state_enum mp_compute_subcheck_state(const mp_subcheck check) { | 212 | mp_state_enum mp_eval_subcheck_default(mp_subcheck subcheck) { |
| 200 | if (check.state_set_explicitly) { | 213 | if (subcheck.evaluation_function != NULL) { |
| 201 | return check.state; | 214 | return subcheck.evaluation_function(subcheck); |
| 202 | } | 215 | } |
| 203 | 216 | ||
| 204 | mp_subcheck_list *scl = check.subchecks; | 217 | if (subcheck.state_set_explicitly) { |
| 205 | mp_state_enum result = check.default_state; | 218 | return subcheck.state; |
| 219 | } | ||
| 220 | |||
| 221 | mp_subcheck_list *scl = subcheck.subchecks; | ||
| 222 | |||
| 223 | if (scl == NULL) { | ||
| 224 | return subcheck.default_state; | ||
| 225 | } | ||
| 226 | |||
| 227 | mp_state_enum result = STATE_OK; | ||
| 206 | 228 | ||
| 207 | while (scl != NULL) { | 229 | while (scl != NULL) { |
| 208 | result = max_state_alt(result, mp_compute_subcheck_state(scl->subcheck)); | 230 | result = max_state_alt(result, mp_compute_subcheck_state(scl->subcheck)); |
| @@ -212,10 +234,18 @@ mp_state_enum mp_compute_subcheck_state(const mp_subcheck check) { | |||
| 212 | return result; | 234 | return result; |
| 213 | } | 235 | } |
| 214 | 236 | ||
| 237 | mp_state_enum mp_compute_check_state(const mp_check check) { | ||
| 238 | // just a safety check | ||
| 239 | if (check.evaluation_function == NULL) { | ||
| 240 | return mp_eval_check_default(check); | ||
| 241 | } | ||
| 242 | return check.evaluation_function(check); | ||
| 243 | } | ||
| 244 | |||
| 215 | /* | 245 | /* |
| 216 | * Generate the result state of a mp_check object based on it's own state and it's subchecks states | 246 | * Generate the result state of a mp_check object based on it's own state and it's subchecks states |
| 217 | */ | 247 | */ |
| 218 | mp_state_enum mp_compute_check_state(const mp_check check) { | 248 | mp_state_enum mp_eval_check_default(const mp_check check) { |
| 219 | assert(check.subchecks != NULL); // a mp_check without subchecks is invalid, die here | 249 | assert(check.subchecks != NULL); // a mp_check without subchecks is invalid, die here |
| 220 | 250 | ||
| 221 | mp_subcheck_list *scl = check.subchecks; | 251 | mp_subcheck_list *scl = check.subchecks; |
| @@ -247,7 +277,11 @@ char *mp_fmt_output(mp_check check) { | |||
| 247 | mp_subcheck_list *subchecks = check.subchecks; | 277 | mp_subcheck_list *subchecks = check.subchecks; |
| 248 | 278 | ||
| 249 | while (subchecks != NULL) { | 279 | while (subchecks != NULL) { |
| 250 | asprintf(&result, "%s\n%s", result, fmt_subcheck_output(MP_FORMAT_MULTI_LINE, subchecks->subcheck, 1)); | 280 | if (level_of_detail == MP_DETAIL_ALL || |
| 281 | mp_compute_subcheck_state(subchecks->subcheck) != STATE_OK) { | ||
| 282 | asprintf(&result, "%s\n%s", result, | ||
| 283 | fmt_subcheck_output(MP_FORMAT_MULTI_LINE, subchecks->subcheck, 1)); | ||
| 284 | } | ||
| 251 | subchecks = subchecks->next; | 285 | subchecks = subchecks->next; |
| 252 | } | 286 | } |
| 253 | 287 | ||
| @@ -258,7 +292,8 @@ char *mp_fmt_output(mp_check check) { | |||
| 258 | if (pd_string == NULL) { | 292 | if (pd_string == NULL) { |
| 259 | asprintf(&pd_string, "%s", fmt_subcheck_perfdata(subchecks->subcheck)); | 293 | asprintf(&pd_string, "%s", fmt_subcheck_perfdata(subchecks->subcheck)); |
| 260 | } else { | 294 | } else { |
| 261 | asprintf(&pd_string, "%s %s", pd_string, fmt_subcheck_perfdata(subchecks->subcheck)); | 295 | asprintf(&pd_string, "%s %s", pd_string, |
| 296 | fmt_subcheck_perfdata(subchecks->subcheck)); | ||
| 262 | } | 297 | } |
| 263 | 298 | ||
| 264 | subchecks = subchecks->next; | 299 | subchecks = subchecks->next; |
| @@ -327,7 +362,8 @@ static char *generate_indentation_string(unsigned int indentation) { | |||
| 327 | /* | 362 | /* |
| 328 | * Helper function to generate the output string of mp_subcheck | 363 | * Helper function to generate the output string of mp_subcheck |
| 329 | */ | 364 | */ |
| 330 | static inline char *fmt_subcheck_output(mp_output_format output_format, mp_subcheck check, unsigned int indentation) { | 365 | static inline char *fmt_subcheck_output(mp_output_format output_format, mp_subcheck check, |
| 366 | unsigned int indentation) { | ||
| 331 | char *result = NULL; | 367 | char *result = NULL; |
| 332 | mp_subcheck_list *subchecks = NULL; | 368 | mp_subcheck_list *subchecks = NULL; |
| 333 | 369 | ||
| @@ -341,7 +377,7 @@ static inline char *fmt_subcheck_output(mp_output_format output_format, mp_subch | |||
| 341 | 377 | ||
| 342 | while (tmp_string != NULL) { | 378 | while (tmp_string != NULL) { |
| 343 | *tmp_string = '\0'; | 379 | *tmp_string = '\0'; |
| 344 | xasprintf(&intermediate_string, "%s%s\n%s", intermediate_string,check.output, generate_indentation_string(indentation+1)); // one more indentation to make it look better | 380 | asprintf(&intermediate_string, "%s%s\n%s", intermediate_string,check.output, generate_indentation_string(indentation+1)); // one more indentation to make it look better |
| 345 | 381 | ||
| 346 | if (*(tmp_string + 1) != '\0') { | 382 | if (*(tmp_string + 1) != '\0') { |
| 347 | check.output = tmp_string + 1; | 383 | check.output = tmp_string + 1; |
| @@ -369,7 +405,8 @@ static inline char *fmt_subcheck_output(mp_output_format output_format, mp_subch | |||
| 369 | subchecks = check.subchecks; | 405 | subchecks = check.subchecks; |
| 370 | 406 | ||
| 371 | while (subchecks != NULL) { | 407 | while (subchecks != NULL) { |
| 372 | asprintf(&result, "%s\n%s", result, fmt_subcheck_output(output_format, subchecks->subcheck, indentation + 1)); | 408 | asprintf(&result, "%s\n%s", result, |
| 409 | fmt_subcheck_output(output_format, subchecks->subcheck, indentation + 1)); | ||
| 373 | subchecks = subchecks->next; | 410 | subchecks = subchecks->next; |
| 374 | } | 411 | } |
| 375 | return result; | 412 | return result; |
| @@ -570,3 +607,27 @@ parsed_output_format mp_parse_output_format(char *format_string) { | |||
| 570 | void mp_set_format(mp_output_format format) { output_format = format; } | 607 | void mp_set_format(mp_output_format format) { output_format = format; } |
| 571 | 608 | ||
| 572 | mp_output_format mp_get_format(void) { return output_format; } | 609 | mp_output_format mp_get_format(void) { return output_format; } |
| 610 | |||
| 611 | void mp_set_level_of_detail(mp_output_detail_level level) { level_of_detail = level; } | ||
| 612 | |||
| 613 | mp_output_detail_level mp_get_level_of_detail(void) { return level_of_detail; } | ||
| 614 | |||
| 615 | mp_state_enum mp_eval_ok(mp_check overall) { | ||
| 616 | (void)overall; | ||
| 617 | return STATE_OK; | ||
| 618 | } | ||
| 619 | |||
| 620 | mp_state_enum mp_eval_warning(mp_check overall) { | ||
| 621 | (void)overall; | ||
| 622 | return STATE_WARNING; | ||
| 623 | } | ||
| 624 | |||
| 625 | mp_state_enum mp_eval_critical(mp_check overall) { | ||
| 626 | (void)overall; | ||
| 627 | return STATE_CRITICAL; | ||
| 628 | } | ||
| 629 | |||
| 630 | mp_state_enum mp_eval_unknown(mp_check overall) { | ||
| 631 | (void)overall; | ||
| 632 | return STATE_UNKNOWN; | ||
| 633 | } | ||
diff --git a/lib/output.h b/lib/output.h index 2bdfa074..c63c8e3f 100644 --- a/lib/output.h +++ b/lib/output.h | |||
| @@ -7,15 +7,21 @@ | |||
| 7 | /* | 7 | /* |
| 8 | * A partial check result | 8 | * A partial check result |
| 9 | */ | 9 | */ |
| 10 | typedef struct { | 10 | typedef struct mp_subcheck mp_subcheck; |
| 11 | struct mp_subcheck { | ||
| 11 | mp_state_enum state; // OK, Warning, Critical ... set explicitly | 12 | mp_state_enum state; // OK, Warning, Critical ... set explicitly |
| 12 | mp_state_enum default_state; // OK, Warning, Critical .. if not set explicitly | 13 | mp_state_enum default_state; // OK, Warning, Critical .. if not set explicitly |
| 13 | bool state_set_explicitly; // was the state set explicitly (or should it be derived from subchecks) | 14 | bool state_set_explicitly; // was the state set explicitly (or should it be derived from |
| 15 | // subchecks) | ||
| 14 | 16 | ||
| 15 | char *output; // Text output for humans ("Filesystem xyz is fine", "Could not create TCP connection to..") | 17 | char *output; // Text output for humans ("Filesystem xyz is fine", "Could not create TCP |
| 16 | pd_list *perfdata; // Performance data for this check | 18 | // connection to..") |
| 19 | pd_list *perfdata; // Performance data for this check | ||
| 17 | struct subcheck_list *subchecks; // subchecks deeper in the hierarchy | 20 | struct subcheck_list *subchecks; // subchecks deeper in the hierarchy |
| 18 | } mp_subcheck; | 21 | |
| 22 | // the evaluation_functions computes the state of subcheck | ||
| 23 | mp_state_enum (*evaluation_function)(mp_subcheck); | ||
| 24 | }; | ||
| 19 | 25 | ||
| 20 | /* | 26 | /* |
| 21 | * A list of subchecks, used in subchecks and the main check | 27 | * A list of subchecks, used in subchecks and the main check |
| @@ -38,8 +44,18 @@ typedef enum output_format { | |||
| 38 | /* | 44 | /* |
| 39 | * Format related functions | 45 | * Format related functions |
| 40 | */ | 46 | */ |
| 41 | void mp_set_format(mp_output_format format); | 47 | void mp_set_format(mp_output_format format); |
| 42 | mp_output_format mp_get_format(void); | 48 | mp_output_format mp_get_format(void); |
| 49 | |||
| 50 | // Output detail level | ||
| 51 | |||
| 52 | typedef enum output_detail_level { | ||
| 53 | MP_DETAIL_ALL, | ||
| 54 | MP_DETAIL_NON_OK_ONLY, | ||
| 55 | } mp_output_detail_level; | ||
| 56 | |||
| 57 | void mp_set_level_of_detail(mp_output_detail_level level); | ||
| 58 | mp_output_detail_level mp_get_level_of_detail(void); | ||
| 43 | 59 | ||
| 44 | /* | 60 | /* |
| 45 | * The main state object of a plugin. Exists only ONCE per plugin. | 61 | * The main state object of a plugin. Exists only ONCE per plugin. |
| @@ -47,10 +63,14 @@ typedef enum output_format { | |||
| 47 | * The final result is always derived from the children and the "worst" state | 63 | * The final result is always derived from the children and the "worst" state |
| 48 | * in the first layer of subchecks | 64 | * in the first layer of subchecks |
| 49 | */ | 65 | */ |
| 50 | typedef struct { | 66 | typedef struct mp_check mp_check; |
| 51 | char *summary; // Overall summary, if not set a summary will be automatically generated | 67 | struct mp_check { |
| 68 | char *summary; // Overall summary, if not set a summary will be automatically generated | ||
| 52 | mp_subcheck_list *subchecks; | 69 | mp_subcheck_list *subchecks; |
| 53 | } mp_check; | 70 | |
| 71 | // the evaluation_functions computes the state of check | ||
| 72 | mp_state_enum (*evaluation_function)(mp_check); | ||
| 73 | }; | ||
| 54 | 74 | ||
| 55 | mp_check mp_check_init(void); | 75 | mp_check mp_check_init(void); |
| 56 | mp_subcheck mp_subcheck_init(void); | 76 | mp_subcheck mp_subcheck_init(void); |
| @@ -68,6 +88,13 @@ void mp_add_summary(mp_check check[static 1], char *summary); | |||
| 68 | mp_state_enum mp_compute_check_state(mp_check); | 88 | mp_state_enum mp_compute_check_state(mp_check); |
| 69 | mp_state_enum mp_compute_subcheck_state(mp_subcheck); | 89 | mp_state_enum mp_compute_subcheck_state(mp_subcheck); |
| 70 | 90 | ||
| 91 | mp_state_enum mp_eval_ok(mp_check overall); | ||
| 92 | mp_state_enum mp_eval_warning(mp_check overall); | ||
| 93 | mp_state_enum mp_eval_critical(mp_check overall); | ||
| 94 | mp_state_enum mp_eval_unknown(mp_check overall); | ||
| 95 | mp_state_enum mp_eval_check_default(mp_check check); | ||
| 96 | mp_state_enum mp_eval_subcheck_default(mp_subcheck subcheck); | ||
| 97 | |||
| 71 | typedef struct { | 98 | typedef struct { |
| 72 | bool parsing_success; | 99 | bool parsing_success; |
| 73 | mp_output_format output_format; | 100 | mp_output_format output_format; |
diff --git a/lib/perfdata.c b/lib/perfdata.c index 661756c5..b87de7e0 100644 --- a/lib/perfdata.c +++ b/lib/perfdata.c | |||
| @@ -33,7 +33,7 @@ char *pd_value_to_string(const mp_perfdata_value pd) { | |||
| 33 | char *pd_to_string(mp_perfdata pd) { | 33 | char *pd_to_string(mp_perfdata pd) { |
| 34 | assert(pd.label != NULL); | 34 | assert(pd.label != NULL); |
| 35 | char *result = NULL; | 35 | char *result = NULL; |
| 36 | asprintf(&result, "%s=", pd.label); | 36 | asprintf(&result, "'%s'=", pd.label); |
| 37 | 37 | ||
| 38 | asprintf(&result, "%s%s", result, pd_value_to_string(pd.value)); | 38 | asprintf(&result, "%s%s", result, pd_value_to_string(pd.value)); |
| 39 | 39 | ||
| @@ -257,6 +257,10 @@ mp_perfdata mp_set_pd_value_double(mp_perfdata pd, double value) { | |||
| 257 | return pd; | 257 | return pd; |
| 258 | } | 258 | } |
| 259 | 259 | ||
| 260 | mp_perfdata mp_set_pd_value_char(mp_perfdata pd, char value) { return mp_set_pd_value_long_long(pd, (long long)value); } | ||
| 261 | |||
| 262 | mp_perfdata mp_set_pd_value_u_char(mp_perfdata pd, unsigned char value) { return mp_set_pd_value_u_long_long(pd, (unsigned long long)value); } | ||
| 263 | |||
| 260 | mp_perfdata mp_set_pd_value_int(mp_perfdata pd, int value) { return mp_set_pd_value_long_long(pd, (long long)value); } | 264 | mp_perfdata mp_set_pd_value_int(mp_perfdata pd, int value) { return mp_set_pd_value_long_long(pd, (long long)value); } |
| 261 | 265 | ||
| 262 | mp_perfdata mp_set_pd_value_u_int(mp_perfdata pd, unsigned int value) { return mp_set_pd_value_u_long_long(pd, (unsigned long long)value); } | 266 | mp_perfdata mp_set_pd_value_u_int(mp_perfdata pd, unsigned int value) { return mp_set_pd_value_u_long_long(pd, (unsigned long long)value); } |
| @@ -288,6 +292,10 @@ mp_perfdata_value mp_create_pd_value_double(double value) { | |||
| 288 | 292 | ||
| 289 | mp_perfdata_value mp_create_pd_value_float(float value) { return mp_create_pd_value_double((double)value); } | 293 | mp_perfdata_value mp_create_pd_value_float(float value) { return mp_create_pd_value_double((double)value); } |
| 290 | 294 | ||
| 295 | mp_perfdata_value mp_create_pd_value_char(char value) { return mp_create_pd_value_long_long((long long)value); } | ||
| 296 | |||
| 297 | mp_perfdata_value mp_create_pd_value_u_char(unsigned char value) { return mp_create_pd_value_u_long_long((unsigned long long)value); } | ||
| 298 | |||
| 291 | mp_perfdata_value mp_create_pd_value_int(int value) { return mp_create_pd_value_long_long((long long)value); } | 299 | mp_perfdata_value mp_create_pd_value_int(int value) { return mp_create_pd_value_long_long((long long)value); } |
| 292 | 300 | ||
| 293 | mp_perfdata_value mp_create_pd_value_u_int(unsigned int value) { return mp_create_pd_value_u_long_long((unsigned long long)value); } | 301 | mp_perfdata_value mp_create_pd_value_u_int(unsigned int value) { return mp_create_pd_value_u_long_long((unsigned long long)value); } |
| @@ -514,3 +522,84 @@ perfdata_value_parser_wrapper parse_pd_value(const char *input) { | |||
| 514 | } | 522 | } |
| 515 | return result; | 523 | return result; |
| 516 | } | 524 | } |
| 525 | |||
| 526 | mp_perfdata mp_set_pd_max_value(mp_perfdata perfdata, mp_perfdata_value value) { | ||
| 527 | perfdata.max = value; | ||
| 528 | perfdata.max_present = true; | ||
| 529 | return perfdata; | ||
| 530 | } | ||
| 531 | |||
| 532 | mp_perfdata mp_set_pd_min_value(mp_perfdata perfdata, mp_perfdata_value value) { | ||
| 533 | perfdata.min = value; | ||
| 534 | perfdata.min_present = true; | ||
| 535 | return perfdata; | ||
| 536 | } | ||
| 537 | |||
| 538 | double mp_get_pd_value(mp_perfdata_value value) { | ||
| 539 | assert(value.type != PD_TYPE_NONE); | ||
| 540 | switch (value.type) { | ||
| 541 | case PD_TYPE_DOUBLE: | ||
| 542 | return value.pd_double; | ||
| 543 | case PD_TYPE_INT: | ||
| 544 | return (double)value.pd_int; | ||
| 545 | case PD_TYPE_UINT: | ||
| 546 | return (double)value.pd_uint; | ||
| 547 | default: | ||
| 548 | return 0; // just to make the compiler happy | ||
| 549 | } | ||
| 550 | } | ||
| 551 | |||
| 552 | mp_perfdata_value mp_pd_value_multiply(mp_perfdata_value left, mp_perfdata_value right) { | ||
| 553 | if (left.type == right.type) { | ||
| 554 | switch (left.type) { | ||
| 555 | case PD_TYPE_DOUBLE: | ||
| 556 | left.pd_double *= right.pd_double; | ||
| 557 | return left; | ||
| 558 | case PD_TYPE_INT: | ||
| 559 | left.pd_int *= right.pd_int; | ||
| 560 | return left; | ||
| 561 | case PD_TYPE_UINT: | ||
| 562 | left.pd_uint *= right.pd_uint; | ||
| 563 | return left; | ||
| 564 | default: | ||
| 565 | // what to here? | ||
| 566 | return left; | ||
| 567 | } | ||
| 568 | } | ||
| 569 | |||
| 570 | // Different types, oh boy, just do the lazy thing for now and switch to double | ||
| 571 | switch (left.type) { | ||
| 572 | case PD_TYPE_INT: | ||
| 573 | left.pd_double = (double)left.pd_int; | ||
| 574 | left.type = PD_TYPE_DOUBLE; | ||
| 575 | break; | ||
| 576 | case PD_TYPE_UINT: | ||
| 577 | left.pd_double = (double)left.pd_uint; | ||
| 578 | left.type = PD_TYPE_DOUBLE; | ||
| 579 | break; | ||
| 580 | } | ||
| 581 | |||
| 582 | switch (right.type) { | ||
| 583 | case PD_TYPE_INT: | ||
| 584 | right.pd_double = (double)right.pd_int; | ||
| 585 | right.type = PD_TYPE_DOUBLE; | ||
| 586 | break; | ||
| 587 | case PD_TYPE_UINT: | ||
| 588 | right.pd_double = (double)right.pd_uint; | ||
| 589 | right.type = PD_TYPE_DOUBLE; | ||
| 590 | break; | ||
| 591 | } | ||
| 592 | |||
| 593 | left.pd_double *= right.pd_double; | ||
| 594 | return left; | ||
| 595 | } | ||
| 596 | |||
| 597 | mp_range mp_range_multiply(mp_range range, mp_perfdata_value factor) { | ||
| 598 | if (!range.end_infinity) { | ||
| 599 | range.end = mp_pd_value_multiply(range.end, factor); | ||
| 600 | } | ||
| 601 | if (!range.start_infinity) { | ||
| 602 | range.start = mp_pd_value_multiply(range.start, factor); | ||
| 603 | } | ||
| 604 | return range; | ||
| 605 | } | ||
diff --git a/lib/perfdata.h b/lib/perfdata.h index 74583ee5..7fd908a9 100644 --- a/lib/perfdata.h +++ b/lib/perfdata.h | |||
| @@ -155,6 +155,8 @@ mp_perfdata mp_set_pd_value_u_long_long(mp_perfdata, unsigned long long); | |||
| 155 | _Generic((V), \ | 155 | _Generic((V), \ |
| 156 | float: mp_create_pd_value_float, \ | 156 | float: mp_create_pd_value_float, \ |
| 157 | double: mp_create_pd_value_double, \ | 157 | double: mp_create_pd_value_double, \ |
| 158 | char: mp_create_pd_value_char, \ | ||
| 159 | unsigned char: mp_create_pd_value_u_char, \ | ||
| 158 | int: mp_create_pd_value_int, \ | 160 | int: mp_create_pd_value_int, \ |
| 159 | unsigned int: mp_create_pd_value_u_int, \ | 161 | unsigned int: mp_create_pd_value_u_int, \ |
| 160 | long: mp_create_pd_value_long, \ | 162 | long: mp_create_pd_value_long, \ |
| @@ -164,6 +166,8 @@ mp_perfdata mp_set_pd_value_u_long_long(mp_perfdata, unsigned long long); | |||
| 164 | 166 | ||
| 165 | mp_perfdata_value mp_create_pd_value_float(float); | 167 | mp_perfdata_value mp_create_pd_value_float(float); |
| 166 | mp_perfdata_value mp_create_pd_value_double(double); | 168 | mp_perfdata_value mp_create_pd_value_double(double); |
| 169 | mp_perfdata_value mp_create_pd_value_char(char); | ||
| 170 | mp_perfdata_value mp_create_pd_value_u_char(unsigned char); | ||
| 167 | mp_perfdata_value mp_create_pd_value_int(int); | 171 | mp_perfdata_value mp_create_pd_value_int(int); |
| 168 | mp_perfdata_value mp_create_pd_value_u_int(unsigned int); | 172 | mp_perfdata_value mp_create_pd_value_u_int(unsigned int); |
| 169 | mp_perfdata_value mp_create_pd_value_long(long); | 173 | mp_perfdata_value mp_create_pd_value_long(long); |
| @@ -171,6 +175,11 @@ mp_perfdata_value mp_create_pd_value_u_long(unsigned long); | |||
| 171 | mp_perfdata_value mp_create_pd_value_long_long(long long); | 175 | mp_perfdata_value mp_create_pd_value_long_long(long long); |
| 172 | mp_perfdata_value mp_create_pd_value_u_long_long(unsigned long long); | 176 | mp_perfdata_value mp_create_pd_value_u_long_long(unsigned long long); |
| 173 | 177 | ||
| 178 | mp_perfdata mp_set_pd_max_value(mp_perfdata perfdata, mp_perfdata_value value); | ||
| 179 | mp_perfdata mp_set_pd_min_value(mp_perfdata perfdata, mp_perfdata_value value); | ||
| 180 | |||
| 181 | double mp_get_pd_value(mp_perfdata_value value); | ||
| 182 | |||
| 174 | /* | 183 | /* |
| 175 | * Free the memory used by a pd_list | 184 | * Free the memory used by a pd_list |
| 176 | */ | 185 | */ |
| @@ -178,6 +187,13 @@ void pd_list_free(pd_list[1]); | |||
| 178 | 187 | ||
| 179 | int cmp_perfdata_value(mp_perfdata_value, mp_perfdata_value); | 188 | int cmp_perfdata_value(mp_perfdata_value, mp_perfdata_value); |
| 180 | 189 | ||
| 190 | // ================ | ||
| 191 | // Helper functions | ||
| 192 | // ================ | ||
| 193 | |||
| 194 | mp_perfdata_value mp_pd_value_multiply(mp_perfdata_value left, mp_perfdata_value right); | ||
| 195 | mp_range mp_range_multiply(mp_range range, mp_perfdata_value factor); | ||
| 196 | |||
| 181 | // ================= | 197 | // ================= |
| 182 | // String formatters | 198 | // String formatters |
| 183 | // ================= | 199 | // ================= |
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@ | |||
| 8 | AM_CPPFLAGS = -DNP_STATE_DIR_PREFIX=\"$(localstatedir)\" \ | 8 | AM_CPPFLAGS = -DNP_STATE_DIR_PREFIX=\"$(localstatedir)\" \ |
| 9 | -I$(top_srcdir)/lib -I$(top_srcdir)/gl -I$(top_srcdir)/intl -I$(top_srcdir)/plugins | 9 | -I$(top_srcdir)/lib -I$(top_srcdir)/gl -I$(top_srcdir)/intl -I$(top_srcdir)/plugins |
| 10 | 10 | ||
| 11 | 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 | 11 | EXTRA_PROGRAMS = test_utils test_tcp test_cmd test_base64 test_ini1 test_ini3 test_opts1 test_opts2 test_opts3 test_generic_output |
| 12 | 12 | ||
| 13 | 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 | 13 | 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 |
| 14 | np_test_files = config-dos.ini config-opts.ini config-tiny.ini plugin.ini plugins.ini | 14 | np_test_files = config-dos.ini config-opts.ini config-tiny.ini plugin.ini plugins.ini |
| 15 | EXTRA_DIST = $(np_test_scripts) $(np_test_files) var | 15 | EXTRA_DIST = $(np_test_scripts) $(np_test_files) var |
| 16 | 16 | ||
| @@ -29,7 +29,7 @@ AM_CFLAGS = -g -I$(top_srcdir)/lib -I$(top_srcdir)/gl $(tap_cflags) | |||
| 29 | AM_LDFLAGS = $(tap_ldflags) -ltap | 29 | AM_LDFLAGS = $(tap_ldflags) -ltap |
| 30 | LDADD = $(top_srcdir)/lib/libmonitoringplug.a $(top_srcdir)/gl/libgnu.a $(LIB_CRYPTO) | 30 | LDADD = $(top_srcdir)/lib/libmonitoringplug.a $(top_srcdir)/gl/libgnu.a $(LIB_CRYPTO) |
| 31 | 31 | ||
| 32 | 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 | 32 | 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 |
| 33 | 33 | ||
| 34 | test: ${noinst_PROGRAMS} | 34 | test: ${noinst_PROGRAMS} |
| 35 | perl -MTest::Harness -e '$$Test::Harness::switches=""; runtests(map {$$_ .= ".t"} @ARGV)' $(EXTRA_PROGRAMS) | 35 | 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 @@ | |||
| 1 | /***************************************************************************** | ||
| 2 | * | ||
| 3 | * This program is free software: you can redistribute it and/or modify | ||
| 4 | * it under the terms of the GNU General Public License as published by | ||
| 5 | * the Free Software Foundation, either version 3 of the License, or | ||
| 6 | * (at your option) any later version. | ||
| 7 | * | ||
| 8 | * This program is distributed in the hope that it will be useful, | ||
| 9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 11 | * GNU General Public License for more details. | ||
| 12 | * | ||
| 13 | * You should have received a copy of the GNU General Public License | ||
| 14 | * along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
| 15 | * | ||
| 16 | * | ||
| 17 | *****************************************************************************/ | ||
| 18 | |||
| 19 | #include "common.h" | ||
| 20 | #include "utils_disk.h" | ||
| 21 | #include "tap.h" | ||
| 22 | #include "regex.h" | ||
| 23 | |||
| 24 | void np_test_mount_entry_regex(struct mount_entry *dummy_mount_list, char *regstr, int cflags, int expect, char *desc); | ||
| 25 | |||
| 26 | int main(int argc, char **argv) { | ||
| 27 | struct name_list *exclude_filesystem = NULL; | ||
| 28 | struct name_list *exclude_fstype = NULL; | ||
| 29 | struct name_list *dummy_mountlist = NULL; | ||
| 30 | struct name_list *temp_name; | ||
| 31 | struct parameter_list *paths = NULL; | ||
| 32 | struct parameter_list *p, *prev = NULL, *last = NULL; | ||
| 33 | |||
| 34 | struct mount_entry *dummy_mount_list; | ||
| 35 | struct mount_entry *me; | ||
| 36 | struct mount_entry **mtail = &dummy_mount_list; | ||
| 37 | int cflags = REG_NOSUB | REG_EXTENDED; | ||
| 38 | int found = 0, count = 0; | ||
| 39 | |||
| 40 | plan_tests(33); | ||
| 41 | |||
| 42 | ok(np_find_name(exclude_filesystem, "/var/log") == false, "/var/log not in list"); | ||
| 43 | np_add_name(&exclude_filesystem, "/var/log"); | ||
| 44 | ok(np_find_name(exclude_filesystem, "/var/log") == true, "is in list now"); | ||
| 45 | ok(np_find_name(exclude_filesystem, "/home") == false, "/home not in list"); | ||
| 46 | np_add_name(&exclude_filesystem, "/home"); | ||
| 47 | ok(np_find_name(exclude_filesystem, "/home") == true, "is in list now"); | ||
| 48 | ok(np_find_name(exclude_filesystem, "/var/log") == true, "/var/log still in list"); | ||
| 49 | |||
| 50 | ok(np_find_name(exclude_fstype, "iso9660") == false, "iso9660 not in list"); | ||
| 51 | np_add_name(&exclude_fstype, "iso9660"); | ||
| 52 | ok(np_find_name(exclude_fstype, "iso9660") == true, "is in list now"); | ||
| 53 | |||
| 54 | ok(np_find_name(exclude_filesystem, "iso9660") == false, "Make sure no clashing in variables"); | ||
| 55 | |||
| 56 | /* | ||
| 57 | for (temp_name = exclude_filesystem; temp_name; temp_name = temp_name->next) { | ||
| 58 | printf("Name: %s\n", temp_name->name); | ||
| 59 | } | ||
| 60 | */ | ||
| 61 | |||
| 62 | me = (struct mount_entry *)malloc(sizeof *me); | ||
| 63 | me->me_devname = strdup("/dev/c0t0d0s0"); | ||
| 64 | me->me_mountdir = strdup("/"); | ||
| 65 | *mtail = me; | ||
| 66 | mtail = &me->me_next; | ||
| 67 | |||
| 68 | me = (struct mount_entry *)malloc(sizeof *me); | ||
| 69 | me->me_devname = strdup("/dev/c1t0d1s0"); | ||
| 70 | me->me_mountdir = strdup("/var"); | ||
| 71 | *mtail = me; | ||
| 72 | mtail = &me->me_next; | ||
| 73 | |||
| 74 | me = (struct mount_entry *)malloc(sizeof *me); | ||
| 75 | me->me_devname = strdup("/dev/c2t0d0s0"); | ||
| 76 | me->me_mountdir = strdup("/home"); | ||
| 77 | *mtail = me; | ||
| 78 | mtail = &me->me_next; | ||
| 79 | |||
| 80 | np_test_mount_entry_regex(dummy_mount_list, strdup("/"), cflags, 3, strdup("a")); | ||
| 81 | np_test_mount_entry_regex(dummy_mount_list, strdup("/dev"), cflags, 3, strdup("regex on dev names:")); | ||
| 82 | np_test_mount_entry_regex(dummy_mount_list, strdup("/foo"), cflags, 0, strdup("regex on non existent dev/path:")); | ||
| 83 | np_test_mount_entry_regex(dummy_mount_list, strdup("/Foo"), cflags | REG_ICASE, 0, strdup("regi on non existent dev/path:")); | ||
| 84 | np_test_mount_entry_regex(dummy_mount_list, strdup("/c.t0"), cflags, 3, strdup("partial devname regex match:")); | ||
| 85 | np_test_mount_entry_regex(dummy_mount_list, strdup("c0t0"), cflags, 1, strdup("partial devname regex match:")); | ||
| 86 | np_test_mount_entry_regex(dummy_mount_list, strdup("C0t0"), cflags | REG_ICASE, 1, strdup("partial devname regi match:")); | ||
| 87 | np_test_mount_entry_regex(dummy_mount_list, strdup("home"), cflags, 1, strdup("partial pathname regex match:")); | ||
| 88 | np_test_mount_entry_regex(dummy_mount_list, strdup("hOme"), cflags | REG_ICASE, 1, strdup("partial pathname regi match:")); | ||
| 89 | np_test_mount_entry_regex(dummy_mount_list, strdup("(/home)|(/var)"), cflags, 2, strdup("grouped regex pathname match:")); | ||
| 90 | np_test_mount_entry_regex(dummy_mount_list, strdup("(/homE)|(/Var)"), cflags | REG_ICASE, 2, strdup("grouped regi pathname match:")); | ||
| 91 | |||
| 92 | np_add_parameter(&paths, "/home/groups"); | ||
| 93 | np_add_parameter(&paths, "/var"); | ||
| 94 | np_add_parameter(&paths, "/tmp"); | ||
| 95 | np_add_parameter(&paths, "/home/tonvoon"); | ||
| 96 | np_add_parameter(&paths, "/dev/c2t0d0s0"); | ||
| 97 | |||
| 98 | np_set_best_match(paths, dummy_mount_list, false); | ||
| 99 | for (p = paths; p; p = p->name_next) { | ||
| 100 | struct mount_entry *temp_me; | ||
| 101 | temp_me = p->best_match; | ||
| 102 | if (!strcmp(p->name, "/home/groups")) { | ||
| 103 | ok(temp_me && !strcmp(temp_me->me_mountdir, "/home"), "/home/groups got right best match: /home"); | ||
| 104 | } else if (!strcmp(p->name, "/var")) { | ||
| 105 | ok(temp_me && !strcmp(temp_me->me_mountdir, "/var"), "/var got right best match: /var"); | ||
| 106 | } else if (!strcmp(p->name, "/tmp")) { | ||
| 107 | ok(temp_me && !strcmp(temp_me->me_mountdir, "/"), "/tmp got right best match: /"); | ||
| 108 | } else if (!strcmp(p->name, "/home/tonvoon")) { | ||
| 109 | ok(temp_me && !strcmp(temp_me->me_mountdir, "/home"), "/home/tonvoon got right best match: /home"); | ||
| 110 | } else if (!strcmp(p->name, "/dev/c2t0d0s0")) { | ||
| 111 | ok(temp_me && !strcmp(temp_me->me_devname, "/dev/c2t0d0s0"), "/dev/c2t0d0s0 got right best match: /dev/c2t0d0s0"); | ||
| 112 | } | ||
| 113 | } | ||
| 114 | |||
| 115 | paths = NULL; /* Bad boy - should free, but this is a test suite */ | ||
| 116 | np_add_parameter(&paths, "/home/groups"); | ||
| 117 | np_add_parameter(&paths, "/var"); | ||
| 118 | np_add_parameter(&paths, "/tmp"); | ||
| 119 | np_add_parameter(&paths, "/home/tonvoon"); | ||
| 120 | np_add_parameter(&paths, "/home"); | ||
| 121 | |||
| 122 | np_set_best_match(paths, dummy_mount_list, true); | ||
| 123 | for (p = paths; p; p = p->name_next) { | ||
| 124 | if (!strcmp(p->name, "/home/groups")) { | ||
| 125 | ok(!p->best_match, "/home/groups correctly not found"); | ||
| 126 | } else if (!strcmp(p->name, "/var")) { | ||
| 127 | ok(p->best_match, "/var found"); | ||
| 128 | } else if (!strcmp(p->name, "/tmp")) { | ||
| 129 | ok(!p->best_match, "/tmp correctly not found"); | ||
| 130 | } else if (!strcmp(p->name, "/home/tonvoon")) { | ||
| 131 | ok(!p->best_match, "/home/tonvoon not found"); | ||
| 132 | } else if (!strcmp(p->name, "/home")) { | ||
| 133 | ok(p->best_match, "/home found"); | ||
| 134 | } | ||
| 135 | } | ||
| 136 | |||
| 137 | /* test deleting first element in paths */ | ||
| 138 | paths = np_del_parameter(paths, NULL); | ||
| 139 | for (p = paths; p; p = p->name_next) { | ||
| 140 | if (!strcmp(p->name, "/home/groups")) | ||
| 141 | found = 1; | ||
| 142 | } | ||
| 143 | ok(found == 0, "first element successfully deleted"); | ||
| 144 | found = 0; | ||
| 145 | |||
| 146 | p = paths; | ||
| 147 | while (p) { | ||
| 148 | if (!strcmp(p->name, "/tmp")) | ||
| 149 | p = np_del_parameter(p, prev); | ||
| 150 | else { | ||
| 151 | prev = p; | ||
| 152 | p = p->name_next; | ||
| 153 | } | ||
| 154 | } | ||
| 155 | |||
| 156 | for (p = paths; p; p = p->name_next) { | ||
| 157 | if (!strcmp(p->name, "/tmp")) | ||
| 158 | found = 1; | ||
| 159 | if (p->name_next) | ||
| 160 | prev = p; | ||
| 161 | else | ||
| 162 | last = p; | ||
| 163 | } | ||
| 164 | ok(found == 0, "/tmp element successfully deleted"); | ||
| 165 | |||
| 166 | p = np_del_parameter(last, prev); | ||
| 167 | for (p = paths; p; p = p->name_next) { | ||
| 168 | if (!strcmp(p->name, "/home")) | ||
| 169 | found = 1; | ||
| 170 | last = p; | ||
| 171 | count++; | ||
| 172 | } | ||
| 173 | ok(found == 0, "last (/home) element successfully deleted"); | ||
| 174 | ok(count == 2, "two elements remaining"); | ||
| 175 | |||
| 176 | return exit_status(); | ||
| 177 | } | ||
| 178 | |||
| 179 | void np_test_mount_entry_regex(struct mount_entry *dummy_mount_list, char *regstr, int cflags, int expect, char *desc) { | ||
| 180 | int matches = 0; | ||
| 181 | regex_t re; | ||
| 182 | struct mount_entry *me; | ||
| 183 | if (regcomp(&re, regstr, cflags) == 0) { | ||
| 184 | for (me = dummy_mount_list; me; me = me->me_next) { | ||
| 185 | if (np_regex_match_mount_entry(me, &re)) | ||
| 186 | matches++; | ||
| 187 | } | ||
| 188 | ok(matches == expect, "%s '%s' matched %i/3 entries. ok: %i/3", desc, regstr, expect, matches); | ||
| 189 | |||
| 190 | } else | ||
| 191 | ok(false, "regex '%s' not compilable", regstr); | ||
| 192 | } | ||
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 @@ | |||
| 1 | #!/usr/bin/perl | ||
| 2 | use Test::More; | ||
| 3 | if (! -e "./test_disk") { | ||
| 4 | plan skip_all => "./test_disk not compiled - please enable libtap library to test"; | ||
| 5 | } | ||
| 6 | exec "./test_disk"; | ||
diff --git a/lib/thresholds.c b/lib/thresholds.c index ddefae37..de2b9315 100644 --- a/lib/thresholds.c +++ b/lib/thresholds.c | |||
| @@ -51,9 +51,21 @@ mp_state_enum mp_get_pd_status(mp_perfdata perfdata) { | |||
| 51 | } | 51 | } |
| 52 | if (perfdata.warn_present) { | 52 | if (perfdata.warn_present) { |
| 53 | if (mp_check_range(perfdata.value, perfdata.warn)) { | 53 | if (mp_check_range(perfdata.value, perfdata.warn)) { |
| 54 | return STATE_CRITICAL; | 54 | return STATE_WARNING; |
| 55 | } | 55 | } |
| 56 | } | 56 | } |
| 57 | 57 | ||
| 58 | return STATE_OK; | 58 | return STATE_OK; |
| 59 | } | 59 | } |
| 60 | |||
| 61 | mp_thresholds mp_thresholds_set_warn(mp_thresholds thlds, mp_range warn) { | ||
| 62 | thlds.warning = warn; | ||
| 63 | thlds.warning_is_set = true; | ||
| 64 | return thlds; | ||
| 65 | } | ||
| 66 | |||
| 67 | mp_thresholds mp_thresholds_set_crit(mp_thresholds thlds, mp_range crit) { | ||
| 68 | thlds.critical = crit; | ||
| 69 | thlds.critical_is_set = true; | ||
| 70 | return thlds; | ||
| 71 | } | ||
diff --git a/lib/thresholds.h b/lib/thresholds.h index 4e7defee..5f9f9247 100644 --- a/lib/thresholds.h +++ b/lib/thresholds.h | |||
| @@ -24,5 +24,8 @@ mp_perfdata mp_pd_set_thresholds(mp_perfdata /* pd */, mp_thresholds /* th */); | |||
| 24 | 24 | ||
| 25 | mp_state_enum mp_get_pd_status(mp_perfdata /* pd */); | 25 | mp_state_enum mp_get_pd_status(mp_perfdata /* pd */); |
| 26 | 26 | ||
| 27 | mp_thresholds mp_thresholds_set_warn(mp_thresholds thlds, mp_range warn); | ||
| 28 | mp_thresholds mp_thresholds_set_crit(mp_thresholds thlds, mp_range crit); | ||
| 29 | |||
| 27 | char *fmt_threshold_warning(thresholds th); | 30 | char *fmt_threshold_warning(thresholds th); |
| 28 | char *fmt_threshold_critical(thresholds th); | 31 | char *fmt_threshold_critical(thresholds th); |
diff --git a/lib/utils_base.c b/lib/utils_base.c index ff9540c7..c49a473f 100644 --- a/lib/utils_base.c +++ b/lib/utils_base.c | |||
| @@ -225,27 +225,15 @@ bool mp_check_range(const mp_perfdata_value value, const mp_range my_range) { | |||
| 225 | if (my_range.end_infinity == false && my_range.start_infinity == false) { | 225 | if (my_range.end_infinity == false && my_range.start_infinity == false) { |
| 226 | // range: .........|---inside---|........... | 226 | // range: .........|---inside---|........... |
| 227 | // value | 227 | // value |
| 228 | if ((cmp_perfdata_value(my_range.start, value) < 1) && (cmp_perfdata_value(value, my_range.end) <= 0)) { | 228 | is_inside = ((cmp_perfdata_value(my_range.start, value) < 1) && (cmp_perfdata_value(value, my_range.end) <= 0)); |
| 229 | is_inside = true; | ||
| 230 | } else { | ||
| 231 | is_inside = false; | ||
| 232 | } | ||
| 233 | } else if (my_range.start_infinity == false && my_range.end_infinity == true) { | 229 | } else if (my_range.start_infinity == false && my_range.end_infinity == true) { |
| 234 | // range: .........|---inside--------- | 230 | // range: .........|---inside--------- |
| 235 | // value | 231 | // value |
| 236 | if (cmp_perfdata_value(my_range.start, value) < 0) { | 232 | is_inside = (cmp_perfdata_value(my_range.start, value) < 0); |
| 237 | is_inside = true; | ||
| 238 | } else { | ||
| 239 | is_inside = false; | ||
| 240 | } | ||
| 241 | } else if (my_range.start_infinity == true && my_range.end_infinity == false) { | 233 | } else if (my_range.start_infinity == true && my_range.end_infinity == false) { |
| 242 | // range: -inside--------|.................... | 234 | // range: -inside--------|.................... |
| 243 | // value | 235 | // value |
| 244 | if (cmp_perfdata_value(value, my_range.end) == -1) { | 236 | is_inside = (cmp_perfdata_value(value, my_range.end) == -1); |
| 245 | is_inside = true; | ||
| 246 | } else { | ||
| 247 | is_inside = false; | ||
| 248 | } | ||
| 249 | } else { | 237 | } else { |
| 250 | // range from -inf to inf, so always inside | 238 | // range from -inf to inf, so always inside |
| 251 | is_inside = true; | 239 | is_inside = true; |
diff --git a/lib/utils_cmd.c b/lib/utils_cmd.c index 18350ac0..9b222409 100644 --- a/lib/utils_cmd.c +++ b/lib/utils_cmd.c | |||
| @@ -346,7 +346,7 @@ int cmd_run_array(char *const *argv, output *out, output *err, int flags) { | |||
| 346 | return _cmd_close(fd); | 346 | return _cmd_close(fd); |
| 347 | } | 347 | } |
| 348 | 348 | ||
| 349 | int cmd_file_read(char *filename, output *out, int flags) { | 349 | int cmd_file_read(const char *filename, output *out, int flags) { |
| 350 | int fd; | 350 | int fd; |
| 351 | if (out) | 351 | if (out) |
| 352 | memset(out, 0, sizeof(output)); | 352 | memset(out, 0, sizeof(output)); |
diff --git a/lib/utils_cmd.h b/lib/utils_cmd.h index d00069c9..728ece23 100644 --- a/lib/utils_cmd.h +++ b/lib/utils_cmd.h | |||
| @@ -20,7 +20,7 @@ typedef struct output output; | |||
| 20 | /** prototypes **/ | 20 | /** prototypes **/ |
| 21 | int cmd_run(const char *, output *, output *, int); | 21 | int cmd_run(const char *, output *, output *, int); |
| 22 | int cmd_run_array(char *const *, output *, output *, int); | 22 | int cmd_run_array(char *const *, output *, output *, int); |
| 23 | int cmd_file_read(char *, output *, int); | 23 | int cmd_file_read(const char *, output *, int); |
| 24 | 24 | ||
| 25 | /* only multi-threaded plugins need to bother with this */ | 25 | /* only multi-threaded plugins need to bother with this */ |
| 26 | void cmd_init(void); | 26 | void cmd_init(void); |
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 @@ | |||
| 1 | /***************************************************************************** | ||
| 2 | * | ||
| 3 | * Library for check_disk | ||
| 4 | * | ||
| 5 | * License: GPL | ||
| 6 | * Copyright (c) 1999-2024 Monitoring Plugins Development Team | ||
| 7 | * | ||
| 8 | * Description: | ||
| 9 | * | ||
| 10 | * This file contains utilities for check_disk. These are tested by libtap | ||
| 11 | * | ||
| 12 | * | ||
| 13 | * This program is free software: you can redistribute it and/or modify | ||
| 14 | * it under the terms of the GNU General Public License as published by | ||
| 15 | * the Free Software Foundation, either version 3 of the License, or | ||
| 16 | * (at your option) any later version. | ||
| 17 | * | ||
| 18 | * This program is distributed in the hope that it will be useful, | ||
| 19 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 20 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 21 | * GNU General Public License for more details. | ||
| 22 | * | ||
| 23 | * You should have received a copy of the GNU General Public License | ||
| 24 | * along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
| 25 | * | ||
| 26 | * | ||
| 27 | *****************************************************************************/ | ||
| 28 | |||
| 29 | #include "common.h" | ||
| 30 | #include "utils_disk.h" | ||
| 31 | #include "gl/fsusage.h" | ||
| 32 | #include <string.h> | ||
| 33 | |||
| 34 | void np_add_name(struct name_list **list, const char *name) { | ||
| 35 | struct name_list *new_entry; | ||
| 36 | new_entry = (struct name_list *)malloc(sizeof *new_entry); | ||
| 37 | new_entry->name = (char *)name; | ||
| 38 | new_entry->next = *list; | ||
| 39 | *list = new_entry; | ||
| 40 | } | ||
| 41 | |||
| 42 | /* @brief Initialises a new regex at the begin of list via regcomp(3) | ||
| 43 | * | ||
| 44 | * @details if the regex fails to compile the error code of regcomp(3) is returned | ||
| 45 | * and list is not modified, otherwise list is modified to point to the new | ||
| 46 | * element | ||
| 47 | * @param list Pointer to a linked list of regex_list elements | ||
| 48 | * @param regex the string containing the regex which should be inserted into the list | ||
| 49 | * @param clags the cflags parameter for regcomp(3) | ||
| 50 | */ | ||
| 51 | int np_add_regex(struct regex_list **list, const char *regex, int cflags) { | ||
| 52 | struct regex_list *new_entry = (struct regex_list *)malloc(sizeof *new_entry); | ||
| 53 | |||
| 54 | if (new_entry == NULL) { | ||
| 55 | die(STATE_UNKNOWN, _("Cannot allocate memory: %s"), strerror(errno)); | ||
| 56 | } | ||
| 57 | |||
| 58 | int regcomp_result = regcomp(&new_entry->regex, regex, cflags); | ||
| 59 | |||
| 60 | if (!regcomp_result) { | ||
| 61 | // regcomp succeeded | ||
| 62 | new_entry->next = *list; | ||
| 63 | *list = new_entry; | ||
| 64 | |||
| 65 | return 0; | ||
| 66 | } else { | ||
| 67 | // regcomp failed | ||
| 68 | free(new_entry); | ||
| 69 | |||
| 70 | return regcomp_result; | ||
| 71 | } | ||
| 72 | } | ||
| 73 | |||
| 74 | /* Initialises a new parameter at the end of list */ | ||
| 75 | struct parameter_list *np_add_parameter(struct parameter_list **list, const char *name) { | ||
| 76 | struct parameter_list *current = *list; | ||
| 77 | struct parameter_list *new_path; | ||
| 78 | new_path = (struct parameter_list *)malloc(sizeof *new_path); | ||
| 79 | new_path->name = (char *)malloc(strlen(name) + 1); | ||
| 80 | new_path->best_match = NULL; | ||
| 81 | new_path->name_next = NULL; | ||
| 82 | new_path->name_prev = NULL; | ||
| 83 | new_path->freespace_bytes = NULL; | ||
| 84 | new_path->freespace_units = NULL; | ||
| 85 | new_path->freespace_percent = NULL; | ||
| 86 | new_path->usedspace_bytes = NULL; | ||
| 87 | new_path->usedspace_units = NULL; | ||
| 88 | new_path->usedspace_percent = NULL; | ||
| 89 | new_path->usedinodes_percent = NULL; | ||
| 90 | new_path->freeinodes_percent = NULL; | ||
| 91 | new_path->group = NULL; | ||
| 92 | new_path->dfree_pct = -1; | ||
| 93 | new_path->dused_pct = -1; | ||
| 94 | new_path->total = 0; | ||
| 95 | new_path->available = 0; | ||
| 96 | new_path->available_to_root = 0; | ||
| 97 | new_path->used = 0; | ||
| 98 | new_path->dused_units = 0; | ||
| 99 | new_path->dfree_units = 0; | ||
| 100 | new_path->dtotal_units = 0; | ||
| 101 | new_path->inodes_total = 0; | ||
| 102 | new_path->inodes_free = 0; | ||
| 103 | new_path->inodes_free_to_root = 0; | ||
| 104 | new_path->inodes_used = 0; | ||
| 105 | new_path->dused_inodes_percent = 0; | ||
| 106 | new_path->dfree_inodes_percent = 0; | ||
| 107 | |||
| 108 | strcpy(new_path->name, name); | ||
| 109 | |||
| 110 | if (current == NULL) { | ||
| 111 | *list = new_path; | ||
| 112 | new_path->name_prev = NULL; | ||
| 113 | } else { | ||
| 114 | while (current->name_next) { | ||
| 115 | current = current->name_next; | ||
| 116 | } | ||
| 117 | current->name_next = new_path; | ||
| 118 | new_path->name_prev = current; | ||
| 119 | } | ||
| 120 | return new_path; | ||
| 121 | } | ||
| 122 | |||
| 123 | /* Delete a given parameter from list and return pointer to next element*/ | ||
| 124 | struct parameter_list *np_del_parameter(struct parameter_list *item, struct parameter_list *prev) { | ||
| 125 | if (item == NULL) { | ||
| 126 | return NULL; | ||
| 127 | } | ||
| 128 | struct parameter_list *next; | ||
| 129 | |||
| 130 | if (item->name_next) | ||
| 131 | next = item->name_next; | ||
| 132 | else | ||
| 133 | next = NULL; | ||
| 134 | |||
| 135 | if (next) | ||
| 136 | next->name_prev = prev; | ||
| 137 | |||
| 138 | if (prev) | ||
| 139 | prev->name_next = next; | ||
| 140 | |||
| 141 | if (item->name) { | ||
| 142 | free(item->name); | ||
| 143 | } | ||
| 144 | free(item); | ||
| 145 | |||
| 146 | return next; | ||
| 147 | } | ||
| 148 | |||
| 149 | /* returns a pointer to the struct found in the list */ | ||
| 150 | struct parameter_list *np_find_parameter(struct parameter_list *list, const char *name) { | ||
| 151 | struct parameter_list *temp_list; | ||
| 152 | for (temp_list = list; temp_list; temp_list = temp_list->name_next) { | ||
| 153 | if (!strcmp(temp_list->name, name)) | ||
| 154 | return temp_list; | ||
| 155 | } | ||
| 156 | |||
| 157 | return NULL; | ||
| 158 | } | ||
| 159 | |||
| 160 | void np_set_best_match(struct parameter_list *desired, struct mount_entry *mount_list, bool exact) { | ||
| 161 | struct parameter_list *d; | ||
| 162 | for (d = desired; d; d = d->name_next) { | ||
| 163 | if (!d->best_match) { | ||
| 164 | struct mount_entry *me; | ||
| 165 | size_t name_len = strlen(d->name); | ||
| 166 | size_t best_match_len = 0; | ||
| 167 | struct mount_entry *best_match = NULL; | ||
| 168 | struct fs_usage fsp; | ||
| 169 | |||
| 170 | /* set best match if path name exactly matches a mounted device name */ | ||
| 171 | for (me = mount_list; me; me = me->me_next) { | ||
| 172 | if (strcmp(me->me_devname, d->name) == 0) { | ||
| 173 | if (get_fs_usage(me->me_mountdir, me->me_devname, &fsp) >= 0) { | ||
| 174 | best_match = me; | ||
| 175 | } | ||
| 176 | } | ||
| 177 | } | ||
| 178 | |||
| 179 | /* set best match by directory name if no match was found by devname */ | ||
| 180 | if (!best_match) { | ||
| 181 | for (me = mount_list; me; me = me->me_next) { | ||
| 182 | size_t len = strlen(me->me_mountdir); | ||
| 183 | if ((!exact && | ||
| 184 | (best_match_len <= len && len <= name_len && (len == 1 || strncmp(me->me_mountdir, d->name, len) == 0))) || | ||
| 185 | (exact && strcmp(me->me_mountdir, d->name) == 0)) { | ||
| 186 | if (get_fs_usage(me->me_mountdir, me->me_devname, &fsp) >= 0) { | ||
| 187 | best_match = me; | ||
| 188 | best_match_len = len; | ||
| 189 | } | ||
| 190 | } | ||
| 191 | } | ||
| 192 | } | ||
| 193 | |||
| 194 | if (best_match) { | ||
| 195 | d->best_match = best_match; | ||
| 196 | } else { | ||
| 197 | d->best_match = NULL; /* Not sure why this is needed as it should be null on initialisation */ | ||
| 198 | } | ||
| 199 | } | ||
| 200 | } | ||
| 201 | } | ||
| 202 | |||
| 203 | /* Returns true if name is in list */ | ||
| 204 | bool np_find_name(struct name_list *list, const char *name) { | ||
| 205 | const struct name_list *n; | ||
| 206 | |||
| 207 | if (list == NULL || name == NULL) { | ||
| 208 | return false; | ||
| 209 | } | ||
| 210 | for (n = list; n; n = n->next) { | ||
| 211 | if (!strcmp(name, n->name)) { | ||
| 212 | return true; | ||
| 213 | } | ||
| 214 | } | ||
| 215 | return false; | ||
| 216 | } | ||
| 217 | |||
| 218 | /* Returns true if name is in list */ | ||
| 219 | bool np_find_regmatch(struct regex_list *list, const char *name) { | ||
| 220 | int len; | ||
| 221 | regmatch_t m; | ||
| 222 | |||
| 223 | if (name == NULL) { | ||
| 224 | return false; | ||
| 225 | } | ||
| 226 | |||
| 227 | len = strlen(name); | ||
| 228 | |||
| 229 | for (; list; list = list->next) { | ||
| 230 | /* Emulate a full match as if surrounded with ^( )$ | ||
| 231 | by checking whether the match spans the whole name */ | ||
| 232 | if (!regexec(&list->regex, name, 1, &m, 0) && m.rm_so == 0 && m.rm_eo == len) { | ||
| 233 | return true; | ||
| 234 | } | ||
| 235 | } | ||
| 236 | |||
| 237 | return false; | ||
| 238 | } | ||
| 239 | |||
| 240 | bool np_seen_name(struct name_list *list, const char *name) { | ||
| 241 | const struct name_list *s; | ||
| 242 | for (s = list; s; s = s->next) { | ||
| 243 | if (!strcmp(s->name, name)) { | ||
| 244 | return true; | ||
| 245 | } | ||
| 246 | } | ||
| 247 | return false; | ||
| 248 | } | ||
| 249 | |||
| 250 | bool np_regex_match_mount_entry(struct mount_entry *me, regex_t *re) { | ||
| 251 | if (regexec(re, me->me_devname, (size_t)0, NULL, 0) == 0 || regexec(re, me->me_mountdir, (size_t)0, NULL, 0) == 0) { | ||
| 252 | return true; | ||
| 253 | } | ||
| 254 | return false; | ||
| 255 | } | ||
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 @@ | |||
| 1 | /* Header file for utils_disk */ | ||
| 2 | |||
| 3 | #include "mountlist.h" | ||
| 4 | #include "utils_base.h" | ||
| 5 | #include "regex.h" | ||
| 6 | |||
| 7 | struct name_list { | ||
| 8 | char *name; | ||
| 9 | struct name_list *next; | ||
| 10 | }; | ||
| 11 | |||
| 12 | struct regex_list { | ||
| 13 | regex_t regex; | ||
| 14 | struct regex_list *next; | ||
| 15 | }; | ||
| 16 | |||
| 17 | struct parameter_list { | ||
| 18 | char *name; | ||
| 19 | thresholds *freespace_bytes; | ||
| 20 | thresholds *freespace_units; | ||
| 21 | thresholds *freespace_percent; | ||
| 22 | thresholds *usedspace_bytes; | ||
| 23 | thresholds *usedspace_units; | ||
| 24 | thresholds *usedspace_percent; | ||
| 25 | thresholds *usedinodes_percent; | ||
| 26 | thresholds *freeinodes_percent; | ||
| 27 | char *group; | ||
| 28 | struct mount_entry *best_match; | ||
| 29 | struct parameter_list *name_next; | ||
| 30 | struct parameter_list *name_prev; | ||
| 31 | uintmax_t total, available, available_to_root, used, inodes_free, inodes_free_to_root, inodes_used, inodes_total; | ||
| 32 | double dfree_pct, dused_pct; | ||
| 33 | uint64_t dused_units, dfree_units, dtotal_units; | ||
| 34 | double dused_inodes_percent, dfree_inodes_percent; | ||
| 35 | }; | ||
| 36 | |||
| 37 | void np_add_name(struct name_list **list, const char *name); | ||
| 38 | bool np_find_name(struct name_list *list, const char *name); | ||
| 39 | bool np_seen_name(struct name_list *list, const char *name); | ||
| 40 | int np_add_regex(struct regex_list **list, const char *regex, int cflags); | ||
| 41 | bool np_find_regmatch(struct regex_list *list, const char *name); | ||
| 42 | struct parameter_list *np_add_parameter(struct parameter_list **list, const char *name); | ||
| 43 | struct parameter_list *np_find_parameter(struct parameter_list *list, const char *name); | ||
| 44 | struct parameter_list *np_del_parameter(struct parameter_list *item, struct parameter_list *prev); | ||
| 45 | |||
| 46 | int search_parameter_list(struct parameter_list *list, const char *name); | ||
| 47 | void np_set_best_match(struct parameter_list *desired, struct mount_entry *mount_list, bool exact); | ||
| 48 | bool np_regex_match_mount_entry(struct mount_entry *me, regex_t *re); | ||
