Code

use asprintf instead of ssprintf
[nagiosplug.git] / plugins / check_swap.c
1 /******************************************************************************
2 *
3 * CHECK_SWAP.C
4 *
5 * Program: Process plugin for Nagios
6 * License: GPL
7 * Copyright (c) 2000 Karl DeBisschop (kdebisschop@users.sourceforge.net)
8 *
9 * $Id$
10 *
11 ******************************************************************************/
13 #include "common.h"
14 #include "popen.h"
15 #include "utils.h"
17 #define PROGNAME "check_swap"
19 int process_arguments (int argc, char **argv);
20 int call_getopt (int argc, char **argv);
21 int validate_arguments (void);
22 void print_usage (void);
23 void print_help (void);
25 int warn_percent = 200, crit_percent = 200, warn_size = -1, crit_size = -1;
27 int
28 main (int argc, char **argv)
29 {
30         int total_swap, used_swap, free_swap, percent_used;
31         int result = STATE_OK;
32         char input_buffer[MAX_INPUT_BUFFER];
33 #ifdef HAVE_SWAP
34         char *temp_buffer;
35 #endif
36 #ifdef HAVE_PROC_MEMINFO
37         FILE *fp;
38 #endif
39         char str[32];
40         char *status = NULL;
42         if (process_arguments (argc, argv) != OK)
43                 usage ("Invalid command arguments supplied\n");
45 #ifdef HAVE_PROC_MEMINFO
46         fp = fopen (PROC_MEMINFO, "r");
47         asprintf (&status, "%s", "Swap used:");
48         while (fgets (input_buffer, MAX_INPUT_BUFFER - 1, fp)) {
49                 sscanf (input_buffer, " %s %d %d %d", str, &total_swap, &used_swap,
50                                                 &free_swap);
51                 if (strstr (str, "Swap")) {
52                         percent_used = 100 * (((float) used_swap) / ((float) total_swap));
53                         asprintf (&status, "%s %2d%% (%d bytes out of %d)",
54                                   status, percent_used, used_swap, total_swap);
55                         if (percent_used >= crit_percent || free_swap <= crit_size)
56                                 result = STATE_CRITICAL;
57                         else if (percent_used >= warn_percent || free_swap <= warn_size)
58                                 result = STATE_WARNING;
59                         break;
60                 }
61         }
62         fclose (fp);
63 #else
64 #ifdef HAVE_SWAP
65         child_process = spopen (SWAP_COMMAND);
66         if (child_process == NULL) {
67                 printf ("Could not open pipe: %s\n", SWAP_COMMAND);
68                 return STATE_UNKNOWN;
69         }
71         child_stderr = fdopen (child_stderr_array[fileno (child_process)], "r");
72         if (child_stderr == NULL)
73                 printf ("Could not open stderr for %s\n", SWAP_COMMAND);
75         sprintf (str, "%s", "");
76         /* read 1st line */
77         fgets (input_buffer, MAX_INPUT_BUFFER - 1, child_process);
78         if (strcmp (SWAP_FORMAT, "") == 0) {
79                 temp_buffer = strtok (input_buffer, " \n");
80                 while (temp_buffer) {
81                         if (strstr (temp_buffer, "blocks"))
82                                 sprintf (str, "%s %s", str, "%f");
83                         else if (strstr (temp_buffer, "free"))
84                                 sprintf (str, "%s %s", str, "%f");
85                         else
86                                 sprintf (str, "%s %s", str, "%*s");
87                         temp_buffer = strtok (NULL, " \n");
88                 }
89         }
91         asprintf (&status, "%s", "Swap used:");
92         while (fgets (input_buffer, MAX_INPUT_BUFFER - 1, child_process)) {
93                 sscanf (input_buffer, SWAP_FORMAT, &total_swap, &free_swap);
94                 used_swap = total_swap - free_swap;
95                 percent_used = 100 * ((float) used_swap) / ((float) total_swap);
96                 asprintf (&status, "%s %2d%% (%d bytes out of %d)",
97                           status, percent_used, used_swap, total_swap);
98                 if (percent_used >= crit_percent || free_swap <= crit_size)
99                         result = STATE_CRITICAL;
100                 else if (percent_used >= warn_percent || free_swap <= warn_size)
101                         result = STATE_WARNING;
102         }
104         /* If we get anything on STDERR, at least set warning */
105         while (fgets (input_buffer, MAX_INPUT_BUFFER - 1, child_stderr))
106                 result = max (result, STATE_WARNING);
108         /* close stderr */
109         (void) fclose (child_stderr);
111         /* close the pipe */
112         if (spclose (child_process))
113                 result = max (result, STATE_WARNING);
114 #endif
115 #endif
117 #ifndef SWAP_COMMAND
118 #ifndef SWAP_FILE
119 #ifndef HAVE_PROC_MEMINFO
120         return STATE_UNKNOWN;
121 #endif
122 #endif
123 #endif
125         if (result == STATE_OK)
126                 printf ("Swap ok - %s\n", status);
127         else if (result == STATE_CRITICAL)
128                 printf ("CRITICAL - %s\n", status);
129         else if (result == STATE_WARNING)
130                 printf ("WARNING - %s\n", status);
131         else if (result == STATE_UNKNOWN)
132                 printf ("Unable to read output\n");
133         else {
134                 result = STATE_UNKNOWN;
135                 printf ("UNKNOWN - %s\n", status);
136         }
138         return result;
145 /* process command-line arguments */
146 int
147 process_arguments (int argc, char **argv)
149         int c, i = 0;
151 #ifdef HAVE_GETOPT_H
152         int option_index = 0;
153         static struct option long_options[] = {
154                 {"warning", required_argument, 0, 'w'},
155                 {"critical", required_argument, 0, 'c'},
156                 {"verbose", no_argument, 0, 'v'},
157                 {"version", no_argument, 0, 'V'},
158                 {"help", no_argument, 0, 'h'},
159                 {0, 0, 0, 0}
160         };
161 #endif
163         if (argc < 2)
164                 return ERROR;
166         while (1) {
167 #ifdef HAVE_GETOPT_H
168                 c = getopt_long (argc, argv, "+?Vhc:w:", long_options, &option_index);
169 #else
170                 c = getopt (argc, argv, "+?Vhc:w:");
171 #endif
173                 if (c == -1 || c == EOF)
174                         break;
176                 switch (c) {
177                 case 'w':                                                                       /* warning time threshold */
178                         if (is_intnonneg (optarg)) {
179                                 warn_size = atoi (optarg);
180                                 break;
181                         }
182                         else if (strstr (optarg, ",") &&
183                                                          strstr (optarg, "%") &&
184                                                          sscanf (optarg, "%d,%d%%", &warn_size, &warn_percent) == 2) {
185                                 break;
186                         }
187                         else if (strstr (optarg, "%") &&
188                                                          sscanf (optarg, "%d%%", &warn_percent) == 1) {
189                                 break;
190                         }
191                         else {
192                                 usage ("Warning threshold must be integer or percentage!\n");
193                         }
194                 case 'c':                                                                       /* critical time threshold */
195                         if (is_intnonneg (optarg)) {
196                                 crit_size = atoi (optarg);
197                                 break;
198                         }
199                         else if (strstr (optarg, ",") &&
200                                                          strstr (optarg, "%") &&
201                                                          sscanf (optarg, "%d,%d%%", &crit_size, &crit_percent) == 2) {
202                                 break;
203                         }
204                         else if (strstr (optarg, "%") &&
205                                                          sscanf (optarg, "%d%%", &crit_percent) == 1) {
206                                 break;
207                         }
208                         else {
209                                 usage ("Critical threshold must be integer or percentage!\n");
210                         }
211                 case 'V':                                                                       /* version */
212                         print_revision (my_basename (argv[0]), "$Revision$");
213                         exit (STATE_OK);
214                 case 'h':                                                                       /* help */
215                         print_help ();
216                         exit (STATE_OK);
217                 case '?':                                                                       /* help */
218                         usage ("Invalid argument\n");
219                 }
220         }
222         c = optind;
223         if (c == argc)
224                 return validate_arguments ();
225         if (warn_percent > 100 && is_intnonneg (argv[c]))
226                 warn_percent = atoi (argv[c++]);
228         if (c == argc)
229                 return validate_arguments ();
230         if (crit_percent > 100 && is_intnonneg (argv[c]))
231                 crit_percent = atoi (argv[c++]);
233         if (c == argc)
234                 return validate_arguments ();
235         if (warn_size < 0 && is_intnonneg (argv[c]))
236                 warn_size = atoi (argv[c++]);
238         if (c == argc)
239                 return validate_arguments ();
240         if (crit_size < 0 && is_intnonneg (argv[c]))
241                 crit_size = atoi (argv[c++]);
243         return validate_arguments ();
250 int
251 validate_arguments (void)
253         if (warn_percent > 100 && crit_percent > 100 && warn_size < 0
254                         && crit_size < 0) {
255                 return ERROR;
256         }
257         else if (warn_percent > crit_percent) {
258                 usage
259                         ("Warning percentage should not be less than critical percentage\n");
260         }
261         else if (warn_size < crit_size) {
262                 usage
263                         ("Warning free space should not be more than critical free space\n");
264         }
265         return OK;
272 void
273 print_usage (void)
275         printf
276                 ("Usage: check_swap -w <used_percentage>%% -c <used_percentage>%%\n"
277                  "       check_swap -w <bytes_free> -c <bytes_free>\n"
278                  "       check_swap (-V|--version)\n" "       check_swap (-h|--help)\n");
285 void
286 print_help (void)
288         print_revision (PROGNAME, "$Revision$");
289         printf
290                 ("Copyright (c) 2000 Karl DeBisschop\n\n"
291                  "This plugin will check all of the swap partitions and return an\n"
292                  "error if the the avalable swap space is less than specified.\n\n");
293         print_usage ();
294         printf
295                 ("\nOptions:\n"
296                  " -w, --warning=INTEGER\n"
297                  "   Exit with WARNING status if less than INTEGER bytes of swap space are free\n"
298                  " -w, --warning=PERCENT%%\n"
299                  "   Exit with WARNING status if more than PERCENT of swap space has been used\n"
300                  " -c, --critical=INTEGER\n"
301                  "   Exit with CRITICAL status if less than INTEGER bytes of swap space are free\n"
302                  " -c, --critical=PERCENT%%\n"
303                  "   Exit with CRITCAL status if more than PERCENT of swap space has been used\n"
304                  " -h, --help\n"
305                  "    Print detailed help screen\n"
306                  " -V, --version\n" "    Print version information\n\n");
307         support ();