summaryrefslogtreecommitdiffstats
path: root/plugins
diff options
context:
space:
mode:
authorLorenz Kästle <12514511+RincewindsHat@users.noreply.github.com>2025-03-17 19:36:11 +0100
committerLorenz Kästle <12514511+RincewindsHat@users.noreply.github.com>2025-03-17 19:36:11 +0100
commit4fb7fb05b672febfdfa69381f7f403dc872c7aa6 (patch)
treef33e2e264f5071640720334a4dbd6a3c3bd7768f /plugins
parent969f40c2a083b4e0654a46e6b9e37a0378a4f332 (diff)
downloadmonitoring-plugins-4fb7fb05b672febfdfa69381f7f403dc872c7aa6.tar.gz
check_disk: General refactoring
Diffstat (limited to 'plugins')
-rw-r--r--plugins/check_disk.c353
1 files changed, 158 insertions, 195 deletions
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 */
31const char *copyright = "1999-2024"; 31const char *copyright = "1999-2024";
32const char *email = "devel@monitoring-plugins.org"; 32const char *email = "devel@monitoring-plugins.org";
33 33
34#include "states.h"
34#include "common.h" 35#include "common.h"
36
35#ifdef HAVE_SYS_STAT_H 37#ifdef HAVE_SYS_STAT_H
36# include <sys/stat.h> 38# include <sys/stat.h>
37#endif 39#endif
40
38#if HAVE_INTTYPES_H 41#if HAVE_INTTYPES_H
39# include <inttypes.h> 42# include <inttypes.h>
40#endif 43#endif
44
41#include <assert.h> 45#include <assert.h>
42#include "popen.h" 46#include "popen.h"
43#include "utils.h" 47#include "utils.h"
@@ -46,9 +50,11 @@ const char *email = "devel@monitoring-plugins.org";
46#include "fsusage.h" 50#include "fsusage.h"
47#include "mountlist.h" 51#include "mountlist.h"
48#include <float.h> 52#include <float.h>
53
49#if HAVE_LIMITS_H 54#if HAVE_LIMITS_H
50# include <limits.h> 55# include <limits.h>
51#endif 56#endif
57
52#include "regex.h" 58#include "regex.h"
53 59
54#ifdef __CYGWIN__ 60#ifdef __CYGWIN__
@@ -57,39 +63,12 @@ const char *email = "devel@monitoring-plugins.org";
57# define ERROR -1 63# define ERROR -1
58#endif 64#endif
59 65
60/* If nonzero, show even filesystems with zero size or
61 uninteresting types. */
62static int show_all_fs = 1;
63
64/* If nonzero, show only local filesystems. */ 66/* If nonzero, show only local filesystems. */
65static bool show_local_fs = false; 67static bool show_local_fs = false;
66 68
67/* If nonzero, show only local filesystems but call stat() on remote ones. */ 69/* If nonzero, show only local filesystems but call stat() on remote ones. */
68static bool stat_remote_fs = false; 70static bool stat_remote_fs = false;
69 71
70/* If positive, the units to use when printing sizes;
71 if negative, the human-readable base. */
72/* static int output_block_size; */
73
74/* If nonzero, invoke the `sync' system call before getting any usage data.
75 Using this option can make df very slow, especially with many or very
76 busy disks. Note that this may make a difference on some systems --
77 SunOs4.1.3, for one. It is *not* necessary on Linux. */
78/* static int require_sync = 0; */
79
80/* Linked list of filesystem types to display.
81 If `fs_select_list' is NULL, list all types.
82 This table is generated dynamically from command-line options,
83 rather than hardcoding into the program what it thinks are the
84 valid filesystem types; let the user specify any filesystem type
85 they want to, and if there are any filesystems of that type, they
86 will be shown.
87
88 Some filesystem types:
89 4.2 4.3 ufs nfs swap ignore io vm efs dbg */
90
91/* static struct parameter_list *fs_select_list; */
92
93/* Linked list of filesystem types to omit. 72/* Linked list of filesystem types to omit.
94 If the list is empty, don't exclude any types. */ 73 If the list is empty, don't exclude any types. */
95static struct regex_list *fs_exclude_list = NULL; 74static struct regex_list *fs_exclude_list = NULL;
@@ -150,43 +129,18 @@ static char *crit_freeinodes_percent = NULL;
150static bool path_selected = false; 129static bool path_selected = false;
151static bool path_ignored = false; 130static bool path_ignored = false;
152static char *group = NULL; 131static char *group = NULL;
153static struct stat *stat_buf;
154static struct name_list *seen = NULL; 132static struct name_list *seen = NULL;
155 133
156int main(int argc, char **argv) { 134int main(int argc, char **argv) {
157 int result = STATE_UNKNOWN; 135 setlocale(LC_ALL, "");
158 int disk_result = STATE_UNKNOWN; 136 bindtextdomain(PACKAGE, LOCALEDIR);
159 char *output = NULL; 137 textdomain(PACKAGE);
160 char *ignored = NULL;
161 char *details = NULL;
162 char *perf = NULL;
163 char *perf_ilabel = NULL;
164 char *preamble = " - free space:";
165 char *ignored_preamble = " - ignored paths:";
166 char *flag_header = NULL;
167 int temp_result = STATE_UNKNOWN;
168
169 struct mount_entry *me = NULL;
170 struct fs_usage fsp = {0};
171 struct parameter_list *temp_list = NULL;
172 struct parameter_list *path = NULL;
173 138
174#ifdef __CYGWIN__ 139#ifdef __CYGWIN__
175 char mountdir[32]; 140 char mountdir[32];
176#endif 141#endif
177 142
178 output = strdup(""); 143 mount_list = read_file_system_list(false);
179 ignored = strdup("");
180 details = strdup("");
181 perf = strdup("");
182 perf_ilabel = strdup("");
183 stat_buf = malloc(sizeof *stat_buf);
184
185 setlocale(LC_ALL, "");
186 bindtextdomain(PACKAGE, LOCALEDIR);
187 textdomain(PACKAGE);
188
189 mount_list = read_file_system_list(0);
190 144
191 /* Parse extra opts if any */ 145 /* Parse extra opts if any */
192 argv = np_extra_opts(&argc, argv, progname); 146 argv = np_extra_opts(&argc, argv, progname);
@@ -199,7 +153,8 @@ int main(int argc, char **argv) {
199 mount list and create list of paths 153 mount list and create list of paths
200 */ 154 */
201 if (!path_selected && !path_ignored) { 155 if (!path_selected && !path_ignored) {
202 for (me = mount_list; me; me = me->me_next) { 156 for (struct mount_entry *me = mount_list; me; me = me->me_next) {
157 struct parameter_list *path = NULL;
203 if (!(path = np_find_parameter(path_select_list, me->me_mountdir))) { 158 if (!(path = np_find_parameter(path_select_list, me->me_mountdir))) {
204 path = np_add_parameter(&path_select_list, me->me_mountdir); 159 path = np_add_parameter(&path_select_list, me->me_mountdir);
205 } 160 }
@@ -214,8 +169,9 @@ int main(int argc, char **argv) {
214 } 169 }
215 170
216 /* Error if no match found for specified paths */ 171 /* Error if no match found for specified paths */
217 temp_list = path_select_list; 172 struct parameter_list *temp_list = path_select_list;
218 173
174 char *ignored = strdup("");
219 while (path_select_list) { 175 while (path_select_list) {
220 if (!path_select_list->best_match && ignore_missing) { 176 if (!path_select_list->best_match && ignore_missing) {
221 /* If the first element will be deleted, the temp_list must be updated with the new start address as well */ 177 /* 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) {
237 193
238 path_select_list = temp_list; 194 path_select_list = temp_list;
239 195
196 int result = STATE_UNKNOWN;
240 if (!path_select_list && ignore_missing) { 197 if (!path_select_list && ignore_missing) {
241 result = STATE_OK; 198 result = STATE_OK;
242 if (verbose >= 2) { 199 if (verbose >= 2) {
@@ -244,6 +201,11 @@ int main(int argc, char **argv) {
244 } 201 }
245 } 202 }
246 203
204 mp_state_enum disk_result = STATE_UNKNOWN;
205 char *perf = strdup("");
206 char *perf_ilabel = strdup("");
207 char *output = strdup("");
208 struct parameter_list *path = NULL;
247 /* Process for every path in list */ 209 /* Process for every path in list */
248 for (path = path_select_list; path; path = path->name_next) { 210 for (path = path_select_list; path; path = path->name_next) {
249 if (verbose >= 3 && path->freespace_percent->warning != NULL && path->freespace_percent->critical != NULL) { 211 if (verbose >= 3 && path->freespace_percent->warning != NULL && path->freespace_percent->critical != NULL) {
@@ -255,12 +217,9 @@ int main(int argc, char **argv) {
255 printf("Group of %s: %s\n", path->name, path->group); 217 printf("Group of %s: %s\n", path->name, path->group);
256 } 218 }
257 219
258 /* reset disk result */ 220 struct mount_entry *mount_entry = path->best_match;
259 disk_result = STATE_UNKNOWN;
260 221
261 me = path->best_match; 222 if (!mount_entry) {
262
263 if (!me) {
264 continue; 223 continue;
265 } 224 }
266 225
@@ -276,14 +235,14 @@ int main(int argc, char **argv) {
276 /* Filters */ 235 /* Filters */
277 236
278 /* Remove filesystems already seen */ 237 /* Remove filesystems already seen */
279 if (np_seen_name(seen, me->me_mountdir)) { 238 if (np_seen_name(seen, mount_entry->me_mountdir)) {
280 continue; 239 continue;
281 } 240 }
282 np_add_name(&seen, me->me_mountdir); 241 np_add_name(&seen, mount_entry->me_mountdir);
283 242
284 if (path->group == NULL) { 243 if (path->group == NULL) {
285 /* Skip remote filesystems if we're not interested in them */ 244 /* Skip remote filesystems if we're not interested in them */
286 if (me->me_remote && show_local_fs) { 245 if (mount_entry->me_remote && show_local_fs) {
287 if (stat_remote_fs) { 246 if (stat_remote_fs) {
288 if (!stat_path(path) && ignore_missing) { 247 if (!stat_path(path) && ignore_missing) {
289 result = STATE_OK; 248 result = STATE_OK;
@@ -293,19 +252,16 @@ int main(int argc, char **argv) {
293 continue; 252 continue;
294 /* Skip pseudo fs's if we haven't asked for all fs's */ 253 /* Skip pseudo fs's if we haven't asked for all fs's */
295 } 254 }
296 if (me->me_dummy && !show_all_fs) { 255 if (fs_exclude_list && np_find_regmatch(fs_exclude_list, mount_entry->me_type)) {
297 continue;
298 /* Skip excluded fstypes */
299 }
300 if (fs_exclude_list && np_find_regmatch(fs_exclude_list, me->me_type)) {
301 continue; 256 continue;
302 /* Skip excluded fs's */ 257 /* Skip excluded fs's */
303 } 258 }
304 if (dp_exclude_list && (np_find_name(dp_exclude_list, me->me_devname) || np_find_name(dp_exclude_list, me->me_mountdir))) { 259 if (dp_exclude_list &&
260 (np_find_name(dp_exclude_list, mount_entry->me_devname) || np_find_name(dp_exclude_list, mount_entry->me_mountdir))) {
305 continue; 261 continue;
306 /* Skip not included fstypes */ 262 /* Skip not included fstypes */
307 } 263 }
308 if (fs_include_list && !np_find_regmatch(fs_include_list, me->me_type)) { 264 if (fs_include_list && !np_find_regmatch(fs_include_list, mount_entry->me_type)) {
309 continue; 265 continue;
310 } 266 }
311 } 267 }
@@ -317,21 +273,23 @@ int main(int argc, char **argv) {
317 } 273 }
318 continue; 274 continue;
319 } 275 }
320 get_fs_usage(me->me_mountdir, me->me_devname, &fsp);
321 276
322 if (fsp.fsu_blocks && strcmp("none", me->me_mountdir)) { 277 struct fs_usage fsp = {0};
278 get_fs_usage(mount_entry->me_mountdir, mount_entry->me_devname, &fsp);
279
280 if (fsp.fsu_blocks && strcmp("none", mount_entry->me_mountdir)) {
323 get_stats(path, &fsp); 281 get_stats(path, &fsp);
324 282
325 if (verbose >= 3) { 283 if (verbose >= 3) {
326 printf("For %s, used_pct=%f free_pct=%f used_units=%lu free_units=%lu total_units=%lu used_inodes_pct=%f " 284 printf("For %s, used_pct=%f free_pct=%f used_units=%lu free_units=%lu total_units=%lu used_inodes_pct=%f "
327 "free_inodes_pct=%f fsp.fsu_blocksize=%lu mult=%lu\n", 285 "free_inodes_pct=%f fsp.fsu_blocksize=%lu mult=%lu\n",
328 me->me_mountdir, path->dused_pct, path->dfree_pct, path->dused_units, path->dfree_units, path->dtotal_units, 286 mount_entry->me_mountdir, path->dused_pct, path->dfree_pct, path->dused_units, path->dfree_units, path->dtotal_units,
329 path->dused_inodes_percent, path->dfree_inodes_percent, fsp.fsu_blocksize, mult); 287 path->dused_inodes_percent, path->dfree_inodes_percent, fsp.fsu_blocksize, mult);
330 } 288 }
331 289
332 /* Threshold comparisons */ 290 /* Threshold comparisons */
333 291
334 temp_result = get_status(path->dfree_units, path->freespace_units); 292 mp_state_enum temp_result = get_status(path->dfree_units, path->freespace_units);
335 if (verbose >= 3) { 293 if (verbose >= 3) {
336 printf("Freespace_units result=%d\n", temp_result); 294 printf("Freespace_units result=%d\n", temp_result);
337 } 295 }
@@ -397,10 +355,10 @@ int main(int argc, char **argv) {
397 355
398 /* Nb: *_high_tide are unset when == UINT64_MAX */ 356 /* Nb: *_high_tide are unset when == UINT64_MAX */
399 xasprintf(&perf, "%s %s", perf, 357 xasprintf(&perf, "%s %s", perf,
400 perfdata_uint64((!strcmp(me->me_mountdir, "none") || display_mntp) ? me->me_devname : me->me_mountdir, 358 perfdata_uint64((!strcmp(mount_entry->me_mountdir, "none") || display_mntp) ? mount_entry->me_devname
401 path->dused_units * mult, "B", (warning_high_tide != UINT64_MAX ), warning_high_tide, 359 : mount_entry->me_mountdir,
402 (critical_high_tide != UINT64_MAX ), critical_high_tide, true, 0, true, 360 path->dused_units * mult, "B", (warning_high_tide != UINT64_MAX), warning_high_tide,
403 path->dtotal_units * mult)); 361 (critical_high_tide != UINT64_MAX), critical_high_tide, true, 0, true, path->dtotal_units * mult));
404 362
405 if (display_inodes_perfdata) { 363 if (display_inodes_perfdata) {
406 /* *_high_tide must be reinitialized at each run */ 364 /* *_high_tide must be reinitialized at each run */
@@ -417,26 +375,26 @@ int main(int argc, char **argv) {
417 } 375 }
418 376
419 xasprintf(&perf_ilabel, "%s (inodes)", 377 xasprintf(&perf_ilabel, "%s (inodes)",
420 (!strcmp(me->me_mountdir, "none") || display_mntp) ? me->me_devname : me->me_mountdir); 378 (!strcmp(mount_entry->me_mountdir, "none") || display_mntp) ? mount_entry->me_devname : mount_entry->me_mountdir);
421 /* Nb: *_high_tide are unset when == UINT64_MAX */ 379 /* Nb: *_high_tide are unset when == UINT64_MAX */
422 xasprintf(&perf, "%s %s", perf, 380 xasprintf(&perf, "%s %s", perf,
423 perfdata_uint64(perf_ilabel, path->inodes_used, "", (warning_high_tide != UINT64_MAX), 381 perfdata_uint64(perf_ilabel, path->inodes_used, "", (warning_high_tide != UINT64_MAX), warning_high_tide,
424 warning_high_tide, (critical_high_tide != UINT64_MAX), critical_high_tide, true, 0, 382 (critical_high_tide != UINT64_MAX), critical_high_tide, true, 0, true, path->inodes_total));
425 true, path->inodes_total));
426 } 383 }
427 384
428 if (disk_result == STATE_OK && erronly && !verbose) { 385 if (disk_result == STATE_OK && erronly && !verbose) {
429 continue; 386 continue;
430 } 387 }
431 388
389 char *flag_header = NULL;
432 if (disk_result && verbose >= 1) { 390 if (disk_result && verbose >= 1) {
433 xasprintf(&flag_header, " %s [", state_text(disk_result)); 391 xasprintf(&flag_header, " %s [", state_text(disk_result));
434 } else { 392 } else {
435 xasprintf(&flag_header, ""); 393 xasprintf(&flag_header, "");
436 } 394 }
437 xasprintf(&output, "%s%s %s %llu%s (%.1f%%", output, flag_header, 395 xasprintf(&output, "%s%s %s %llu%s (%.1f%%", output, flag_header,
438 (!strcmp(me->me_mountdir, "none") || display_mntp) ? me->me_devname : me->me_mountdir, path->dfree_units, units, 396 (!strcmp(mount_entry->me_mountdir, "none") || display_mntp) ? mount_entry->me_devname : mount_entry->me_mountdir,
439 path->dfree_pct); 397 path->dfree_units, units, path->dfree_pct);
440 if (path->dused_inodes_percent < 0) { 398 if (path->dused_inodes_percent < 0) {
441 xasprintf(&output, "%s inode=-)%s;", output, (disk_result ? "]" : "")); 399 xasprintf(&output, "%s inode=-)%s;", output, (disk_result ? "]" : ""));
442 } else { 400 } else {
@@ -446,15 +404,13 @@ int main(int argc, char **argv) {
446 } 404 }
447 } 405 }
448 406
449 if (verbose >= 2) { 407 char *preamble = " - free space:";
450 xasprintf(&output, "%s%s", output, details);
451 }
452
453 if (strcmp(output, "") == 0 && !erronly) { 408 if (strcmp(output, "") == 0 && !erronly) {
454 preamble = ""; 409 preamble = "";
455 xasprintf(&output, " - No disks were found for provided parameters"); 410 xasprintf(&output, " - No disks were found for provided parameters");
456 } 411 }
457 412
413 char *ignored_preamble = " - ignored paths:";
458 printf("DISK %s%s%s%s%s|%s\n", state_text(result), ((erronly && result == STATE_OK)) ? "" : preamble, output, 414 printf("DISK %s%s%s%s%s|%s\n", state_text(result), ((erronly && result == STATE_OK)) ? "" : preamble, output,
459 (strcmp(ignored, "") == 0) ? "" : ignored_preamble, ignored, perf); 415 (strcmp(ignored, "") == 0) ? "" : ignored_preamble, ignored, perf);
460 return result; 416 return result;
@@ -470,19 +426,10 @@ double calculate_percent(uintmax_t value, uintmax_t total) {
470 426
471/* process command-line arguments */ 427/* process command-line arguments */
472int process_arguments(int argc, char **argv) { 428int process_arguments(int argc, char **argv) {
473 int c; 429 if (argc < 2) {
474 int err; 430 return ERROR;
475 struct parameter_list *se; 431 }
476 struct parameter_list *temp_list = NULL;
477 struct parameter_list *previous = NULL;
478 struct mount_entry *me;
479 regex_t re;
480 int cflags = REG_NOSUB | REG_EXTENDED;
481 int default_cflags = cflags;
482 char errbuf[MAX_INPUT_BUFFER];
483 int fnd = 0;
484 432
485 int option = 0;
486 static struct option longopts[] = {{"timeout", required_argument, 0, 't'}, 433 static struct option longopts[] = {{"timeout", required_argument, 0, 't'},
487 {"warning", required_argument, 0, 'w'}, 434 {"warning", required_argument, 0, 'w'},
488 {"critical", required_argument, 0, 'c'}, 435 {"critical", required_argument, 0, 'c'},
@@ -522,26 +469,26 @@ int process_arguments(int argc, char **argv) {
522 {"help", no_argument, 0, 'h'}, 469 {"help", no_argument, 0, 'h'},
523 {0, 0, 0, 0}}; 470 {0, 0, 0, 0}};
524 471
525 if (argc < 2) { 472 for (int index = 1; index < argc; index++) {
526 return ERROR; 473 if (strcmp("-to", argv[index]) == 0) {
474 strcpy(argv[index], "-t");
475 }
527 } 476 }
528 477
529 np_add_regex(&fs_exclude_list, "iso9660", REG_EXTENDED); 478 int cflags = REG_NOSUB | REG_EXTENDED;
479 int default_cflags = cflags;
530 480
531 for (c = 1; c < argc; c++) { 481 np_add_regex(&fs_exclude_list, "iso9660", REG_EXTENDED);
532 if (strcmp("-to", argv[c]) == 0) {
533 strcpy(argv[c], "-t");
534 }
535 }
536 482
537 while (1) { 483 while (true) {
538 c = getopt_long(argc, argv, "+?VqhvefCt:c:w:K:W:u:p:x:X:N:mklLPg:R:r:i:I:MEAn", longopts, &option); 484 int option = 0;
485 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);
539 486
540 if (c == -1 || c == EOF) { 487 if (option_index == -1 || option_index == EOF) {
541 break; 488 break;
542 } 489 }
543 490
544 switch (c) { 491 switch (option_index) {
545 case 't': /* timeout period */ 492 case 't': /* timeout period */
546 if (is_integer(optarg)) { 493 if (is_integer(optarg)) {
547 timeout_interval = atoi(optarg); 494 timeout_interval = atoi(optarg);
@@ -685,10 +632,12 @@ int process_arguments(int argc, char **argv) {
685 } 632 }
686 633
687 /* add parameter if not found. overwrite thresholds if path has already been added */ 634 /* add parameter if not found. overwrite thresholds if path has already been added */
635 struct parameter_list *se;
688 if (!(se = np_find_parameter(path_select_list, optarg))) { 636 if (!(se = np_find_parameter(path_select_list, optarg))) {
689 se = np_add_parameter(&path_select_list, optarg); 637 se = np_add_parameter(&path_select_list, optarg);
690 638
691 if (stat(optarg, &stat_buf[0]) && ignore_missing) { 639 struct stat stat_buf = {};
640 if (stat(optarg, &stat_buf) && ignore_missing) {
692 path_ignored = true; 641 path_ignored = true;
693 break; 642 break;
694 } 643 }
@@ -703,7 +652,7 @@ int process_arguments(int argc, char **argv) {
703 /* NB: We can't free the old mount_list "just like that": both list pointers and struct 652 /* NB: We can't free the old mount_list "just like that": both list pointers and struct
704 * pointers are copied around. One of the reason it wasn't done yet is that other parts 653 * pointers are copied around. One of the reason it wasn't done yet is that other parts
705 * of check_disk need the same kind of cleanup so it'd better be done as a whole */ 654 * of check_disk need the same kind of cleanup so it'd better be done as a whole */
706 mount_list = read_file_system_list(0); 655 mount_list = read_file_system_list(false);
707 np_set_best_match(se, mount_list, exact_match); 656 np_set_best_match(se, mount_list, exact_match);
708 657
709 path_selected = true; 658 path_selected = true;
@@ -711,9 +660,10 @@ int process_arguments(int argc, char **argv) {
711 case 'x': /* exclude path or partition */ 660 case 'x': /* exclude path or partition */
712 np_add_name(&dp_exclude_list, optarg); 661 np_add_name(&dp_exclude_list, optarg);
713 break; 662 break;
714 case 'X': /* exclude file system type */ 663 case 'X': /* exclude file system type */ {
715 err = np_add_regex(&fs_exclude_list, optarg, REG_EXTENDED); 664 int err = np_add_regex(&fs_exclude_list, optarg, REG_EXTENDED);
716 if (err != 0) { 665 if (err != 0) {
666 char errbuf[MAX_INPUT_BUFFER];
717 regerror(err, &fs_exclude_list->regex, errbuf, MAX_INPUT_BUFFER); 667 regerror(err, &fs_exclude_list->regex, errbuf, MAX_INPUT_BUFFER);
718 die(STATE_UNKNOWN, "DISK %s: %s - %s\n", _("UNKNOWN"), _("Could not compile regular expression"), errbuf); 668 die(STATE_UNKNOWN, "DISK %s: %s - %s\n", _("UNKNOWN"), _("Could not compile regular expression"), errbuf);
719 } 669 }
@@ -721,10 +671,11 @@ int process_arguments(int argc, char **argv) {
721 case 'N': /* include file system type */ 671 case 'N': /* include file system type */
722 err = np_add_regex(&fs_include_list, optarg, REG_EXTENDED); 672 err = np_add_regex(&fs_include_list, optarg, REG_EXTENDED);
723 if (err != 0) { 673 if (err != 0) {
674 char errbuf[MAX_INPUT_BUFFER];
724 regerror(err, &fs_exclude_list->regex, errbuf, MAX_INPUT_BUFFER); 675 regerror(err, &fs_exclude_list->regex, errbuf, MAX_INPUT_BUFFER);
725 die(STATE_UNKNOWN, "DISK %s: %s - %s\n", _("UNKNOWN"), _("Could not compile regular expression"), errbuf); 676 die(STATE_UNKNOWN, "DISK %s: %s - %s\n", _("UNKNOWN"), _("Could not compile regular expression"), errbuf);
726 } 677 }
727 break; 678 } break;
728 case 'v': /* verbose */ 679 case 'v': /* verbose */
729 verbose++; 680 verbose++;
730 break; 681 break;
@@ -753,23 +704,24 @@ int process_arguments(int argc, char **argv) {
753 case 'I': 704 case 'I':
754 cflags |= REG_ICASE; 705 cflags |= REG_ICASE;
755 // Intentional fallthrough 706 // Intentional fallthrough
756 case 'i': 707 case 'i': {
757 if (!path_selected) { 708 if (!path_selected) {
758 die(STATE_UNKNOWN, "DISK %s: %s\n", _("UNKNOWN"), 709 die(STATE_UNKNOWN, "DISK %s: %s\n", _("UNKNOWN"),
759 _("Paths need to be selected before using -i/-I. Use -A to select all paths explicitly")); 710 _("Paths need to be selected before using -i/-I. Use -A to select all paths explicitly"));
760 } 711 }
761 err = regcomp(&re, optarg, cflags); 712 regex_t regex;
713 int err = regcomp(&regex, optarg, cflags);
762 if (err != 0) { 714 if (err != 0) {
763 regerror(err, &re, errbuf, MAX_INPUT_BUFFER); 715 char errbuf[MAX_INPUT_BUFFER];
716 regerror(err, &regex, errbuf, MAX_INPUT_BUFFER);
764 die(STATE_UNKNOWN, "DISK %s: %s - %s\n", _("UNKNOWN"), _("Could not compile regular expression"), errbuf); 717 die(STATE_UNKNOWN, "DISK %s: %s - %s\n", _("UNKNOWN"), _("Could not compile regular expression"), errbuf);
765 } 718 }
766 719
767 temp_list = path_select_list; 720 struct parameter_list *temp_list = path_select_list;
768 721 struct parameter_list *previous = NULL;
769 previous = NULL;
770 while (temp_list) { 722 while (temp_list) {
771 if (temp_list->best_match) { 723 if (temp_list->best_match) {
772 if (np_regex_match_mount_entry(temp_list->best_match, &re)) { 724 if (np_regex_match_mount_entry(temp_list->best_match, &regex)) {
773 725
774 if (verbose >= 3) { 726 if (verbose >= 3) {
775 printf("ignoring %s matching regex\n", temp_list->name); 727 printf("ignoring %s matching regex\n", temp_list->name);
@@ -791,8 +743,7 @@ int process_arguments(int argc, char **argv) {
791 } 743 }
792 744
793 cflags = default_cflags; 745 cflags = default_cflags;
794 break; 746 } break;
795
796 case 'n': 747 case 'n':
797 ignore_missing = true; 748 ignore_missing = true;
798 break; 749 break;
@@ -802,7 +753,7 @@ int process_arguments(int argc, char **argv) {
802 case 'R': 753 case 'R':
803 cflags |= REG_ICASE; 754 cflags |= REG_ICASE;
804 // Intentional fallthrough 755 // Intentional fallthrough
805 case 'r': 756 case 'r': {
806 if (!(warn_freespace_units || crit_freespace_units || warn_freespace_percent || crit_freespace_percent || 757 if (!(warn_freespace_units || crit_freespace_units || warn_freespace_percent || crit_freespace_percent ||
807 warn_usedspace_units || crit_usedspace_units || warn_usedspace_percent || crit_usedspace_percent || 758 warn_usedspace_units || crit_usedspace_units || warn_usedspace_percent || crit_usedspace_percent ||
808 warn_usedinodes_percent || crit_usedinodes_percent || warn_freeinodes_percent || crit_freeinodes_percent)) { 759 warn_usedinodes_percent || crit_usedinodes_percent || warn_freeinodes_percent || crit_freeinodes_percent)) {
@@ -810,15 +761,18 @@ int process_arguments(int argc, char **argv) {
810 _("Must set a threshold value before using -r/-R/-A (--ereg-path/--eregi-path/--all)\n")); 761 _("Must set a threshold value before using -r/-R/-A (--ereg-path/--eregi-path/--all)\n"));
811 } 762 }
812 763
813 err = regcomp(&re, optarg, cflags); 764 regex_t regex;
765 int err = regcomp(&regex, optarg, cflags);
814 if (err != 0) { 766 if (err != 0) {
815 regerror(err, &re, errbuf, MAX_INPUT_BUFFER); 767 char errbuf[MAX_INPUT_BUFFER];
768 regerror(err, &regex, errbuf, MAX_INPUT_BUFFER);
816 die(STATE_UNKNOWN, "DISK %s: %s - %s\n", _("UNKNOWN"), _("Could not compile regular expression"), errbuf); 769 die(STATE_UNKNOWN, "DISK %s: %s - %s\n", _("UNKNOWN"), _("Could not compile regular expression"), errbuf);
817 } 770 }
818 771
819 for (me = mount_list; me; me = me->me_next) { 772 bool found = false;
820 if (np_regex_match_mount_entry(me, &re)) { 773 for (struct mount_entry *me = mount_list; me; me = me->me_next) {
821 fnd = true; 774 if (np_regex_match_mount_entry(me, &regex)) {
775 found = true;
822 if (verbose >= 3) { 776 if (verbose >= 3) {
823 printf("%s %s matching expression %s\n", me->me_devname, me->me_mountdir, optarg); 777 printf("%s %s matching expression %s\n", me->me_devname, me->me_mountdir, optarg);
824 } 778 }
@@ -832,21 +786,21 @@ int process_arguments(int argc, char **argv) {
832 } 786 }
833 } 787 }
834 788
835 if (!fnd && ignore_missing) { 789 if (!found && ignore_missing) {
836 path_ignored = true; 790 path_ignored = true;
837 path_selected = true; 791 path_selected = true;
838 break; 792 break;
839 } 793 }
840 if (!fnd) { 794 if (!found) {
841 die(STATE_UNKNOWN, "DISK %s: %s - %s\n", _("UNKNOWN"), _("Regular expression did not match any path or disk"), optarg); 795 die(STATE_UNKNOWN, "DISK %s: %s - %s\n", _("UNKNOWN"), _("Regular expression did not match any path or disk"), optarg);
842 } 796 }
843 797
844 fnd = false; 798 found = false;
845 path_selected = true; 799 path_selected = true;
846 np_set_best_match(path_select_list, mount_list, exact_match); 800 np_set_best_match(path_select_list, mount_list, exact_match);
847 cflags = default_cflags; 801 cflags = default_cflags;
848 802
849 break; 803 } break;
850 case 'M': /* display mountpoint */ 804 case 'M': /* display mountpoint */
851 display_mntp = true; 805 display_mntp = true;
852 break; 806 break;
@@ -854,7 +808,7 @@ int process_arguments(int argc, char **argv) {
854 /* add all mount entries to path_select list if no partitions have been explicitly defined using -p */ 808 /* add all mount entries to path_select list if no partitions have been explicitly defined using -p */
855 if (!path_selected) { 809 if (!path_selected) {
856 struct parameter_list *path; 810 struct parameter_list *path;
857 for (me = mount_list; me; me = me->me_next) { 811 for (struct mount_entry *me = mount_list; me; me = me->me_next) {
858 if (!(path = np_find_parameter(path_select_list, me->me_mountdir))) { 812 if (!(path = np_find_parameter(path_select_list, me->me_mountdir))) {
859 path = np_add_parameter(&path_select_list, me->me_mountdir); 813 path = np_add_parameter(&path_select_list, me->me_mountdir);
860 } 814 }
@@ -891,17 +845,17 @@ int process_arguments(int argc, char **argv) {
891 } 845 }
892 846
893 /* Support for "check_disk warn crit [fs]" with thresholds at used% level */ 847 /* Support for "check_disk warn crit [fs]" with thresholds at used% level */
894 c = optind; 848 int index = optind;
895 if (warn_usedspace_percent == NULL && argc > c && is_intnonneg(argv[c])) { 849 if (warn_usedspace_percent == NULL && argc > index && is_intnonneg(argv[index])) {
896 warn_usedspace_percent = argv[c++]; 850 warn_usedspace_percent = argv[index++];
897 } 851 }
898 852
899 if (crit_usedspace_percent == NULL && argc > c && is_intnonneg(argv[c])) { 853 if (crit_usedspace_percent == NULL && argc > index && is_intnonneg(argv[index])) {
900 crit_usedspace_percent = argv[c++]; 854 crit_usedspace_percent = argv[index++];
901 } 855 }
902 856
903 if (argc > c) { 857 if (argc > index) {
904 se = np_add_parameter(&path_select_list, strdup(argv[c++])); 858 struct parameter_list *se = np_add_parameter(&path_select_list, strdup(argv[index++]));
905 path_selected = true; 859 path_selected = true;
906 set_all_thresholds(se); 860 set_all_thresholds(se);
907 } 861 }
@@ -911,7 +865,7 @@ int process_arguments(int argc, char **argv) {
911 mult = (uintmax_t)1024 * 1024; 865 mult = (uintmax_t)1024 * 1024;
912 } 866 }
913 867
914 return true; 868 return 0;
915} 869}
916 870
917void set_all_thresholds(struct parameter_list *path) { 871void set_all_thresholds(struct parameter_list *path) {
@@ -919,22 +873,27 @@ void set_all_thresholds(struct parameter_list *path) {
919 free(path->freespace_units); 873 free(path->freespace_units);
920 } 874 }
921 set_thresholds(&path->freespace_units, warn_freespace_units, crit_freespace_units); 875 set_thresholds(&path->freespace_units, warn_freespace_units, crit_freespace_units);
876
922 if (path->freespace_percent != NULL) { 877 if (path->freespace_percent != NULL) {
923 free(path->freespace_percent); 878 free(path->freespace_percent);
924 } 879 }
925 set_thresholds(&path->freespace_percent, warn_freespace_percent, crit_freespace_percent); 880 set_thresholds(&path->freespace_percent, warn_freespace_percent, crit_freespace_percent);
881
926 if (path->usedspace_units != NULL) { 882 if (path->usedspace_units != NULL) {
927 free(path->usedspace_units); 883 free(path->usedspace_units);
928 } 884 }
929 set_thresholds(&path->usedspace_units, warn_usedspace_units, crit_usedspace_units); 885 set_thresholds(&path->usedspace_units, warn_usedspace_units, crit_usedspace_units);
886
930 if (path->usedspace_percent != NULL) { 887 if (path->usedspace_percent != NULL) {
931 free(path->usedspace_percent); 888 free(path->usedspace_percent);
932 } 889 }
933 set_thresholds(&path->usedspace_percent, warn_usedspace_percent, crit_usedspace_percent); 890 set_thresholds(&path->usedspace_percent, warn_usedspace_percent, crit_usedspace_percent);
891
934 if (path->usedinodes_percent != NULL) { 892 if (path->usedinodes_percent != NULL) {
935 free(path->usedinodes_percent); 893 free(path->usedinodes_percent);
936 } 894 }
937 set_thresholds(&path->usedinodes_percent, warn_usedinodes_percent, crit_usedinodes_percent); 895 set_thresholds(&path->usedinodes_percent, warn_usedinodes_percent, crit_usedinodes_percent);
896
938 if (path->freeinodes_percent != NULL) { 897 if (path->freeinodes_percent != NULL) {
939 free(path->freeinodes_percent); 898 free(path->freeinodes_percent);
940 } 899 }
@@ -1046,40 +1005,44 @@ void print_usage(void) {
1046 printf("[-t timeout] [-u unit] [-v] [-X type_regex] [-N type]\n"); 1005 printf("[-t timeout] [-u unit] [-v] [-X type_regex] [-N type]\n");
1047} 1006}
1048 1007
1049bool stat_path(struct parameter_list *p) { 1008bool stat_path(struct parameter_list *parameters) {
1050 /* Stat entry to check that dir exists and is accessible */ 1009 /* Stat entry to check that dir exists and is accessible */
1051 if (verbose >= 3) { 1010 if (verbose >= 3) {
1052 printf("calling stat on %s\n", p->name); 1011 printf("calling stat on %s\n", parameters->name);
1053 } 1012 }
1054 if (stat(p->name, &stat_buf[0])) { 1013
1014 struct stat stat_buf = {0};
1015 if (stat(parameters->name, &stat_buf)) {
1055 if (verbose >= 3) { 1016 if (verbose >= 3) {
1056 printf("stat failed on %s\n", p->name); 1017 printf("stat failed on %s\n", parameters->name);
1057 } 1018 }
1058 if (ignore_missing) { 1019 if (ignore_missing) {
1059 return false; 1020 return false;
1060 } 1021 }
1061 printf("DISK %s - ", _("CRITICAL")); 1022 printf("DISK %s - ", _("CRITICAL"));
1062 die(STATE_CRITICAL, _("%s %s: %s\n"), p->name, _("is not accessible"), strerror(errno)); 1023 die(STATE_CRITICAL, _("%s %s: %s\n"), parameters->name, _("is not accessible"), strerror(errno));
1063 } 1024 }
1025
1064 return true; 1026 return true;
1065} 1027}
1066 1028
1067void get_stats(struct parameter_list *p, struct fs_usage *fsp) { 1029void get_stats(struct parameter_list *parameters, struct fs_usage *fsp) {
1068 struct parameter_list *p_list;
1069 struct fs_usage tmpfsp; 1030 struct fs_usage tmpfsp;
1070 int first = 1; 1031 bool first = true;
1071 1032
1072 if (p->group == NULL) { 1033 if (parameters->group == NULL) {
1073 get_path_stats(p, fsp); 1034 get_path_stats(parameters, fsp);
1074 } else { 1035 } else {
1075 /* find all group members */ 1036 /* find all group members */
1076 for (p_list = path_select_list; p_list; p_list = p_list->name_next) { 1037 for (struct parameter_list *p_list = path_select_list; p_list; p_list = p_list->name_next) {
1038
1077#ifdef __CYGWIN__ 1039#ifdef __CYGWIN__
1078 if (strncmp(p_list->name, "/cygdrive/", 10) != 0) { 1040 if (strncmp(p_list->name, "/cygdrive/", 10) != 0) {
1079 continue; 1041 continue;
1080 } 1042 }
1081#endif 1043#endif
1082 if (p_list->group && !(strcmp(p_list->group, p->group))) { 1044
1045 if (p_list->group && !(strcmp(p_list->group, parameters->group))) {
1083 if (!stat_path(p_list)) { 1046 if (!stat_path(p_list)) {
1084 continue; 1047 continue;
1085 } 1048 }
@@ -1094,63 +1057,63 @@ void get_stats(struct parameter_list *p, struct fs_usage *fsp) {
1094 /* prevent counting the first FS of a group twice since its parameter_list entry 1057 /* prevent counting the first FS of a group twice since its parameter_list entry
1095 * is used to carry the information of all file systems of the entire group */ 1058 * is used to carry the information of all file systems of the entire group */
1096 if (!first) { 1059 if (!first) {
1097 p->total += p_list->total; 1060 parameters->total += p_list->total;
1098 p->available += p_list->available; 1061 parameters->available += p_list->available;
1099 p->available_to_root += p_list->available_to_root; 1062 parameters->available_to_root += p_list->available_to_root;
1100 p->used += p_list->used; 1063 parameters->used += p_list->used;
1101 1064
1102 p->dused_units += p_list->dused_units; 1065 parameters->dused_units += p_list->dused_units;
1103 p->dfree_units += p_list->dfree_units; 1066 parameters->dfree_units += p_list->dfree_units;
1104 p->dtotal_units += p_list->dtotal_units; 1067 parameters->dtotal_units += p_list->dtotal_units;
1105 p->inodes_total += p_list->inodes_total; 1068 parameters->inodes_total += p_list->inodes_total;
1106 p->inodes_free += p_list->inodes_free; 1069 parameters->inodes_free += p_list->inodes_free;
1107 p->inodes_free_to_root += p_list->inodes_free_to_root; 1070 parameters->inodes_free_to_root += p_list->inodes_free_to_root;
1108 p->inodes_used += p_list->inodes_used; 1071 parameters->inodes_used += p_list->inodes_used;
1109 } 1072 }
1110 first = 0; 1073 first = false;
1111 } 1074 }
1112 if (verbose >= 3) { 1075 if (verbose >= 3) {
1113 printf("Group %s now has: used_units=%lu free_units=%lu total_units=%lu fsu_blocksize=%lu mult=%lu\n", p->group, 1076 printf("Group %s now has: used_units=%lu free_units=%lu total_units=%lu fsu_blocksize=%lu mult=%lu\n", parameters->group,
1114 p->dused_units, p->dfree_units, p->dtotal_units, tmpfsp.fsu_blocksize, mult); 1077 parameters->dused_units, parameters->dfree_units, parameters->dtotal_units, tmpfsp.fsu_blocksize, mult);
1115 } 1078 }
1116 } 1079 }
1117 /* modify devname and mountdir for output */ 1080 /* modify devname and mountdir for output */
1118 p->best_match->me_mountdir = p->best_match->me_devname = p->group; 1081 parameters->best_match->me_mountdir = parameters->best_match->me_devname = parameters->group;
1119 } 1082 }
1120 /* finally calculate percentages for either plain FS or summed up group */ 1083 /* finally calculate percentages for either plain FS or summed up group */
1121 p->dused_pct = calculate_percent(p->used, p->used + p->available); /* used + available can never be > uintmax */ 1084 parameters->dused_pct = calculate_percent(parameters->used, parameters->used + parameters->available); /* used + available can never be > uintmax */
1122 p->dfree_pct = 100.0 - p->dused_pct; 1085 parameters->dfree_pct = 100.0 - parameters->dused_pct;
1123 p->dused_inodes_percent = calculate_percent(p->inodes_total - p->inodes_free, p->inodes_total); 1086 parameters->dused_inodes_percent = calculate_percent(parameters->inodes_total - parameters->inodes_free, parameters->inodes_total);
1124 p->dfree_inodes_percent = 100 - p->dused_inodes_percent; 1087 parameters->dfree_inodes_percent = 100 - parameters->dused_inodes_percent;
1125} 1088}
1126 1089
1127void get_path_stats(struct parameter_list *p, struct fs_usage *fsp) { 1090void get_path_stats(struct parameter_list *parameters, struct fs_usage *fsp) {
1128 p->available = fsp->fsu_bavail; 1091 parameters->available = fsp->fsu_bavail;
1129 p->available_to_root = fsp->fsu_bfree; 1092 parameters->available_to_root = fsp->fsu_bfree;
1130 p->used = fsp->fsu_blocks - fsp->fsu_bfree; 1093 parameters->used = fsp->fsu_blocks - fsp->fsu_bfree;
1131 if (freespace_ignore_reserved) { 1094 if (freespace_ignore_reserved) {
1132 /* option activated : we subtract the root-reserved space from the total */ 1095 /* option activated : we subtract the root-reserved space from the total */
1133 p->total = fsp->fsu_blocks - p->available_to_root + p->available; 1096 parameters->total = fsp->fsu_blocks - parameters->available_to_root + parameters->available;
1134 } else { 1097 } else {
1135 /* default behaviour : take all the blocks into account */ 1098 /* default behaviour : take all the blocks into account */
1136 p->total = fsp->fsu_blocks; 1099 parameters->total = fsp->fsu_blocks;
1137 } 1100 }
1138 1101
1139 p->dused_units = p->used * fsp->fsu_blocksize / mult; 1102 parameters->dused_units = parameters->used * fsp->fsu_blocksize / mult;
1140 p->dfree_units = p->available * fsp->fsu_blocksize / mult; 1103 parameters->dfree_units = parameters->available * fsp->fsu_blocksize / mult;
1141 p->dtotal_units = p->total * fsp->fsu_blocksize / mult; 1104 parameters->dtotal_units = parameters->total * fsp->fsu_blocksize / mult;
1142 /* Free file nodes. Not sure the workaround is required, but in case...*/ 1105 /* Free file nodes. Not sure the workaround is required, but in case...*/
1143 p->inodes_free = fsp->fsu_ffree; 1106 parameters->inodes_free = fsp->fsu_ffree;
1144 p->inodes_free_to_root = fsp->fsu_ffree; /* Free file nodes for root. */ 1107 parameters->inodes_free_to_root = fsp->fsu_ffree; /* Free file nodes for root. */
1145 p->inodes_used = fsp->fsu_files - fsp->fsu_ffree; 1108 parameters->inodes_used = fsp->fsu_files - fsp->fsu_ffree;
1146 if (freespace_ignore_reserved) { 1109 if (freespace_ignore_reserved) {
1147 /* option activated : we subtract the root-reserved inodes from the total */ 1110 /* option activated : we subtract the root-reserved inodes from the total */
1148 /* not all OS report fsp->fsu_favail, only the ones with statvfs syscall */ 1111 /* not all OS report fsp->fsu_favail, only the ones with statvfs syscall */
1149 /* for others, fsp->fsu_ffree == fsp->fsu_favail */ 1112 /* for others, fsp->fsu_ffree == fsp->fsu_favail */
1150 p->inodes_total = fsp->fsu_files - p->inodes_free_to_root + p->inodes_free; 1113 parameters->inodes_total = fsp->fsu_files - parameters->inodes_free_to_root + parameters->inodes_free;
1151 } else { 1114 } else {
1152 /* default behaviour : take all the inodes into account */ 1115 /* default behaviour : take all the inodes into account */
1153 p->inodes_total = fsp->fsu_files; 1116 parameters->inodes_total = fsp->fsu_files;
1154 } 1117 }
1155 np_add_name(&seen, p->best_match->me_mountdir); 1118 np_add_name(&seen, parameters->best_match->me_mountdir);
1156} 1119}