Code

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