Revert "check_disk - show all disks if state is ok and option error only is used"
[monitoring-plugins.git] / plugins / utils.c
blob231af92be776104e3d5074951e92c3cbe99561ce
1 /*****************************************************************************
2 *
3 * Library of useful functions for plugins
4 *
5 * License: GPL
6 * Copyright (c) 2000 Karl DeBisschop (karl@debisschop.net)
7 * Copyright (c) 2002-2007 Monitoring Plugins Development Team
8 *
9 * This program is free software: you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation, either version 3 of the License, or
12 * (at your option) any later version.
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
19 * You should have received a copy of the GNU General Public License
20 * along with this program. If not, see <http://www.gnu.org/licenses/>.
23 *****************************************************************************/
25 #include "common.h"
26 #include "utils.h"
27 #include "utils_base.h"
28 #include <stdarg.h>
29 #include <limits.h>
31 #include <arpa/inet.h>
33 extern void print_usage (void);
34 extern const char *progname;
36 #define STRLEN 64
37 #define TXTBLK 128
39 unsigned int timeout_state = STATE_CRITICAL;
40 unsigned int timeout_interval = DEFAULT_SOCKET_TIMEOUT;
42 time_t start_time, end_time;
44 /* **************************************************************************
45 * max_state(STATE_x, STATE_y)
46 * compares STATE_x to STATE_y and returns result based on the following
47 * STATE_UNKNOWN < STATE_OK < STATE_WARNING < STATE_CRITICAL
49 * Note that numerically the above does not hold
50 ****************************************************************************/
52 int
53 max_state (int a, int b)
55 if (a == STATE_CRITICAL || b == STATE_CRITICAL)
56 return STATE_CRITICAL;
57 else if (a == STATE_WARNING || b == STATE_WARNING)
58 return STATE_WARNING;
59 else if (a == STATE_OK || b == STATE_OK)
60 return STATE_OK;
61 else if (a == STATE_UNKNOWN || b == STATE_UNKNOWN)
62 return STATE_UNKNOWN;
63 else if (a == STATE_DEPENDENT || b == STATE_DEPENDENT)
64 return STATE_DEPENDENT;
65 else
66 return max (a, b);
69 /* **************************************************************************
70 * max_state_alt(STATE_x, STATE_y)
71 * compares STATE_x to STATE_y and returns result based on the following
72 * STATE_OK < STATE_DEPENDENT < STATE_UNKNOWN < STATE_WARNING < STATE_CRITICAL
74 * The main difference between max_state_alt and max_state it that it doesn't
75 * allow setting a default to UNKNOWN. It will instead prioritixe any valid
76 * non-OK state.
77 ****************************************************************************/
79 int
80 max_state_alt (int a, int b)
82 if (a == STATE_CRITICAL || b == STATE_CRITICAL)
83 return STATE_CRITICAL;
84 else if (a == STATE_WARNING || b == STATE_WARNING)
85 return STATE_WARNING;
86 else if (a == STATE_UNKNOWN || b == STATE_UNKNOWN)
87 return STATE_UNKNOWN;
88 else if (a == STATE_DEPENDENT || b == STATE_DEPENDENT)
89 return STATE_DEPENDENT;
90 else if (a == STATE_OK || b == STATE_OK)
91 return STATE_OK;
92 else
93 return max (a, b);
96 void usage (const char *msg)
98 printf ("%s\n", msg);
99 print_usage ();
100 exit (STATE_UNKNOWN);
103 void usage_va (const char *fmt, ...)
105 va_list ap;
106 printf("%s: ", progname);
107 va_start(ap, fmt);
108 vprintf(fmt, ap);
109 va_end(ap);
110 printf("\n");
111 exit (STATE_UNKNOWN);
114 void usage2(const char *msg, const char *arg)
116 printf ("%s: %s - %s\n", progname, msg, arg?arg:"(null)" );
117 print_usage ();
118 exit (STATE_UNKNOWN);
121 void
122 usage3 (const char *msg, int arg)
124 printf ("%s: %s - %c\n", progname, msg, arg);
125 print_usage();
126 exit (STATE_UNKNOWN);
129 void
130 usage4 (const char *msg)
132 printf ("%s: %s\n", progname, msg);
133 print_usage();
134 exit (STATE_UNKNOWN);
137 void
138 usage5 (void)
140 print_usage();
141 exit (STATE_UNKNOWN);
144 void
145 print_revision (const char *command_name, const char *revision)
147 printf ("%s v%s (%s %s)\n",
148 command_name, revision, PACKAGE, VERSION);
151 const char *
152 state_text (int result)
154 switch (result) {
155 case STATE_OK:
156 return "OK";
157 case STATE_WARNING:
158 return "WARNING";
159 case STATE_CRITICAL:
160 return "CRITICAL";
161 case STATE_DEPENDENT:
162 return "DEPENDENT";
163 default:
164 return "UNKNOWN";
168 void
169 timeout_alarm_handler (int signo)
171 if (signo == SIGALRM) {
172 printf (_("%s - Plugin timed out after %d seconds\n"),
173 state_text(timeout_state), timeout_interval);
174 exit (timeout_state);
179 is_numeric (char *number)
181 char tmp[1];
182 float x;
184 if (!number)
185 return FALSE;
186 else if (sscanf (number, "%f%c", &x, tmp) == 1)
187 return TRUE;
188 else
189 return FALSE;
193 is_positive (char *number)
195 if (is_numeric (number) && atof (number) > 0.0)
196 return TRUE;
197 else
198 return FALSE;
202 is_negative (char *number)
204 if (is_numeric (number) && atof (number) < 0.0)
205 return TRUE;
206 else
207 return FALSE;
211 is_nonnegative (char *number)
213 if (is_numeric (number) && atof (number) >= 0.0)
214 return TRUE;
215 else
216 return FALSE;
220 is_percentage (char *number)
222 int x;
223 if (is_numeric (number) && (x = atof (number)) >= 0 && x <= 100)
224 return TRUE;
225 else
226 return FALSE;
230 is_integer (char *number)
232 long int n;
234 if (!number || (strspn (number, "-0123456789 ") != strlen (number)))
235 return FALSE;
237 n = strtol (number, NULL, 10);
239 if (errno != ERANGE && n >= INT_MIN && n <= INT_MAX)
240 return TRUE;
241 else
242 return FALSE;
246 is_intpos (char *number)
248 if (is_integer (number) && atoi (number) > 0)
249 return TRUE;
250 else
251 return FALSE;
255 is_intneg (char *number)
257 if (is_integer (number) && atoi (number) < 0)
258 return TRUE;
259 else
260 return FALSE;
264 is_intnonneg (char *number)
266 if (is_integer (number) && atoi (number) >= 0)
267 return TRUE;
268 else
269 return FALSE;
273 is_intpercent (char *number)
275 int i;
276 if (is_integer (number) && (i = atoi (number)) >= 0 && i <= 100)
277 return TRUE;
278 else
279 return FALSE;
283 is_option (char *str)
285 if (!str)
286 return FALSE;
287 else if (strspn (str, "-") == 1 || strspn (str, "-") == 2)
288 return TRUE;
289 else
290 return FALSE;
293 #ifdef NEED_GETTIMEOFDAY
295 gettimeofday (struct timeval *tv, struct timezone *tz)
297 tv->tv_usec = 0;
298 tv->tv_sec = (long) time ((time_t) 0);
300 #endif
304 double
305 delta_time (struct timeval tv)
307 struct timeval now;
309 gettimeofday (&now, NULL);
310 return ((double)(now.tv_sec - tv.tv_sec) + (double)(now.tv_usec - tv.tv_usec) / (double)1000000);
315 long
316 deltime (struct timeval tv)
318 struct timeval now;
319 gettimeofday (&now, NULL);
320 return (now.tv_sec - tv.tv_sec)*1000000 + now.tv_usec - tv.tv_usec;
326 void
327 strip (char *buffer)
329 size_t x;
330 int i;
332 for (x = strlen (buffer); x >= 1; x--) {
333 i = x - 1;
334 if (buffer[i] == ' ' ||
335 buffer[i] == '\r' || buffer[i] == '\n' || buffer[i] == '\t')
336 buffer[i] = '\0';
337 else
338 break;
340 return;
344 /******************************************************************************
346 * Copies one string to another. Any previously existing data in
347 * the destination string is lost.
349 * Example:
351 * char *str=NULL;
352 * str = strscpy("This is a line of text with no trailing newline");
354 *****************************************************************************/
356 char *
357 strscpy (char *dest, const char *src)
359 if (src == NULL)
360 return NULL;
362 xasprintf (&dest, "%s", src);
364 return dest;
369 /******************************************************************************
371 * Returns a pointer to the next line of a multiline string buffer
373 * Given a pointer string, find the text following the next sequence
374 * of \r and \n characters. This has the effect of skipping blank
375 * lines as well
377 * Example:
379 * Given text as follows:
381 * ==============================
382 * This
383 * is
386 * multiline string buffer
387 * ==============================
389 * int i=0;
390 * char *str=NULL;
391 * char *ptr=NULL;
392 * str = strscpy(str,"This\nis\r\na\n\nmultiline string buffer\n");
393 * ptr = str;
394 * while (ptr) {
395 * printf("%d %s",i++,firstword(ptr));
396 * ptr = strnl(ptr);
399 * Produces the following:
401 * 1 This
402 * 2 is
403 * 3 a
404 * 4 multiline
406 * NOTE: The 'firstword()' function is conceptual only and does not
407 * exist in this package.
409 * NOTE: Although the second 'ptr' variable is not strictly needed in
410 * this example, it is good practice with these utilities. Once
411 * the * pointer is advance in this manner, it may no longer be
412 * handled with * realloc(). So at the end of the code fragment
413 * above, * strscpy(str,"foo") work perfectly fine, but
414 * strscpy(ptr,"foo") will * cause the the program to crash with
415 * a segmentation fault.
417 *****************************************************************************/
419 char *
420 strnl (char *str)
422 size_t len;
423 if (str == NULL)
424 return NULL;
425 str = strpbrk (str, "\r\n");
426 if (str == NULL)
427 return NULL;
428 len = strspn (str, "\r\n");
429 if (str[len] == '\0')
430 return NULL;
431 str += len;
432 if (strlen (str) == 0)
433 return NULL;
434 return str;
438 /******************************************************************************
440 * Like strscpy, except only the portion of the source string up to
441 * the provided delimiter is copied.
443 * Example:
445 * str = strpcpy(str,"This is a line of text with no trailing newline","x");
446 * printf("%s\n",str);
448 * Produces:
450 *This is a line of te
452 *****************************************************************************/
454 char *
455 strpcpy (char *dest, const char *src, const char *str)
457 size_t len;
459 if (src)
460 len = strcspn (src, str);
461 else
462 return NULL;
464 if (dest == NULL || strlen (dest) < len)
465 dest = realloc (dest, len + 1);
466 if (dest == NULL)
467 die (STATE_UNKNOWN, _("failed realloc in strpcpy\n"));
469 strncpy (dest, src, len);
470 dest[len] = '\0';
472 return dest;
477 /******************************************************************************
479 * Like strscat, except only the portion of the source string up to
480 * the provided delimiter is copied.
482 * str = strpcpy(str,"This is a line of text with no trailing newline","x");
483 * str = strpcat(str,"This is a line of text with no trailing newline","x");
484 * printf("%s\n",str);
486 *This is a line of texThis is a line of tex
488 *****************************************************************************/
490 char *
491 strpcat (char *dest, const char *src, const char *str)
493 size_t len, l2;
495 if (dest)
496 len = strlen (dest);
497 else
498 len = 0;
500 if (src) {
501 l2 = strcspn (src, str);
503 else {
504 return dest;
507 dest = realloc (dest, len + l2 + 1);
508 if (dest == NULL)
509 die (STATE_UNKNOWN, _("failed malloc in strscat\n"));
511 strncpy (dest + len, src, l2);
512 dest[len + l2] = '\0';
514 return dest;
518 /******************************************************************************
520 * asprintf, but die on failure
522 ******************************************************************************/
525 xvasprintf (char **strp, const char *fmt, va_list ap)
527 int result = vasprintf (strp, fmt, ap);
528 if (result == -1 || *strp == NULL)
529 die (STATE_UNKNOWN, _("failed malloc in xvasprintf\n"));
530 return result;
534 xasprintf (char **strp, const char *fmt, ...)
536 va_list ap;
537 int result;
538 va_start (ap, fmt);
539 result = xvasprintf (strp, fmt, ap);
540 va_end (ap);
541 return result;
544 /******************************************************************************
546 * Print perfdata in a standard format
548 ******************************************************************************/
550 char *perfdata (const char *label,
551 long int val,
552 const char *uom,
553 int warnp,
554 long int warn,
555 int critp,
556 long int crit,
557 int minp,
558 long int minv,
559 int maxp,
560 long int maxv)
562 char *data = NULL;
564 if (strpbrk (label, "'= "))
565 xasprintf (&data, "'%s'=%ld%s;", label, val, uom);
566 else
567 xasprintf (&data, "%s=%ld%s;", label, val, uom);
569 if (warnp)
570 xasprintf (&data, "%s%ld;", data, warn);
571 else
572 xasprintf (&data, "%s;", data);
574 if (critp)
575 xasprintf (&data, "%s%ld;", data, crit);
576 else
577 xasprintf (&data, "%s;", data);
579 if (minp)
580 xasprintf (&data, "%s%ld", data, minv);
582 if (maxp)
583 xasprintf (&data, "%s;%ld", data, maxv);
585 return data;
589 char *fperfdata (const char *label,
590 double val,
591 const char *uom,
592 int warnp,
593 double warn,
594 int critp,
595 double crit,
596 int minp,
597 double minv,
598 int maxp,
599 double maxv)
601 char *data = NULL;
603 if (strpbrk (label, "'= "))
604 xasprintf (&data, "'%s'=", label);
605 else
606 xasprintf (&data, "%s=", label);
608 xasprintf (&data, "%s%f", data, val);
609 xasprintf (&data, "%s%s;", data, uom);
611 if (warnp)
612 xasprintf (&data, "%s%f", data, warn);
614 xasprintf (&data, "%s;", data);
616 if (critp)
617 xasprintf (&data, "%s%f", data, crit);
619 xasprintf (&data, "%s;", data);
621 if (minp)
622 xasprintf (&data, "%s%f", data, minv);
624 if (maxp) {
625 xasprintf (&data, "%s;", data);
626 xasprintf (&data, "%s%f", data, maxv);
629 return data;
632 char *sperfdata (const char *label,
633 double val,
634 const char *uom,
635 char *warn,
636 char *crit,
637 int minp,
638 double minv,
639 int maxp,
640 double maxv)
642 char *data = NULL;
643 if (strpbrk (label, "'= "))
644 xasprintf (&data, "'%s'=", label);
645 else
646 xasprintf (&data, "%s=", label);
648 xasprintf (&data, "%s%f", data, val);
649 xasprintf (&data, "%s%s;", data, uom);
651 if (warn!=NULL)
652 xasprintf (&data, "%s%s", data, warn);
654 xasprintf (&data, "%s;", data);
656 if (crit!=NULL)
657 xasprintf (&data, "%s%s", data, crit);
659 xasprintf (&data, "%s;", data);
661 if (minp)
662 xasprintf (&data, "%s%f", data, minv);
664 if (maxp) {
665 xasprintf (&data, "%s;", data);
666 xasprintf (&data, "%s%f", data, maxv);
669 return data;
672 char *sperfdata_int (const char *label,
673 int val,
674 const char *uom,
675 char *warn,
676 char *crit,
677 int minp,
678 int minv,
679 int maxp,
680 int maxv)
682 char *data = NULL;
683 if (strpbrk (label, "'= "))
684 xasprintf (&data, "'%s'=", label);
685 else
686 xasprintf (&data, "%s=", label);
688 xasprintf (&data, "%s%d", data, val);
689 xasprintf (&data, "%s%s;", data, uom);
691 if (warn!=NULL)
692 xasprintf (&data, "%s%s", data, warn);
694 xasprintf (&data, "%s;", data);
696 if (crit!=NULL)
697 xasprintf (&data, "%s%s", data, crit);
699 xasprintf (&data, "%s;", data);
701 if (minp)
702 xasprintf (&data, "%s%d", data, minv);
704 if (maxp) {
705 xasprintf (&data, "%s;", data);
706 xasprintf (&data, "%s%d", data, maxv);
709 return data;