Code

Remove C style comments (1583467 - Markus Baertschi)
[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   char *preamble;
157   double inode_space_pct;
158   uintmax_t total, available, available_to_root, used;
159   double dfree_pct = -1, dused_pct = -1;
160   double dused_units, dfree_units, dtotal_units;
161   double dused_inodes_percent, dfree_inodes_percent;
162   double warning_high_tide = UINT_MAX;
163   double critical_high_tide = UINT_MAX;
164   int temp_result;
166   struct mount_entry *me;
167   struct fs_usage fsp;
168   struct parameter_list *temp_list, *path;
169   struct name_list *seen = NULL;
171   preamble = strdup (" - free space:");
172   output = strdup ("");
173   details = strdup ("");
174   perf = strdup ("");
176   setlocale (LC_ALL, "");
177   bindtextdomain (PACKAGE, LOCALEDIR);
178   textdomain (PACKAGE);
180   mount_list = read_file_system_list (0);
182   if (process_arguments (argc, argv) == ERROR)
183     usage4 (_("Could not parse arguments"));
185   /* If a list of paths has not been selected, find entire
186      mount list and create list of paths
187    */
188   if (! path_select_list) {
189     for (me = mount_list; me; me = me->me_next) {
190       path = np_add_parameter(&path_select_list, me->me_mountdir);
191       path->best_match = me;
192       set_thresholds(&path->freespace_units, warn_freespace_units, crit_freespace_units);
193       set_thresholds(&path->freespace_percent, warn_freespace_percent, crit_freespace_percent);
194       set_thresholds(&path->usedspace_units, warn_usedspace_units, crit_usedspace_units);
195       set_thresholds(&path->usedspace_percent, warn_usedspace_percent, crit_usedspace_percent);
196       set_thresholds(&path->usedinodes_percent, warn_usedinodes_percent, crit_usedinodes_percent);
197     }
198   } else {
199     np_set_best_match(path_select_list, mount_list, exact_match);
201     /* Error if no match found for specified paths */
202     temp_list = path_select_list;
203     while (temp_list) {
204       if (! temp_list->best_match) {
205         die (STATE_CRITICAL, _("DISK %s: %s not found\n"), _("CRITICAL"), temp_list->name);
206       }
207       temp_list = temp_list->name_next;
208     }
209   }
211   /* Process for every path in list */
212   for (path = path_select_list; path; path=path->name_next) {
214     /* reset disk result */
215     disk_result = STATE_UNKNOWN;
217     me = path->best_match;
219     /* Filters */
221     /* Remove filesystems already seen */
222     if (np_seen_name(seen, me->me_mountdir)) {
223       continue;
224     } else {
225       np_add_name(&seen, me->me_mountdir);
226     }
227     /* Skip remote filesystems if we're not interested in them */
228     if (me->me_remote && show_local_fs) {
229       continue;
230     /* Skip pseudo fs's if we haven't asked for all fs's */
231     } else if (me->me_dummy && !show_all_fs) {
232       continue;
233     /* Skip excluded fstypes */
234     } else if (fs_exclude_list && np_find_name (fs_exclude_list, me->me_type)) {
235       continue;
236     /* Skip excluded fs's */  
237     } else if (dp_exclude_list && 
238              (np_find_name (dp_exclude_list, me->me_devname) ||
239               np_find_name (dp_exclude_list, me->me_mountdir))) {
240       continue;
241     }
243     get_fs_usage (me->me_mountdir, me->me_devname, &fsp);
245     if (fsp.fsu_blocks && strcmp ("none", me->me_mountdir)) {
246       total = fsp.fsu_blocks;
247       available = fsp.fsu_bavail;
248       available_to_root = fsp.fsu_bfree;
249       used = total - available_to_root;
251       dused_pct = calculate_percent( used, used + available );  /* used + available can never be > uintmax */
252      
253       dfree_pct = 100 - dused_pct;
254       dused_units = used*fsp.fsu_blocksize/mult;
255       dfree_units = available*fsp.fsu_blocksize/mult;
256       dtotal_units = total*fsp.fsu_blocksize/mult;
257       dused_inodes_percent = calculate_percent(fsp.fsu_files - fsp.fsu_ffree, fsp.fsu_files);
258       dfree_inodes_percent = 100 - dused_inodes_percent;
260       if (verbose >= 3) {
261         printf ("For %s, used_pct=%g free_pct=%g used_units=%g free_units=%g total_units=%g used_inodes_pct=%g\n", 
262           me->me_mountdir, dused_pct, dfree_pct, dused_units, dfree_units, dtotal_units, dused_inodes_percent);
263       }
265       /* Threshold comparisons */
267       temp_result = get_status(dfree_units, path->freespace_units);
268       if (verbose >=3) printf("Freespace_units result=%d\n", temp_result);
269       disk_result = max_state( disk_result, temp_result );
271       temp_result = get_status(dfree_pct, path->freespace_percent);
272       if (verbose >=3) printf("Freespace%% result=%d\n", temp_result);
273       disk_result = max_state( disk_result, temp_result );
275       temp_result = get_status(dused_units, path->usedspace_units);
276       if (verbose >=3) printf("Usedspace_units result=%d\n", temp_result);
277       disk_result = max_state( disk_result, temp_result );
279       temp_result = get_status(dused_pct, path->usedspace_percent);
280       if (verbose >=3) printf("Usedspace_percent result=%d\n", temp_result);
281       disk_result = max_state( disk_result, temp_result );
283       temp_result = get_status(dused_inodes_percent, path->usedinodes_percent);
284       if (verbose >=3) printf("Usedinodes_percent result=%d\n", temp_result);
285       disk_result = max_state( disk_result, temp_result );
287       result = max_state(result, disk_result);
289       /* What a mess of units. The output shows free space, the perf data shows used space. Yikes!
290          Hack here. Trying to get warn/crit levels from freespace_(units|percent) for perf
291          data. Assumption that start=0. Roll on new syntax...
292       */
293       if (path->freespace_units->warning != NULL) {
294         warning_high_tide = dtotal_units - path->freespace_units->warning->end;
295       }
296       if (path->freespace_percent->warning != NULL) {
297         warning_high_tide = abs( min( (double) warning_high_tide, (double) (1.0 - path->freespace_percent->warning->end/100)*dtotal_units ));
298       }
299       if (path->freespace_units->critical != NULL) {
300         critical_high_tide = dtotal_units - path->freespace_units->critical->end;
301       }
302       if (path->freespace_percent->critical != NULL) {
303         critical_high_tide = abs( min( (double) critical_high_tide, (double) (1.0 - path->freespace_percent->critical->end/100)*dtotal_units ));
304       }
306       asprintf (&perf, "%s %s", perf,
307                 perfdata ((!strcmp(me->me_mountdir, "none") || display_mntp) ? me->me_devname : me->me_mountdir,
308                           dused_units, units,
309                           TRUE, warning_high_tide,
310                           TRUE, critical_high_tide,
311                           TRUE, 0,
312                           TRUE, dtotal_units));
314       if (disk_result==STATE_OK && erronly && !verbose)
315         continue;
317       if (disk_result!=STATE_OK || verbose>=0) {
318         asprintf (&output, "%s %s %.0f %s (%.0f%%",
319                   output,
320                   (!strcmp(me->me_mountdir, "none") || display_mntp) ? me->me_devname : me->me_mountdir,
321                   dfree_units,
322                   units,
323                   dfree_pct);
324         if (dused_inodes_percent < 0) {
325           asprintf(&output, "%s inode=-);", output);
326         } else {
327           asprintf(&output, "%s inode=%.0f%%);", output, dfree_inodes_percent );
328         }
329       }
331       /* TODO: Need to do a similar debug line
332       asprintf (&details, _("%s\n\
333 %.0f of %.0f %s (%.0f%% inode=%.0f%%) free on %s (type %s mounted on %s) warn:%lu crit:%lu warn%%:%.0f%% crit%%:%.0f%%"),
334                 details, dfree_units, dtotal_units, units, dfree_pct, inode_space_pct,
335                 me->me_devname, me->me_type, me->me_mountdir,
336                 (unsigned long)w_df, (unsigned long)c_df, w_dfp, c_dfp);
337       */
339     }
341   }
343   if (verbose > 2)
344     asprintf (&output, "%s%s", output, details);
347   printf ("DISK %s%s%s|%s\n", state_text (result), (erronly && result==STATE_OK) ? "" : preamble, output, perf);
348   return result;
352 double calculate_percent(uintmax_t value, uintmax_t total) {
353   double pct = -1;
354   /* I don't understand the below, but it is taken from coreutils' df */
355   /* Seems to be calculating pct, in the best possible way */
356   if (value <= TYPE_MAXIMUM(uintmax_t) / 100 
357     && total != 0) {
358     uintmax_t u100 = value * 100;
359     pct = u100 / total + (u100 % total != 0);
360   } else {
361     /* Possible rounding errors - see coreutils' df for more explanation */
362     double u = value;
363     double t = total;
364     if (t) {
365       long int lipct = pct = u * 100 / t;
366       double ipct = lipct;
368       /* Like 'pct = ceil (dpct);', but without ceil - from coreutils again */
369       if (ipct - 1 < pct && pct <= ipct + 1)
370         pct = ipct + (ipct < pct);
371     }
372   }
373   return pct;
376 /* process command-line arguments */
377 int
378 process_arguments (int argc, char **argv)
380   int c;
381   struct parameter_list *se;
382   struct parameter_list *temp_list;
383   int result = OK;
384   struct stat *stat_buf;
386   int option = 0;
387   static struct option longopts[] = {
388     {"timeout", required_argument, 0, 't'},
389     {"warning", required_argument, 0, 'w'},
390     {"critical", required_argument, 0, 'c'},
391     {"iwarning", required_argument, 0, 'W'},
392     /* Dang, -C is taken. We might want to reshuffle this. */
393     {"icritical", required_argument, 0, 'K'},
394     {"local", required_argument, 0, 'l'},
395     {"kilobytes", required_argument, 0, 'k'},
396     {"megabytes", required_argument, 0, 'm'},
397     {"units", required_argument, 0, 'u'},
398     {"path", required_argument, 0, 'p'},
399     {"partition", required_argument, 0, 'p'},
400     {"exclude_device", required_argument, 0, 'x'},
401     {"exclude-type", required_argument, 0, 'X'},
402     {"mountpoint", no_argument, 0, 'M'},
403     {"errors-only", no_argument, 0, 'e'},
404     {"exact-match", no_argument, 0, 'E'},
405     {"verbose", no_argument, 0, 'v'},
406     {"quiet", no_argument, 0, 'q'},
407     {"clear", no_argument, 0, 'C'},
408     {"version", no_argument, 0, 'V'},
409     {"help", no_argument, 0, 'h'},
410     {0, 0, 0, 0}
411   };
413   if (argc < 2)
414     return ERROR;
416   np_add_name(&fs_exclude_list, "iso9660");
418   for (c = 1; c < argc; c++)
419     if (strcmp ("-to", argv[c]) == 0)
420       strcpy (argv[c], "-t");
422   while (1) {
423     c = getopt_long (argc, argv, "+?VqhveCt:c:w:K:W:u:p:x:X:mklME", longopts, &option);
425     if (c == -1 || c == EOF)
426       break;
428     switch (c) {
429     case 't':                 /* timeout period */
430       if (is_integer (optarg)) {
431         timeout_interval = atoi (optarg);
432         break;
433       }
434       else {
435         usage2 (_("Timeout interval must be a positive integer"), optarg);
436       }
438     /* See comments for 'c' */
439     case 'w':                 /* warning threshold */
440       if (strstr(optarg, "%")) {
441         if (*optarg == '@') {
442           warn_freespace_percent = optarg;
443         } else {
444           asprintf(&warn_freespace_percent, "@%s", optarg);
445         }
446       } else {
447         if (*optarg == '@') {
448           warn_freespace_units = optarg;
449         } else {
450           asprintf(&warn_freespace_units, "@%s", optarg);
451         }
452       }
453       break;
455     /* Awful mistake where the range values do not make sense. Normally, 
456        you alert if the value is within the range, but since we are using
457        freespace, we have to alert if outside the range. Thus we artifically
458        force @ at the beginning of the range, so that it is backwards compatible
459     */
460     case 'c':                 /* critical threshold */
461       if (strstr(optarg, "%")) {
462         if (*optarg == '@') {
463           crit_freespace_percent = optarg;
464         } else {
465           asprintf(&crit_freespace_percent, "@%s", optarg);
466         }
467       } else {
468         if (*optarg == '@') {
469           crit_freespace_units = optarg;
470         } else {
471           asprintf(&crit_freespace_units, "@%s", optarg);
472         }
473       }
474       break;
476     case 'W':                   /* warning inode threshold */
477       warn_usedinodes_percent = optarg;
478       break;
479     case 'K':                   /* critical inode threshold */
480       crit_usedinodes_percent = optarg;
481       break;
482     case 'u':
483       if (units)
484         free(units);
485       if (! strcmp (optarg, "bytes")) {
486         mult = (uintmax_t)1;
487         units = strdup ("B");
488       } else if (! strcmp (optarg, "kB")) {
489         mult = (uintmax_t)1024;
490         units = strdup ("kB");
491       } else if (! strcmp (optarg, "MB")) {
492         mult = (uintmax_t)1024 * 1024;
493         units = strdup ("MB");
494       } else if (! strcmp (optarg, "GB")) {
495         mult = (uintmax_t)1024 * 1024 * 1024;
496         units = strdup ("GB");
497       } else if (! strcmp (optarg, "TB")) {
498         mult = (uintmax_t)1024 * 1024 * 1024 * 1024;
499         units = strdup ("TB");
500       } else {
501         die (STATE_UNKNOWN, _("unit type %s not known\n"), optarg);
502       }
503       if (units == NULL)
504         die (STATE_UNKNOWN, _("failed allocating storage for '%s'\n"), "units");
505       break;
506     case 'k': /* display mountpoint */
507       mult = 1024;
508       if (units)
509         free(units);
510       units = strdup ("kB");
511       break;
512     case 'm': /* display mountpoint */
513       mult = 1024 * 1024;
514       if (units)
515         free(units);
516       units = strdup ("MB");
517       break;
518     case 'l':
519       show_local_fs = 1;      
520       break;
521     case 'p':                 /* select path */
522       if (! (warn_freespace_units || crit_freespace_units || warn_freespace_percent || 
523              crit_freespace_percent || warn_usedspace_units || crit_usedspace_units ||
524              warn_usedspace_percent || crit_usedspace_percent || warn_usedinodes_percent ||
525              crit_usedinodes_percent)) {
526         die (STATE_UNKNOWN, "DISK %s: %s", _("UNKNOWN"), _("Must set a threshold value before using -p\n"));
527       }
528       se = np_add_parameter(&path_select_list, optarg);
529       set_thresholds(&se->freespace_units, warn_freespace_units, crit_freespace_units);
530       set_thresholds(&se->freespace_percent, warn_freespace_percent, crit_freespace_percent);
531       set_thresholds(&se->usedspace_units, warn_usedspace_units, crit_usedspace_units);
532       set_thresholds(&se->usedspace_percent, warn_usedspace_percent, crit_usedspace_percent);
533       set_thresholds(&se->usedinodes_percent, warn_usedinodes_percent, crit_usedinodes_percent);
534       break;
535     case 'x':                 /* exclude path or partition */
536       np_add_name(&dp_exclude_list, optarg);
537       break;
538     case 'X':                 /* exclude file system type */
539       np_add_name(&fs_exclude_list, optarg);
540       break;
541     case 'v':                 /* verbose */
542       verbose++;
543       break;
544     case 'q':                 /* verbose */
545       verbose--;
546       break;
547     case 'e':
548       erronly = TRUE;
549       break;
550     case 'E':
551       exact_match = TRUE;
552       break;
553     case 'M': /* display mountpoint */
554       display_mntp = TRUE;
555       break;
556     case 'C':
557       warn_freespace_units = NULL;
558       crit_freespace_units = NULL;
559       warn_usedspace_units = NULL;
560       crit_usedspace_units = NULL;
561       warn_freespace_percent = NULL;
562       crit_freespace_percent = NULL;
563       warn_usedspace_percent = NULL;
564       crit_usedspace_percent = NULL;
565       warn_usedinodes_percent = NULL;
566       crit_usedinodes_percent = NULL;
567       break;
568     case 'V':                 /* version */
569       print_revision (progname, revision);
570       exit (STATE_OK);
571     case 'h':                 /* help */
572       print_help ();
573       exit (STATE_OK);
574     case '?':                 /* help */
575       usage (_("Unknown argument"));
576     }
577   }
579   /* Support for "check_disk warn crit [fs]" with thresholds at used% level */
580   c = optind;
581   if (warn_usedspace_percent == NULL && argc > c && is_intnonneg (argv[c]))
582     warn_usedspace_percent = argv[c++];
584   if (crit_usedspace_percent == NULL && argc > c && is_intnonneg (argv[c]))
585     crit_usedspace_percent = argv[c++];
587   if (argc > c && path == NULL) {
588     se = np_add_parameter(&path_select_list, strdup(argv[c++]));
589     set_thresholds(&se->freespace_units, warn_freespace_units, crit_freespace_units);
590     set_thresholds(&se->freespace_percent, warn_freespace_percent, crit_freespace_percent);
591     set_thresholds(&se->usedspace_units, warn_usedspace_units, crit_usedspace_units);
592     set_thresholds(&se->usedspace_percent, warn_usedspace_percent, crit_usedspace_percent);
593     set_thresholds(&se->usedinodes_percent, warn_usedinodes_percent, crit_usedinodes_percent);
594   }
596   if (units == NULL) {
597     units = strdup ("MB");
598     mult = (uintmax_t)1024 * 1024;
599   }
601   if (path_select_list) {
602     temp_list = path_select_list;
603     stat_buf = malloc(sizeof *stat_buf);
604     while (temp_list) {
605       /* Stat each entry to check that dir exists */
606       if (stat (temp_list->name, &stat_buf[0])) {
607         printf("DISK %s - ", _("CRITICAL"));
608         die (STATE_CRITICAL, _("%s does not exist\n"), temp_list->name);
609       }
610       /* if (validate_arguments (temp_list->w_df,
611                               temp_list->c_df,
612                               temp_list->w_dfp,
613                               temp_list->c_dfp,
614                               temp_list->w_idfp,
615                               temp_list->c_idfp,
616                               temp_list->name) == ERROR)
617         result = ERROR;
618       */
619       temp_list = temp_list->name_next;
620     }
621     free(stat_buf);
622     return result;
623   } else {
624     return TRUE;
625     /* return validate_arguments (w_df, c_df, w_dfp, c_dfp, w_idfp, c_idfp, NULL); */
626   }
631 void
632 print_path (const char *mypath) 
634   if (mypath == NULL)
635     printf ("\n");
636   else
637     printf (_(" for %s\n"), mypath);
642 /* TODO: Remove?
644 int
645 validate_arguments (uintmax_t w, uintmax_t c, double wp, double cp, double iwp, double icp, char *mypath)
647   if (w < 0 && c < 0 && wp < 0.0 && cp < 0.0) {
648     printf (_("INPUT ERROR: No thresholds specified"));
649     print_path (mypath);
650     return ERROR;
651   }
652   else if ((wp >= 0.0 || cp >= 0.0) &&
653            (wp < 0.0 || cp < 0.0 || wp > 100.0 || cp > 100.0 || cp > wp)) {
654     printf (_("\
655 INPUT ERROR: C_DFP (%f) should be less than W_DFP (%.1f) and both should be between zero and 100 percent, inclusive"),
656             cp, wp);
657     print_path (mypath);
658     return ERROR;
659   }
660   else if ((iwp >= 0.0 || icp >= 0.0) &&
661            (iwp < 0.0 || icp < 0.0 || iwp > 100.0 || icp > 100.0 || icp > iwp)) {
662     printf (_("\
663 INPUT ERROR: C_IDFP (%f) should be less than W_IDFP (%.1f) and both should be between zero and 100 percent, inclusive"),
664             icp, iwp);
665     print_path (mypath);
666     return ERROR;
667   }
668   else if ((w > 0 || c > 0) && (w == 0 || c == 0 || c > w)) {
669     printf (_("\
670 INPUT ERROR: C_DF (%lu) should be less than W_DF (%lu) and both should be greater than zero"),
671             (unsigned long)c, (unsigned long)w);
672     print_path (mypath);
673     return ERROR;
674   }
675   
676   return OK;
679 */
687 void
688 print_help (void)
690   print_revision (progname, revision);
692   printf ("Copyright (c) 1999 Ethan Galstad <nagios@nagios.org>\n");
693   printf (COPYRIGHT, copyright, email);
695   printf ("%s\n", _("This plugin checks the amount of used disk space on a mounted file system"));
696   printf ("%s\n", _("and generates an alert if free space is less than one of the threshold values"));
698   printf ("\n\n");
700   print_usage ();
702   printf (_(UT_HELP_VRSN));
704   printf (" %s\n", "-w, --warning=INTEGER");
705   printf ("    %s\n", _("Exit with WARNING status if less than INTEGER units of disk are free"));
706   printf (" %s\n", "-w, --warning=PERCENT%");
707   printf ("    %s\n", _("Exit with WARNING status if less than PERCENT of disk space is free"));
708   printf (" %s\n", "-W, --iwarning=PERCENT%");
709   printf ("    %s\n", _("Exit with WARNING status if less than PERCENT of inode space is free"));
710   printf (" %s\n", "-K, --icritical=PERCENT%");
711   printf ("    %s\n", _("Exit with CRITICAL status if less than PERCENT of inode space is free"));
712   printf (" %s\n", "-c, --critical=INTEGER");
713   printf ("    %s\n", _("Exit with CRITICAL status if less than INTEGER units of disk are free"));
714   printf (" %s\n", "-c, --critical=PERCENT%");
715   printf ("    %s\n", _("Exit with CRITCAL status if less than PERCENT of disk space is free"));
716   printf (" %s\n", "-C, --clear");
717   printf ("    %s\n", _("Clear thresholds"));
718   printf (" %s\n", "-u, --units=STRING");
719   printf ("    %s\n", _("Choose bytes, kB, MB, GB, TB (default: MB)"));
720   printf (" %s\n", "-k, --kilobytes");
721   printf ("    %s\n", _("Same as '--units kB'"));
722   printf (" %s\n", "-m, --megabytes");
723   printf ("    %s\n", _("Same as '--units MB'"));
724   printf (" %s\n", "-l, --local");
725   printf ("    %s\n", _("Only check local filesystems"));
726   printf (" %s\n", "-p, --path=PATH, --partition=PARTITION");
727   printf ("    %s\n", _("Path or partition (may be repeated)"));
728   printf (" %s\n", "-x, --exclude_device=PATH <STRING>");
729   printf ("    %s\n", _("Ignore device (only works if -p unspecified)"));
730   printf (" %s\n", _("-X, --exclude-type=TYPE <STRING>"));
731   printf ("    %s\n", _("Ignore all filesystems of indicated type (may be repeated)"));
732   printf (" %s\n", "-m, --mountpoint");
733   printf ("    %s\n", _("Display the mountpoint instead of the partition"));
734   printf (" %s\n", "-E, --exact-match");
735   printf ("    %s\n", _("For paths or partitions specified with -p, only check for exact paths"));
736   printf (" %s\n", "-e, --errors-only");
737   printf ("    %s\n", _("Display only devices/mountpoints with errors"));
738   printf (_(UT_TIMEOUT), DEFAULT_SOCKET_TIMEOUT);
739   printf (_(UT_VERBOSE));
740   printf ("\n");
741   printf ("%s\n", _("Examples:"));
742   printf (" %s\n", "check_disk -w 10% -c 5% -p /tmp -p /var -C -w 100000 -c 50000 -p /");
743   printf ("    %s\n", _("Checks /tmp and /var at 10% and 5%, and / at 100MB and 50MB"));
744   printf (_(UT_SUPPORT));
749 void
750 print_usage (void)
752   printf (_("Usage:"));
753   printf (" %s -w limit -c limit [-p path | -x device] [-t timeout]", progname);
754   printf ("[-m] [-e] [-W limit] [-K limit] [-v] [-q] [-E]\n");