Code

Fixed output from -e in check_disk (Andreas Behal)
[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 #if HAVE_INTTYPES_H
43 # include <inttypes.h>
44 #endif
45 #include <assert.h>
46 #include "popen.h"
47 #include "utils.h"
48 #include "utils_disk.h"
49 #include <stdarg.h>
50 #include "fsusage.h"
51 #include "mountlist.h"
52 #include "intprops.h"   /* necessary for TYPE_MAXIMUM */
53 #if HAVE_LIMITS_H
54 # include <limits.h>
55 #endif
58 /* If nonzero, show inode information. */
59 static int inode_format = 1;
61 /* If nonzero, show even filesystems with zero size or
62    uninteresting types. */
63 static int show_all_fs = 1;
65 /* If nonzero, show only local filesystems.  */
66 static int show_local_fs = 0;
68 /* If positive, the units to use when printing sizes;
69    if negative, the human-readable base.  */
70 /* static int output_block_size; */
72 /* If nonzero, invoke the `sync' system call before getting any usage data.
73    Using this option can make df very slow, especially with many or very
74    busy disks.  Note that this may make a difference on some systems --
75    SunOs4.1.3, for one.  It is *not* necessary on Linux.  */
76 /* static int require_sync = 0; */
78 /* Linked list of filesystem types to display.
79    If `fs_select_list' is NULL, list all types.
80    This table is generated dynamically from command-line options,
81    rather than hardcoding into the program what it thinks are the
82    valid filesystem types; let the user specify any filesystem type
83    they want to, and if there are any filesystems of that type, they
84    will be shown.
86    Some filesystem types:
87    4.2 4.3 ufs nfs swap ignore io vm efs dbg */
89 /* static struct parameter_list *fs_select_list; */
91 /* Linked list of filesystem types to omit.
92    If the list is empty, don't exclude any types.  */
94 static struct name_list *fs_exclude_list;
96 static struct name_list *dp_exclude_list;
98 static struct parameter_list *path_select_list = NULL;
100 /* Linked list of mounted filesystems. */
101 static struct mount_entry *mount_list;
103 /* For long options that have no equivalent short option, use a
104    non-character as a pseudo short option, starting with CHAR_MAX + 1.  */
105 enum
107   SYNC_OPTION = CHAR_MAX + 1,
108   NO_SYNC_OPTION,
109   BLOCK_SIZE_OPTION
110 };
112 #ifdef _AIX
113  #pragma alloca
114 #endif
116 /* Linked list of mounted filesystems. */
117 static struct mount_entry *mount_list;
119 int process_arguments (int, char **);
120 void print_path (const char *mypath);
121 int validate_arguments (uintmax_t, uintmax_t, double, double, double, double, char *);
122 void print_help (void);
123 void print_usage (void);
124 double calculate_percent(uintmax_t, uintmax_t);
126 double w_dfp = -1.0;
127 double c_dfp = -1.0;
128 char *path;
129 char *exclude_device;
130 char *units;
131 uintmax_t mult = 1024 * 1024;
132 int verbose = 0;
133 int erronly = FALSE;
134 int display_mntp = FALSE;
135 int exact_match = FALSE;
136 char *warn_freespace_units = NULL;
137 char *crit_freespace_units = NULL;
138 char *warn_freespace_percent = NULL;
139 char *crit_freespace_percent = NULL;
140 char *warn_usedspace_units = NULL;
141 char *crit_usedspace_units = NULL;
142 char *warn_usedspace_percent = NULL;
143 char *crit_usedspace_percent = NULL;
144 char *warn_usedinodes_percent = NULL;
145 char *crit_usedinodes_percent = NULL;
148 int
149 main (int argc, char **argv)
151   int result = STATE_UNKNOWN;
152   int disk_result = STATE_UNKNOWN;
153   char *output;
154   char *details;
155   char *perf;
156   double inode_space_pct;
157   uintmax_t total, available, available_to_root, used;
158   double dfree_pct = -1, dused_pct = -1;
159   double dused_units, dfree_units, dtotal_units;
160   double dused_inodes_percent, dfree_inodes_percent;
161   int temp_result;
163   struct mount_entry *me;
164   struct fs_usage fsp;
165   struct parameter_list *temp_list, *path;
166   struct name_list *seen = NULL;
168   output = strdup (" - free space:");
169   details = strdup ("");
170   perf = strdup ("");
172   setlocale (LC_ALL, "");
173   bindtextdomain (PACKAGE, LOCALEDIR);
174   textdomain (PACKAGE);
176   mount_list = read_file_system_list (0);
178   if (process_arguments (argc, argv) == ERROR)
179     usage4 (_("Could not parse arguments"));
181   /* If a list of paths has not been selected, find entire
182      mount list and create list of paths
183    */
184   if (! path_select_list) {
185     for (me = mount_list; me; me = me->me_next) {
186       path = np_add_parameter(&path_select_list, me->me_mountdir);
187       path->best_match = me;
188       set_thresholds(&path->freespace_units, warn_freespace_units, crit_freespace_units);
189       set_thresholds(&path->freespace_percent, warn_freespace_percent, crit_freespace_percent);
190       set_thresholds(&path->usedspace_units, warn_usedspace_units, crit_usedspace_units);
191       set_thresholds(&path->usedspace_percent, warn_usedspace_percent, crit_usedspace_percent);
192       set_thresholds(&path->usedinodes_percent, warn_usedinodes_percent, crit_usedinodes_percent);
193     }
194   } else {
195     np_set_best_match(path_select_list, mount_list, exact_match);
197     /* Error if no match found for specified paths */
198     temp_list = path_select_list;
199     while (temp_list) {
200       if (! temp_list->best_match) {
201         die (STATE_CRITICAL, _("DISK %s: %s not found\n"), _("CRITICAL"), temp_list->name);
202       }
203       temp_list = temp_list->name_next;
204     }
205   }
207   /* Process for every path in list */
208   for (path = path_select_list; path; path=path->name_next) {
210     /* reset disk result */
211     disk_result = STATE_UNKNOWN;
213     me = path->best_match;
215     /* Filters */
217     /* Remove filesystems already seen */
218     if (np_seen_name(seen, me->me_mountdir)) {
219       continue;
220     } else {
221       np_add_name(&seen, me->me_mountdir);
222     }
223     /* Skip remote filesystems if we're not interested in them */
224     if (me->me_remote && show_local_fs) {
225       continue;
226     /* Skip pseudo fs's if we haven't asked for all fs's */
227     } else if (me->me_dummy && !show_all_fs) {
228       continue;
229     /* Skip excluded fstypes */
230     } else if (fs_exclude_list && np_find_name (fs_exclude_list, me->me_type)) {
231       continue;
232     /* Skip excluded fs's */  
233     } else if (dp_exclude_list && 
234              (np_find_name (dp_exclude_list, me->me_devname) ||
235               np_find_name (dp_exclude_list, me->me_mountdir))) {
236       continue;
237     }
239     get_fs_usage (me->me_mountdir, me->me_devname, &fsp);
241     if (fsp.fsu_blocks && strcmp ("none", me->me_mountdir)) {
242       total = fsp.fsu_blocks;
243       available = fsp.fsu_bavail;
244       available_to_root = fsp.fsu_bfree;
245       used = total - available_to_root;
247       dused_pct = calculate_percent( used, used + available );  /* used + available can never be > uintmax */
248      
249       dfree_pct = 100 - dused_pct;
250       dused_units = used*fsp.fsu_blocksize/mult;
251       dfree_units = available*fsp.fsu_blocksize/mult;
252       dtotal_units = total*fsp.fsu_blocksize/mult;
253       dused_inodes_percent = calculate_percent(fsp.fsu_files - fsp.fsu_ffree, fsp.fsu_files);
254       dfree_inodes_percent = 100 - dused_inodes_percent;
256       if (verbose >= 3) {
257         printf ("For %s, used_pct=%g free_pct=%g used_units=%g free_units=%g total_units=%g used_inodes_pct=%g\n", 
258           me->me_mountdir, dused_pct, dfree_pct, dused_units, dfree_units, dtotal_units, dused_inodes_percent);
259       }
261       /* Threshold comparisons */
263       temp_result = get_status(dfree_units, path->freespace_units);
264       if (verbose >=3) printf("Freespace_units result=%d\n", temp_result);
265       disk_result = max_state( disk_result, temp_result );
267       temp_result = get_status(dfree_pct, path->freespace_percent);
268       if (verbose >=3) printf("Freespace%% result=%d\n", temp_result);
269       disk_result = max_state( disk_result, temp_result );
271       temp_result = get_status(dused_units, path->usedspace_units);
272       if (verbose >=3) printf("Usedspace_units result=%d\n", temp_result);
273       disk_result = max_state( disk_result, temp_result );
275       temp_result = get_status(dused_pct, path->usedspace_percent);
276       if (verbose >=3) printf("Usedspace_percent result=%d\n", temp_result);
277       disk_result = max_state( disk_result, temp_result );
279       temp_result = get_status(dused_inodes_percent, path->usedinodes_percent);
280       if (verbose >=3) printf("Usedinodes_percent result=%d\n", temp_result);
281       disk_result = max_state( disk_result, temp_result );
283       result = max_state(result, disk_result);
285       asprintf (&perf, "%s %s", perf,
286                 perfdata ((!strcmp(me->me_mountdir, "none") || display_mntp) ? me->me_devname : me->me_mountdir,
287                           dused_units, units,
288                           FALSE, 0, /* min ((uintmax_t)dtotal_units-(uintmax_t)w_df, (uintmax_t)((1.0-w_dfp/100.0)*dtotal_units)), */
289                           FALSE, 0, /* min ((uintmax_t)dtotal_units-(uintmax_t)c_df, (uintmax_t)((1.0-c_dfp/100.0)*dtotal_units)), */
290                           FALSE, 0, /* inode_space_pct - this is not meant to be here???, */
291                           FALSE, 0));; /* dtotal_units)); */
293       if (disk_result==STATE_OK && erronly && !verbose)
294         continue;
296       if (disk_result!=STATE_OK || verbose>=0) {
297         asprintf (&output, "%s %s %.0f %s (%.0f%%",
298                   output,
299                   (!strcmp(me->me_mountdir, "none") || display_mntp) ? me->me_devname : me->me_mountdir,
300                   dfree_units,
301                   units,
302                   dfree_pct);
303         if (dused_inodes_percent < 0) {
304           asprintf(&output, "%s inode=-);", output);
305         } else {
306           asprintf(&output, "%s inode=%.0f%%);", output, dfree_inodes_percent );
307         }
308       }
310       /* TODO: Need to do a similar debug line
311       asprintf (&details, _("%s\n\
312 %.0f of %.0f %s (%.0f%% inode=%.0f%%) free on %s (type %s mounted on %s) warn:%lu crit:%lu warn%%:%.0f%% crit%%:%.0f%%"),
313                 details, dfree_units, dtotal_units, units, dfree_pct, inode_space_pct,
314                 me->me_devname, me->me_type, me->me_mountdir,
315                 (unsigned long)w_df, (unsigned long)c_df, w_dfp, c_dfp);
316       */
318     }
320   }
322   if (verbose > 2)
323     asprintf (&output, "%s%s", output, details);
326   printf ("DISK %s%s|%s\n", state_text (result), output, perf);
327   return result;
331 double calculate_percent(uintmax_t value, uintmax_t total) {
332   double pct = -1;
333   /* I don't understand the below, but it is taken from coreutils' df */
334   /* Seems to be calculating pct, in the best possible way */
335   if (value <= TYPE_MAXIMUM(uintmax_t) / 100 
336     && total != 0) {
337     uintmax_t u100 = value * 100;
338     pct = u100 / total + (u100 % total != 0);
339   } else {
340     /* Possible rounding errors - see coreutils' df for more explanation */
341     double u = value;
342     double t = total;
343     if (t) {
344       long int lipct = pct = u * 100 / t;
345       double ipct = lipct;
347       /* Like 'pct = ceil (dpct);', but without ceil - from coreutils again */
348       if (ipct - 1 < pct && pct <= ipct + 1)
349         pct = ipct + (ipct < pct);
350     }
351   }
352   return pct;
355 /* process command-line arguments */
356 int
357 process_arguments (int argc, char **argv)
359   int c;
360   struct parameter_list *se;
361   struct parameter_list *temp_list;
362   int result = OK;
363   struct stat *stat_buf;
365   int option = 0;
366   static struct option longopts[] = {
367     {"timeout", required_argument, 0, 't'},
368     {"warning", required_argument, 0, 'w'},
369     {"critical", required_argument, 0, 'c'},
370     {"iwarning", required_argument, 0, 'W'},
371     /* Dang, -C is taken. We might want to reshuffle this. */
372     {"icritical", required_argument, 0, 'K'},
373     {"local", required_argument, 0, 'l'},
374     {"kilobytes", required_argument, 0, 'k'},
375     {"megabytes", required_argument, 0, 'm'},
376     {"units", required_argument, 0, 'u'},
377     {"path", required_argument, 0, 'p'},
378     {"partition", required_argument, 0, 'p'},
379     {"exclude_device", required_argument, 0, 'x'},
380     {"exclude-type", required_argument, 0, 'X'},
381     {"mountpoint", no_argument, 0, 'M'},
382     {"errors-only", no_argument, 0, 'e'},
383     {"exact-match", no_argument, 0, 'E'},
384     {"verbose", no_argument, 0, 'v'},
385     {"quiet", no_argument, 0, 'q'},
386     {"clear", no_argument, 0, 'C'},
387     {"version", no_argument, 0, 'V'},
388     {"help", no_argument, 0, 'h'},
389     {0, 0, 0, 0}
390   };
392   if (argc < 2)
393     return ERROR;
395   np_add_name(&fs_exclude_list, "iso9660");
397   for (c = 1; c < argc; c++)
398     if (strcmp ("-to", argv[c]) == 0)
399       strcpy (argv[c], "-t");
401   while (1) {
402     c = getopt_long (argc, argv, "+?VqhveCt:c:w:K:W:u:p:x:X:mklME", longopts, &option);
404     if (c == -1 || c == EOF)
405       break;
407     switch (c) {
408     case 't':                 /* timeout period */
409       if (is_integer (optarg)) {
410         timeout_interval = atoi (optarg);
411         break;
412       }
413       else {
414         usage2 (_("Timeout interval must be a positive integer"), optarg);
415       }
417     /* See comments for 'c' */
418     case 'w':                 /* warning threshold */
419       if (strstr(optarg, "%")) {
420         if (*optarg == '@') {
421           warn_freespace_percent = optarg;
422         } else {
423           asprintf(&warn_freespace_percent, "@%s", optarg);
424         }
425       } else {
426         if (*optarg == '@') {
427           warn_freespace_units = optarg;
428         } else {
429           asprintf(&warn_freespace_units, "@%s", optarg);
430         }
431       }
432       break;
434     /* Awful mistake where the range values do not make sense. Normally, 
435        you alert if the value is within the range, but since we are using
436        freespace, we have to alert if outside the range. Thus we artifically
437        force @ at the beginning of the range, so that it is backwards compatible
438     */
439     case 'c':                 /* critical threshold */
440       if (strstr(optarg, "%")) {
441         if (*optarg == '@') {
442           crit_freespace_percent = optarg;
443         } else {
444           asprintf(&crit_freespace_percent, "@%s", optarg);
445         }
446       } else {
447         if (*optarg == '@') {
448           crit_freespace_units = optarg;
449         } else {
450           asprintf(&crit_freespace_units, "@%s", optarg);
451         }
452       }
453       break;
455     case 'W':                   /* warning inode threshold */
456       warn_usedinodes_percent = optarg;
457       break;
458     case 'K':                   /* critical inode threshold */
459       crit_usedinodes_percent = optarg;
460       break;
461     case 'u':
462       if (units)
463         free(units);
464       if (! strcmp (optarg, "bytes")) {
465         mult = (uintmax_t)1;
466         units = strdup ("B");
467       } else if (! strcmp (optarg, "kB")) {
468         mult = (uintmax_t)1024;
469         units = strdup ("kB");
470       } else if (! strcmp (optarg, "MB")) {
471         mult = (uintmax_t)1024 * 1024;
472         units = strdup ("MB");
473       } else if (! strcmp (optarg, "GB")) {
474         mult = (uintmax_t)1024 * 1024 * 1024;
475         units = strdup ("GB");
476       } else if (! strcmp (optarg, "TB")) {
477         mult = (uintmax_t)1024 * 1024 * 1024 * 1024;
478         units = strdup ("TB");
479       } else {
480         die (STATE_UNKNOWN, _("unit type %s not known\n"), optarg);
481       }
482       if (units == NULL)
483         die (STATE_UNKNOWN, _("failed allocating storage for '%s'\n"), "units");
484       break;
485     case 'k': /* display mountpoint */
486       mult = 1024;
487       if (units)
488         free(units);
489       units = strdup ("kB");
490       break;
491     case 'm': /* display mountpoint */
492       mult = 1024 * 1024;
493       if (units)
494         free(units);
495       units = strdup ("MB");
496       break;
497     case 'l':
498       show_local_fs = 1;      
499       break;
500     case 'p':                 /* select path */
501       if (! (warn_freespace_units || crit_freespace_units || warn_freespace_percent || 
502              crit_freespace_percent || warn_usedspace_units || crit_usedspace_units ||
503              warn_usedspace_percent || crit_usedspace_percent || warn_usedinodes_percent ||
504              crit_usedinodes_percent)) {
505         die (STATE_UNKNOWN, "DISK %s: %s", _("UNKNOWN"), _("Must set a threshold value before using -p\n"));
506       }
507       se = np_add_parameter(&path_select_list, optarg);
508       set_thresholds(&se->freespace_units, warn_freespace_units, crit_freespace_units);
509       set_thresholds(&se->freespace_percent, warn_freespace_percent, crit_freespace_percent);
510       set_thresholds(&se->usedspace_units, warn_usedspace_units, crit_usedspace_units);
511       set_thresholds(&se->usedspace_percent, warn_usedspace_percent, crit_usedspace_percent);
512       set_thresholds(&se->usedinodes_percent, warn_usedinodes_percent, crit_usedinodes_percent);
513       break;
514     case 'x':                 /* exclude path or partition */
515       np_add_name(&dp_exclude_list, optarg);
516       break;
517     case 'X':                 /* exclude file system type */
518       np_add_name(&fs_exclude_list, optarg);
519       break;
520     case 'v':                 /* verbose */
521       verbose++;
522       break;
523     case 'q':                 /* verbose */
524       verbose--;
525       break;
526     case 'e':
527       erronly = TRUE;
528       break;
529     case 'E':
530       exact_match = TRUE;
531       break;
532     case 'M': /* display mountpoint */
533       display_mntp = TRUE;
534       break;
535     case 'C':
536       warn_freespace_units = NULL;
537       crit_freespace_units = NULL;
538       warn_usedspace_units = NULL;
539       crit_usedspace_units = NULL;
540       warn_freespace_percent = NULL;
541       crit_freespace_percent = NULL;
542       warn_usedspace_percent = NULL;
543       crit_usedspace_percent = NULL;
544       warn_usedinodes_percent = NULL;
545       crit_usedinodes_percent = NULL;
546       break;
547     case 'V':                 /* version */
548       print_revision (progname, revision);
549       exit (STATE_OK);
550     case 'h':                 /* help */
551       print_help ();
552       exit (STATE_OK);
553     case '?':                 /* help */
554       usage (_("Unknown argument"));
555     }
556   }
558   /* Support for "check_disk warn crit [fs]" with thresholds at used% level */
559   c = optind;
560   if (warn_usedspace_percent == NULL && argc > c && is_intnonneg (argv[c]))
561     warn_usedspace_percent = argv[c++];
563   if (crit_usedspace_percent == NULL && argc > c && is_intnonneg (argv[c]))
564     crit_usedspace_percent = argv[c++];
566   if (argc > c && path == NULL) {
567     se = np_add_parameter(&path_select_list, strdup(argv[c++]));
568     set_thresholds(&se->freespace_units, warn_freespace_units, crit_freespace_units);
569     set_thresholds(&se->freespace_percent, warn_freespace_percent, crit_freespace_percent);
570     set_thresholds(&se->usedspace_units, warn_usedspace_units, crit_usedspace_units);
571     set_thresholds(&se->usedspace_percent, warn_usedspace_percent, crit_usedspace_percent);
572     set_thresholds(&se->usedinodes_percent, warn_usedinodes_percent, crit_usedinodes_percent);
573   }
575   if (units == NULL) {
576     units = strdup ("MB");
577     mult = (uintmax_t)1024 * 1024;
578   }
580   if (path_select_list) {
581     temp_list = path_select_list;
582     stat_buf = malloc(sizeof *stat_buf);
583     while (temp_list) {
584       /* Stat each entry to check that dir exists */
585       if (stat (temp_list->name, &stat_buf[0])) {
586         printf("DISK %s - ", _("CRITICAL"));
587         die (STATE_CRITICAL, _("%s does not exist\n"), temp_list->name);
588       }
589       /* if (validate_arguments (temp_list->w_df,
590                               temp_list->c_df,
591                               temp_list->w_dfp,
592                               temp_list->c_dfp,
593                               temp_list->w_idfp,
594                               temp_list->c_idfp,
595                               temp_list->name) == ERROR)
596         result = ERROR;
597       */
598       temp_list = temp_list->name_next;
599     }
600     free(stat_buf);
601     return result;
602   } else {
603     return TRUE;
604     /* return validate_arguments (w_df, c_df, w_dfp, c_dfp, w_idfp, c_idfp, NULL); */
605   }
610 void
611 print_path (const char *mypath) 
613   if (mypath == NULL)
614     printf ("\n");
615   else
616     printf (_(" for %s\n"), mypath);
618   //return;
623 /* TODO: Remove?
625 int
626 validate_arguments (uintmax_t w, uintmax_t c, double wp, double cp, double iwp, double icp, char *mypath)
628   if (w < 0 && c < 0 && wp < 0.0 && cp < 0.0) {
629     printf (_("INPUT ERROR: No thresholds specified"));
630     print_path (mypath);
631     return ERROR;
632   }
633   else if ((wp >= 0.0 || cp >= 0.0) &&
634            (wp < 0.0 || cp < 0.0 || wp > 100.0 || cp > 100.0 || cp > wp)) {
635     printf (_("\
636 INPUT ERROR: C_DFP (%f) should be less than W_DFP (%.1f) and both should be between zero and 100 percent, inclusive"),
637             cp, wp);
638     print_path (mypath);
639     return ERROR;
640   }
641   else if ((iwp >= 0.0 || icp >= 0.0) &&
642            (iwp < 0.0 || icp < 0.0 || iwp > 100.0 || icp > 100.0 || icp > iwp)) {
643     printf (_("\
644 INPUT ERROR: C_IDFP (%f) should be less than W_IDFP (%.1f) and both should be between zero and 100 percent, inclusive"),
645             icp, iwp);
646     print_path (mypath);
647     return ERROR;
648   }
649   else if ((w > 0 || c > 0) && (w == 0 || c == 0 || c > w)) {
650     printf (_("\
651 INPUT ERROR: C_DF (%lu) should be less than W_DF (%lu) and both should be greater than zero"),
652             (unsigned long)c, (unsigned long)w);
653     print_path (mypath);
654     return ERROR;
655   }
656   
657   return OK;
660 */
668 void
669 print_help (void)
671   print_revision (progname, revision);
673   printf ("Copyright (c) 1999 Ethan Galstad <nagios@nagios.org>\n");
674   printf (COPYRIGHT, copyright, email);
676   printf ("%s\n", _("This plugin checks the amount of used disk space on a mounted file system"));
677   printf ("%s\n", _("and generates an alert if free space is less than one of the threshold values"));
679   printf ("\n\n");
681   print_usage ();
683   printf (_(UT_HELP_VRSN));
685   printf (" %s\n", "-w, --warning=INTEGER");
686   printf ("    %s\n", _("Exit with WARNING status if less than INTEGER units of disk are free"));
687   printf (" %s\n", "-w, --warning=PERCENT%");
688   printf ("    %s\n", _("Exit with WARNING status if less than PERCENT of disk space is free"));
689   printf (" %s\n", "-W, --iwarning=PERCENT%");
690   printf ("    %s\n", _("Exit with WARNING status if less than PERCENT of inode space is free"));
691   printf (" %s\n", "-K, --icritical=PERCENT%");
692   printf ("    %s\n", _("Exit with CRITICAL status if less than PERCENT of inode space is free"));
693   printf (" %s\n", "-c, --critical=INTEGER");
694   printf ("    %s\n", _("Exit with CRITICAL status if less than INTEGER units of disk are free"));
695   printf (" %s\n", "-c, --critical=PERCENT%");
696   printf ("    %s\n", _("Exit with CRITCAL status if less than PERCENT of disk space is free"));
697   printf (" %s\n", "-C, --clear");
698   printf ("    %s\n", _("Clear thresholds"));
699   printf (" %s\n", "-u, --units=STRING");
700   printf ("    %s\n", _("Choose bytes, kB, MB, GB, TB (default: MB)"));
701   printf (" %s\n", "-k, --kilobytes");
702   printf ("    %s\n", _("Same as '--units kB'"));
703   printf (" %s\n", "-m, --megabytes");
704   printf ("    %s\n", _("Same as '--units MB'"));
705   printf (" %s\n", "-l, --local");
706   printf ("    %s\n", _("Only check local filesystems"));
707   printf (" %s\n", "-p, --path=PATH, --partition=PARTITION");
708   printf ("    %s\n", _("Path or partition (may be repeated)"));
709   printf (" %s\n", "-x, --exclude_device=PATH <STRING>");
710   printf ("    %s\n", _("Ignore device (only works if -p unspecified)"));
711   printf (" %s\n", _("-X, --exclude-type=TYPE <STRING>"));
712   printf ("    %s\n", _("Ignore all filesystems of indicated type (may be repeated)"));
713   printf (" %s\n", "-m, --mountpoint");
714   printf ("    %s\n", _("Display the mountpoint instead of the partition"));
715   printf (" %s\n", "-E, --exact-match");
716   printf ("    %s\n", _("For paths or partitions specified with -p, only check for exact paths"));
717   printf (" %s\n", "-e, --errors-only");
718   printf ("    %s\n", _("Display only devices/mountpoints with errors"));
719   printf (_(UT_TIMEOUT), DEFAULT_SOCKET_TIMEOUT);
720   printf (_(UT_VERBOSE));
721   printf ("\n");
722   printf ("%s\n", _("Examples:"));
723   printf (" %s\n", "check_disk -w 10% -c 5% -p /tmp -p /var -C -w 100000 -c 50000 -p /");
724   printf ("    %s\n", _("Checks /tmp and /var at 10% and 5%, and / at 100MB and 50MB"));
725   printf (_(UT_SUPPORT));
730 void
731 print_usage (void)
733   printf (_("Usage:"));
734   printf (" %s -w limit -c limit [-p path | -x device] [-t timeout]", progname);
735   printf ("[-m] [-e] [-W limit] [-K limit] [-v] [-q] [-E]\n");