Code

7bd044adf6dc046fe2dd460164bbd3ed3cb9abba
[nagiosplug.git] / plugins / check_disk.c
1 /******************************************************************************
2 *
3 * Nagios check_disk plugin
4 *
5 * License: GPL
6 * Copyright (c) 1999-2006 nagios-plugins team
7 *
8 * Last Modified: $Date$
9 *
10 * Description:
11 *
12 * This file contains the check_disk plugin
13 *
14 * License Information:
15 *
16 * This program is free software; you can redistribute it and/or modify
17 * it under the terms of the GNU General Public License as published by
18 * the Free Software Foundation; either version 2 of the License, or
19 * (at your option) any later version.
20 *
21 * This program is distributed in the hope that it will be useful,
22 * but WITHOUT ANY WARRANTY; without even the implied warranty of
23 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
24 * GNU General Public License for more details.
25 *
26 * You should have received a copy of the GNU General Public License
27 * along with this program; if not, write to the Free Software
28 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
29 *
30 * $Id$
31
32 *****************************************************************************/
34 const char *progname = "check_disk";
35 const char *program_name = "check_disk";  /* Required for coreutils libs */
36 const char *revision = "$Revision$";
37 const char *copyright = "1999-2006";
38 const char *email = "nagiosplug-devel@lists.sourceforge.net";
41 #include "common.h"
42 #ifdef HAVE_SYS_STAT_H
43 # include <sys/stat.h>
44 #endif
45 #if HAVE_INTTYPES_H
46 # include <inttypes.h>
47 #endif
48 #include <assert.h>
49 #include "popen.h"
50 #include "utils.h"
51 #include "utils_disk.h"
52 #include <stdarg.h>
53 #include "fsusage.h"
54 #include "mountlist.h"
55 #include "intprops.h"   /* necessary for TYPE_MAXIMUM */
56 #if HAVE_LIMITS_H
57 # include <limits.h>
58 #endif
61 /* If nonzero, show inode information. */
62 static int inode_format = 1;
64 /* If nonzero, show even filesystems with zero size or
65    uninteresting types. */
66 static int show_all_fs = 1;
68 /* If nonzero, show only local filesystems.  */
69 static int show_local_fs = 0;
71 /* If positive, the units to use when printing sizes;
72    if negative, the human-readable base.  */
73 /* static int output_block_size; */
75 /* If nonzero, invoke the `sync' system call before getting any usage data.
76    Using this option can make df very slow, especially with many or very
77    busy disks.  Note that this may make a difference on some systems --
78    SunOs4.1.3, for one.  It is *not* necessary on Linux.  */
79 /* static int require_sync = 0; */
81 /* Linked list of filesystem types to display.
82    If `fs_select_list' is NULL, list all types.
83    This table is generated dynamically from command-line options,
84    rather than hardcoding into the program what it thinks are the
85    valid filesystem types; let the user specify any filesystem type
86    they want to, and if there are any filesystems of that type, they
87    will be shown.
89    Some filesystem types:
90    4.2 4.3 ufs nfs swap ignore io vm efs dbg */
92 /* static struct parameter_list *fs_select_list; */
94 /* Linked list of filesystem types to omit.
95    If the list is empty, don't exclude any types.  */
97 static struct name_list *fs_exclude_list;
99 static struct name_list *dp_exclude_list;
101 static struct parameter_list *path_select_list = NULL;
103 /* Linked list of mounted filesystems. */
104 static struct mount_entry *mount_list;
106 /* For long options that have no equivalent short option, use a
107    non-character as a pseudo short option, starting with CHAR_MAX + 1.  */
108 enum
110   SYNC_OPTION = CHAR_MAX + 1,
111   NO_SYNC_OPTION,
112   BLOCK_SIZE_OPTION
113 };
115 #ifdef _AIX
116  #pragma alloca
117 #endif
119 /* Linked list of mounted filesystems. */
120 static struct mount_entry *mount_list;
122 int process_arguments (int, char **);
123 void print_path (const char *mypath);
124 void set_all_thresholds (struct parameter_list *path);
125 int validate_arguments (uintmax_t, uintmax_t, double, double, double, double, char *);
126 void print_help (void);
127 void print_usage (void);
128 double calculate_percent(uintmax_t, uintmax_t);
130 double w_dfp = -1.0;
131 double c_dfp = -1.0;
132 char *path;
133 char *exclude_device;
134 char *units;
135 uintmax_t mult = 1024 * 1024;
136 int verbose = 0;
137 int erronly = FALSE;
138 int display_mntp = FALSE;
139 int exact_match = FALSE;
140 char *warn_freespace_units = NULL;
141 char *crit_freespace_units = NULL;
142 char *warn_freespace_percent = NULL;
143 char *crit_freespace_percent = NULL;
144 char *warn_usedspace_units = NULL;
145 char *crit_usedspace_units = NULL;
146 char *warn_usedspace_percent = NULL;
147 char *crit_usedspace_percent = NULL;
148 char *warn_usedinodes_percent = NULL;
149 char *crit_usedinodes_percent = NULL;
150 char *warn_freeinodes_percent = NULL;
151 char *crit_freeinodes_percent = NULL;
152 bool path_selected = false;
155 int
156 main (int argc, char **argv)
158   int result = STATE_UNKNOWN;
159   int disk_result = STATE_UNKNOWN;
160   char *output;
161   char *details;
162   char *perf;
163   char *preamble;
164   double inode_space_pct;
165   uintmax_t total, available, available_to_root, used;
166   double dfree_pct = -1, dused_pct = -1;
167   double dused_units, dfree_units, dtotal_units;
168   double dused_inodes_percent, dfree_inodes_percent;
169   double warning_high_tide;
170   double critical_high_tide;
171   int temp_result;
173   struct mount_entry *me;
174   struct fs_usage fsp;
175   struct parameter_list *temp_list, *path;
176   struct name_list *seen = NULL;
178   preamble = strdup (" - free space:");
179   output = strdup ("");
180   details = strdup ("");
181   perf = strdup ("");
183   setlocale (LC_ALL, "");
184   bindtextdomain (PACKAGE, LOCALEDIR);
185   textdomain (PACKAGE);
187   mount_list = read_file_system_list (0);
189   if (process_arguments (argc, argv) == ERROR)
190     usage4 (_("Could not parse arguments"));
192   /* If a list of paths has not been selected, find entire
193      mount list and create list of paths
194    */
195   if (path_selected == false) { 
196     for (me = mount_list; me; me = me->me_next) {
197       if (! (path = np_find_parameter(path_select_list, me->me_mountdir))) {
198         path = np_add_parameter(&path_select_list, me->me_mountdir);
199       }
200       path->best_match = me;
201       set_all_thresholds(path);
202     }
203   }
204   np_set_best_match(path_select_list, mount_list, exact_match);
206   /* Error if no match found for specified paths */
207   temp_list = path_select_list;
208   while (temp_list) {
209     if (! temp_list->best_match) {
210       die (STATE_CRITICAL, _("DISK %s: %s not found\n"), _("CRITICAL"), temp_list->name);
211     }
212     temp_list = temp_list->name_next;
213   }
214   
216   /* Process for every path in list */
217   for (path = path_select_list; path; path=path->name_next) {
219     if (verbose > 3 && path->freespace_percent->warning != NULL && path->freespace_percent->critical != NULL)
220       printf("Thresholds(pct) for %s warn: %f crit %f\n",path->name, path->freespace_percent->warning->end,
221                                                          path->freespace_percent->critical->end);
223     /* reset disk result */
224     disk_result = STATE_UNKNOWN;
226     me = path->best_match;
228     /* Filters */
230     /* Remove filesystems already seen */
231     if (np_seen_name(seen, me->me_mountdir)) {
232       continue;
233     } else {
234       np_add_name(&seen, me->me_mountdir);
235     }
236     /* Skip remote filesystems if we're not interested in them */
237     if (me->me_remote && show_local_fs) {
238       continue;
239     /* Skip pseudo fs's if we haven't asked for all fs's */
240     } else if (me->me_dummy && !show_all_fs) {
241       continue;
242     /* Skip excluded fstypes */
243     } else if (fs_exclude_list && np_find_name (fs_exclude_list, me->me_type)) {
244       continue;
245     /* Skip excluded fs's */  
246     } else if (dp_exclude_list && 
247              (np_find_name (dp_exclude_list, me->me_devname) ||
248               np_find_name (dp_exclude_list, me->me_mountdir))) {
249       continue;
250     }
252     get_fs_usage (me->me_mountdir, me->me_devname, &fsp);
254     if (fsp.fsu_blocks && strcmp ("none", me->me_mountdir)) {
255       total = fsp.fsu_blocks;
256       available = fsp.fsu_bavail;
257       available_to_root = fsp.fsu_bfree;
258       used = total - available_to_root;
260       dused_pct = calculate_percent( used, used + available );  /* used + available can never be > uintmax */
261      
262       dfree_pct = 100 - dused_pct;
263       dused_units = used*fsp.fsu_blocksize/mult;
264       dfree_units = available*fsp.fsu_blocksize/mult;
265       dtotal_units = total*fsp.fsu_blocksize/mult;
266       dused_inodes_percent = calculate_percent(fsp.fsu_files - fsp.fsu_ffree, fsp.fsu_files);
267       dfree_inodes_percent = 100 - dused_inodes_percent;
269       if (verbose >= 3) {
270         printf ("For %s, used_pct=%g free_pct=%g used_units=%g free_units=%g total_units=%g used_inodes_pct=%g free_inodes_pct=%g\n", 
271           me->me_mountdir, dused_pct, dfree_pct, dused_units, dfree_units, dtotal_units, dused_inodes_percent, dfree_inodes_percent);
272       }
274       /* Threshold comparisons */
276       temp_result = get_status(dfree_units, path->freespace_units);
277       if (verbose >=3) printf("Freespace_units result=%d\n", temp_result);
278       disk_result = max_state( disk_result, temp_result );
280       temp_result = get_status(dfree_pct, path->freespace_percent);
281       if (verbose >=3) printf("Freespace%% result=%d\n", temp_result);
282       disk_result = max_state( disk_result, temp_result );
284       temp_result = get_status(dused_units, path->usedspace_units);
285       if (verbose >=3) printf("Usedspace_units result=%d\n", temp_result);
286       disk_result = max_state( disk_result, temp_result );
288       temp_result = get_status(dused_pct, path->usedspace_percent);
289       if (verbose >=3) printf("Usedspace_percent result=%d\n", temp_result);
290       disk_result = max_state( disk_result, temp_result );
292       temp_result = get_status(dused_inodes_percent, path->usedinodes_percent);
293       if (verbose >=3) printf("Usedinodes_percent result=%d\n", temp_result);
294       disk_result = max_state( disk_result, temp_result );
296       temp_result = get_status(dfree_inodes_percent, path->freeinodes_percent);
297       if (verbose >=3) printf("Freeinodes_percent result=%d\n", temp_result);
298       disk_result = max_state( disk_result, temp_result );
300       result = max_state(result, disk_result);
302       /* What a mess of units. The output shows free space, the perf data shows used space. Yikes!
303          Hack here. Trying to get warn/crit levels from freespace_(units|percent) for perf
304          data. Assumption that start=0. Roll on new syntax...
305       */
307       /* *_high_tide must be reinitialized at each run */
308       warning_high_tide = UINT_MAX;
309       critical_high_tide = UINT_MAX;
311       if (path->freespace_units->warning != NULL) {
312         warning_high_tide = dtotal_units - path->freespace_units->warning->end;
313       }
314       if (path->freespace_percent->warning != NULL) {
315         warning_high_tide = abs( min( (double) warning_high_tide, (double) (1.0 - path->freespace_percent->warning->end/100)*dtotal_units ));
316       }
317       if (path->freespace_units->critical != NULL) {
318         critical_high_tide = dtotal_units - path->freespace_units->critical->end;
319       }
320       if (path->freespace_percent->critical != NULL) {
321         critical_high_tide = abs( min( (double) critical_high_tide, (double) (1.0 - path->freespace_percent->critical->end/100)*dtotal_units ));
322       }
324       asprintf (&perf, "%s %s", perf,
325                 perfdata ((!strcmp(me->me_mountdir, "none") || display_mntp) ? me->me_devname : me->me_mountdir,
326                           dused_units, units,
327                           (warning_high_tide != UINT_MAX ? TRUE : FALSE), warning_high_tide,
328                           (critical_high_tide != UINT_MAX ? TRUE : FALSE), critical_high_tide,
329                           TRUE, 0,
330                           TRUE, dtotal_units));
332       if (disk_result==STATE_OK && erronly && !verbose)
333         continue;
335       if (disk_result!=STATE_OK || verbose>=0) {
336         asprintf (&output, "%s %s %.0f %s (%.0f%%",
337                   output,
338                   (!strcmp(me->me_mountdir, "none") || display_mntp) ? me->me_devname : me->me_mountdir,
339                   dfree_units,
340                   units,
341                   dfree_pct);
342         if (dused_inodes_percent < 0) {
343           asprintf(&output, "%s inode=-);", output);
344         } else {
345           asprintf(&output, "%s inode=%.0f%%);", output, dfree_inodes_percent );
346         }
347       }
349       /* TODO: Need to do a similar debug line
350       asprintf (&details, _("%s\n\
351 %.0f of %.0f %s (%.0f%% inode=%.0f%%) free on %s (type %s mounted on %s) warn:%lu crit:%lu warn%%:%.0f%% crit%%:%.0f%%"),
352                 details, dfree_units, dtotal_units, units, dfree_pct, inode_space_pct,
353                 me->me_devname, me->me_type, me->me_mountdir,
354                 (unsigned long)w_df, (unsigned long)c_df, w_dfp, c_dfp);
355       */
357     }
359   }
361   if (verbose > 2)
362     asprintf (&output, "%s%s", output, details);
365   printf ("DISK %s%s%s|%s\n", state_text (result), (erronly && result==STATE_OK) ? "" : preamble, output, perf);
366   return result;
370 double calculate_percent(uintmax_t value, uintmax_t total) {
371   double pct = -1;
372   /* I don't understand the below, but it is taken from coreutils' df */
373   /* Seems to be calculating pct, in the best possible way */
374   if (value <= TYPE_MAXIMUM(uintmax_t) / 100 
375     && total != 0) {
376     uintmax_t u100 = value * 100;
377     pct = u100 / total + (u100 % total != 0);
378   } else {
379     /* Possible rounding errors - see coreutils' df for more explanation */
380     double u = value;
381     double t = total;
382     if (t) {
383       long int lipct = pct = u * 100 / t;
384       double ipct = lipct;
386       /* Like 'pct = ceil (dpct);', but without ceil - from coreutils again */
387       if (ipct - 1 < pct && pct <= ipct + 1)
388         pct = ipct + (ipct < pct);
389     }
390   }
391   return pct;
394 /* process command-line arguments */
395 int
396 process_arguments (int argc, char **argv)
398   int c;
399   struct parameter_list *se;
400   struct parameter_list *temp_list;
401   int result = OK;
402   struct stat *stat_buf;
404   int option = 0;
405   static struct option longopts[] = {
406     {"timeout", required_argument, 0, 't'},
407     {"warning", required_argument, 0, 'w'},
408     {"critical", required_argument, 0, 'c'},
409     {"iwarning", required_argument, 0, 'W'},
410     /* Dang, -C is taken. We might want to reshuffle this. */
411     {"icritical", required_argument, 0, 'K'},
412     {"local", required_argument, 0, 'l'},
413     {"kilobytes", required_argument, 0, 'k'},
414     {"megabytes", required_argument, 0, 'm'},
415     {"units", required_argument, 0, 'u'},
416     {"path", required_argument, 0, 'p'},
417     {"partition", required_argument, 0, 'p'},
418     {"exclude_device", required_argument, 0, 'x'},
419     {"exclude-type", required_argument, 0, 'X'},
420     {"mountpoint", no_argument, 0, 'M'},
421     {"errors-only", no_argument, 0, 'e'},
422     {"exact-match", no_argument, 0, 'E'},
423     {"verbose", no_argument, 0, 'v'},
424     {"quiet", no_argument, 0, 'q'},
425     {"clear", no_argument, 0, 'C'},
426     {"version", no_argument, 0, 'V'},
427     {"help", no_argument, 0, 'h'},
428     {0, 0, 0, 0}
429   };
431   if (argc < 2)
432     return ERROR;
434   np_add_name(&fs_exclude_list, "iso9660");
436   for (c = 1; c < argc; c++)
437     if (strcmp ("-to", argv[c]) == 0)
438       strcpy (argv[c], "-t");
440   while (1) {
441     c = getopt_long (argc, argv, "+?VqhveCt:c:w:K:W:u:p:x:X:mklME", longopts, &option);
443     if (c == -1 || c == EOF)
444       break;
446     switch (c) {
447     case 't':                 /* timeout period */
448       if (is_integer (optarg)) {
449         timeout_interval = atoi (optarg);
450         break;
451       }
452       else {
453         usage2 (_("Timeout interval must be a positive integer"), optarg);
454       }
456     /* See comments for 'c' */
457     case 'w':                 /* warning threshold */
458       if (strstr(optarg, "%")) {
459         if (*optarg == '@') {
460           warn_freespace_percent = optarg;
461         } else {
462           asprintf(&warn_freespace_percent, "@%s", optarg);
463         }
464       } else {
465         if (*optarg == '@') {
466           warn_freespace_units = optarg;
467         } else {
468           asprintf(&warn_freespace_units, "@%s", optarg);
469         }
470       }
471       break;
473     /* Awful mistake where the range values do not make sense. Normally, 
474        you alert if the value is within the range, but since we are using
475        freespace, we have to alert if outside the range. Thus we artifically
476        force @ at the beginning of the range, so that it is backwards compatible
477     */
478     case 'c':                 /* critical threshold */
479       if (strstr(optarg, "%")) {
480         if (*optarg == '@') {
481           crit_freespace_percent = optarg;
482         } else {
483           asprintf(&crit_freespace_percent, "@%s", optarg);
484         }
485       } else {
486         if (*optarg == '@') {
487           crit_freespace_units = optarg;
488         } else {
489           asprintf(&crit_freespace_units, "@%s", optarg);
490         }
491       }
492       break;
494     case 'W':                   /* warning inode threshold */
495       if (*optarg == '@') {
496         warn_freeinodes_percent = optarg;
497       } else {
498         asprintf(&warn_freeinodes_percent, "@%s", optarg);
499       }
500       break;
501     case 'K':                   /* critical inode threshold */
502       if (*optarg == '@') {
503         crit_freeinodes_percent = optarg;
504       } else {
505         asprintf(&crit_freeinodes_percent, "@%s", optarg);
506       }
507       break;
508     case 'u':
509       if (units)
510         free(units);
511       if (! strcmp (optarg, "bytes")) {
512         mult = (uintmax_t)1;
513         units = strdup ("B");
514       } else if (! strcmp (optarg, "kB")) {
515         mult = (uintmax_t)1024;
516         units = strdup ("kB");
517       } else if (! strcmp (optarg, "MB")) {
518         mult = (uintmax_t)1024 * 1024;
519         units = strdup ("MB");
520       } else if (! strcmp (optarg, "GB")) {
521         mult = (uintmax_t)1024 * 1024 * 1024;
522         units = strdup ("GB");
523       } else if (! strcmp (optarg, "TB")) {
524         mult = (uintmax_t)1024 * 1024 * 1024 * 1024;
525         units = strdup ("TB");
526       } else {
527         die (STATE_UNKNOWN, _("unit type %s not known\n"), optarg);
528       }
529       if (units == NULL)
530         die (STATE_UNKNOWN, _("failed allocating storage for '%s'\n"), "units");
531       break;
532     case 'k': /* display mountpoint */
533       mult = 1024;
534       if (units)
535         free(units);
536       units = strdup ("kB");
537       break;
538     case 'm': /* display mountpoint */
539       mult = 1024 * 1024;
540       if (units)
541         free(units);
542       units = strdup ("MB");
543       break;
544     case 'l':
545       show_local_fs = 1;      
546       break;
547     case 'p':                 /* select path */
548       if (! (warn_freespace_units || crit_freespace_units || warn_freespace_percent || 
549              crit_freespace_percent || warn_usedspace_units || crit_usedspace_units ||
550              warn_usedspace_percent || crit_usedspace_percent || warn_usedinodes_percent ||
551              crit_usedinodes_percent || warn_freeinodes_percent || crit_freeinodes_percent )) {
552         die (STATE_UNKNOWN, "DISK %s: %s", _("UNKNOWN"), _("Must set a threshold value before using -p\n"));
553       }
555       /* add parameter if not found. overwrite thresholds if path has already been added  */
556       if (! (se = np_find_parameter(path_select_list, optarg))) {
557           se = np_add_parameter(&path_select_list, optarg);
558       }
560       set_all_thresholds(se);
561       path_selected = true;
562       break;
563     case 'x':                 /* exclude path or partition */
564       np_add_name(&dp_exclude_list, optarg);
565       break;
566     case 'X':                 /* exclude file system type */
567       np_add_name(&fs_exclude_list, optarg);
568       break;
569     case 'v':                 /* verbose */
570       verbose++;
571       break;
572     case 'q':                 /* verbose */
573       verbose--;
574       break;
575     case 'e':
576       erronly = TRUE;
577       break;
578     case 'E':
579       exact_match = TRUE;
580       break;
581     case 'M': /* display mountpoint */
582       display_mntp = TRUE;
583       break;
584     case 'C':
585        /* add all mount entries to path_select list if no partitions have been explicitly defined using -p */
586        if (path_selected == false) {
587          struct mount_entry *me;
588          struct parameter_list *path;
589          for (me = mount_list; me; me = me->me_next) {
590            if (! (path = np_find_parameter(path_select_list, me->me_mountdir))) 
591              path = np_add_parameter(&path_select_list, me->me_mountdir);
592            path->best_match = me;
593            set_all_thresholds(path);
594          }
595       }
596       warn_freespace_units = NULL;
597       crit_freespace_units = NULL;
598       warn_usedspace_units = NULL;
599       crit_usedspace_units = NULL;
600       warn_freespace_percent = NULL;
601       crit_freespace_percent = NULL;
602       warn_usedspace_percent = NULL;
603       crit_usedspace_percent = NULL;
604       warn_usedinodes_percent = NULL;
605       crit_usedinodes_percent = NULL;
606       warn_freeinodes_percent = NULL;
607       crit_freeinodes_percent = NULL;
608     
609       path_selected = false;
610       break;
611     case 'V':                 /* version */
612       print_revision (progname, revision);
613       exit (STATE_OK);
614     case 'h':                 /* help */
615       print_help ();
616       exit (STATE_OK);
617     case '?':                 /* help */
618       usage (_("Unknown argument"));
619     }
620   }
622   /* Support for "check_disk warn crit [fs]" with thresholds at used% level */
623   c = optind;
624   if (warn_usedspace_percent == NULL && argc > c && is_intnonneg (argv[c]))
625     warn_usedspace_percent = argv[c++];
627   if (crit_usedspace_percent == NULL && argc > c && is_intnonneg (argv[c]))
628     crit_usedspace_percent = argv[c++];
630   if (argc > c && path == NULL) {
631     se = np_add_parameter(&path_select_list, strdup(argv[c++]));
632     set_all_thresholds(se);
633   }
635   if (units == NULL) {
636     units = strdup ("MB");
637     mult = (uintmax_t)1024 * 1024;
638   }
640   if (path_select_list) {
641     temp_list = path_select_list;
642     stat_buf = malloc(sizeof *stat_buf);
643     while (temp_list) {
644       /* Stat each entry to check that dir exists */
645       if (stat (temp_list->name, &stat_buf[0])) {
646         printf("DISK %s - ", _("CRITICAL"));
647         die (STATE_CRITICAL, _("%s does not exist\n"), temp_list->name);
648       }
649       /* if (validate_arguments (temp_list->w_df,
650                               temp_list->c_df,
651                               temp_list->w_dfp,
652                               temp_list->c_dfp,
653                               temp_list->w_idfp,
654                               temp_list->c_idfp,
655                               temp_list->name) == ERROR)
656         result = ERROR;
657       */
658       temp_list = temp_list->name_next;
659     }
660     free(stat_buf);
661     return result;
662   } else {
663     return TRUE;
664     /* return validate_arguments (w_df, c_df, w_dfp, c_dfp, w_idfp, c_idfp, NULL); */
665   }
670 void
671 print_path (const char *mypath) 
673   if (mypath == NULL)
674     printf ("\n");
675   else
676     printf (_(" for %s\n"), mypath);
680 void
681 set_all_thresholds (struct parameter_list *path) 
683     set_thresholds(&path->freespace_units, warn_freespace_units, crit_freespace_units);
684     set_thresholds(&path->freespace_percent, warn_freespace_percent, crit_freespace_percent);
685     set_thresholds(&path->usedspace_units, warn_usedspace_units, crit_usedspace_units);
686     set_thresholds(&path->usedspace_percent, warn_usedspace_percent, crit_usedspace_percent);
687     set_thresholds(&path->usedinodes_percent, warn_usedinodes_percent, crit_usedinodes_percent);
688     set_thresholds(&path->freeinodes_percent, warn_freeinodes_percent, crit_freeinodes_percent);
691 /* TODO: Remove?
693 int
694 validate_arguments (uintmax_t w, uintmax_t c, double wp, double cp, double iwp, double icp, char *mypath)
696   if (w < 0 && c < 0 && wp < 0.0 && cp < 0.0) {
697     printf (_("INPUT ERROR: No thresholds specified"));
698     print_path (mypath);
699     return ERROR;
700   }
701   else if ((wp >= 0.0 || cp >= 0.0) &&
702            (wp < 0.0 || cp < 0.0 || wp > 100.0 || cp > 100.0 || cp > wp)) {
703     printf (_("\
704 INPUT ERROR: C_DFP (%f) should be less than W_DFP (%.1f) and both should be between zero and 100 percent, inclusive"),
705             cp, wp);
706     print_path (mypath);
707     return ERROR;
708   }
709   else if ((iwp >= 0.0 || icp >= 0.0) &&
710            (iwp < 0.0 || icp < 0.0 || iwp > 100.0 || icp > 100.0 || icp > iwp)) {
711     printf (_("\
712 INPUT ERROR: C_IDFP (%f) should be less than W_IDFP (%.1f) and both should be between zero and 100 percent, inclusive"),
713             icp, iwp);
714     print_path (mypath);
715     return ERROR;
716   }
717   else if ((w > 0 || c > 0) && (w == 0 || c == 0 || c > w)) {
718     printf (_("\
719 INPUT ERROR: C_DF (%lu) should be less than W_DF (%lu) and both should be greater than zero"),
720             (unsigned long)c, (unsigned long)w);
721     print_path (mypath);
722     return ERROR;
723   }
724   
725   return OK;
728 */
736 void
737 print_help (void)
739   print_revision (progname, revision);
741   printf ("Copyright (c) 1999 Ethan Galstad <nagios@nagios.org>\n");
742   printf (COPYRIGHT, copyright, email);
744   printf ("%s\n", _("This plugin checks the amount of used disk space on a mounted file system"));
745   printf ("%s\n", _("and generates an alert if free space is less than one of the threshold values"));
747   printf ("\n\n");
749   print_usage ();
751   printf (_(UT_HELP_VRSN));
753   printf (" %s\n", "-w, --warning=INTEGER");
754   printf ("    %s\n", _("Exit with WARNING status if less than INTEGER units of disk are free"));
755   printf (" %s\n", "-w, --warning=PERCENT%");
756   printf ("    %s\n", _("Exit with WARNING status if less than PERCENT of disk space is free"));
757   printf (" %s\n", "-W, --iwarning=PERCENT%");
758   printf ("    %s\n", _("Exit with WARNING status if less than PERCENT of inode space is free"));
759   printf (" %s\n", "-K, --icritical=PERCENT%");
760   printf ("    %s\n", _("Exit with CRITICAL status if less than PERCENT of inode space is free"));
761   printf (" %s\n", "-c, --critical=INTEGER");
762   printf ("    %s\n", _("Exit with CRITICAL status if less than INTEGER units of disk are free"));
763   printf (" %s\n", "-c, --critical=PERCENT%");
764   printf ("    %s\n", _("Exit with CRITCAL status if less than PERCENT of disk space is free"));
765   printf (" %s\n", "-C, --clear");
766   printf ("    %s\n", _("Clear thresholds"));
767   printf (" %s\n", "-u, --units=STRING");
768   printf ("    %s\n", _("Choose bytes, kB, MB, GB, TB (default: MB)"));
769   printf (" %s\n", "-k, --kilobytes");
770   printf ("    %s\n", _("Same as '--units kB'"));
771   printf (" %s\n", "-m, --megabytes");
772   printf ("    %s\n", _("Same as '--units MB'"));
773   printf (" %s\n", "-l, --local");
774   printf ("    %s\n", _("Only check local filesystems"));
775   printf (" %s\n", "-p, --path=PATH, --partition=PARTITION");
776   printf ("    %s\n", _("Path or partition (may be repeated)"));
777   printf (" %s\n", "-x, --exclude_device=PATH <STRING>");
778   printf ("    %s\n", _("Ignore device (only works if -p unspecified)"));
779   printf (" %s\n", "-X, --exclude-type=TYPE <STRING>");
780   printf ("    %s\n", _("Ignore all filesystems of indicated type (may be repeated)"));
781   printf (" %s\n", "-M, --mountpoint");
782   printf ("    %s\n", _("Display the mountpoint instead of the partition"));
783   printf (" %s\n", "-E, --exact-match");
784   printf ("    %s\n", _("For paths or partitions specified with -p, only check for exact paths"));
785   printf (" %s\n", "-e, --errors-only");
786   printf ("    %s\n", _("Display only devices/mountpoints with errors"));
787   printf (_(UT_TIMEOUT), DEFAULT_SOCKET_TIMEOUT);
788   printf (_(UT_VERBOSE));
789   printf ("\n");
790   printf ("%s\n", _("Examples:"));
791   printf (" %s\n", "check_disk -w 10% -c 5% -p /tmp -p /var -C -w 100000 -c 50000 -p /");
792   printf ("    %s\n", _("Checks /tmp and /var at 10% and 5%, and / at 100MB and 50MB"));
793   printf (_(UT_SUPPORT));
798 void
799 print_usage (void)
801   printf (_("Usage:"));
802   printf (" %s -w limit -c limit [-p path | -x device] [-t timeout]", progname);
803   printf ("[-m] [-e] [-W limit] [-K limit] [-v] [-q] [-E]\n");