1 /*****************************************************************************
3 * Library of useful functions for plugins
6 * Copyright (c) 2000 Karl DeBisschop (karl@debisschop.net)
7 * Copyright (c) 2002-2007 Monitoring Plugins Development Team
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 *****************************************************************************/
27 #include "utils_base.h"
31 #include <arpa/inet.h>
33 extern void print_usage (void);
34 extern const char *progname
;
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 ****************************************************************************/
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
)
59 else if (a
== STATE_OK
|| b
== STATE_OK
)
61 else if (a
== STATE_UNKNOWN
|| b
== STATE_UNKNOWN
)
63 else if (a
== STATE_DEPENDENT
|| b
== STATE_DEPENDENT
)
64 return STATE_DEPENDENT
;
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
77 ****************************************************************************/
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
)
86 else if (a
== STATE_UNKNOWN
|| b
== STATE_UNKNOWN
)
88 else if (a
== STATE_DEPENDENT
|| b
== STATE_DEPENDENT
)
89 return STATE_DEPENDENT
;
90 else if (a
== STATE_OK
|| b
== STATE_OK
)
96 void usage (const char *msg
)
100 exit (STATE_UNKNOWN
);
103 void usage_va (const char *fmt
, ...)
106 printf("%s: ", progname
);
111 exit (STATE_UNKNOWN
);
114 void usage2(const char *msg
, const char *arg
)
116 printf ("%s: %s - %s\n", progname
, msg
, arg
?arg
:"(null)" );
118 exit (STATE_UNKNOWN
);
122 usage3 (const char *msg
, int arg
)
124 printf ("%s: %s - %c\n", progname
, msg
, arg
);
126 exit (STATE_UNKNOWN
);
130 usage4 (const char *msg
)
132 printf ("%s: %s\n", progname
, msg
);
134 exit (STATE_UNKNOWN
);
141 exit (STATE_UNKNOWN
);
145 print_revision (const char *command_name
, const char *revision
)
147 printf ("%s v%s (%s %s)\n",
148 command_name
, revision
, PACKAGE
, VERSION
);
152 state_text (int result
)
161 case STATE_DEPENDENT
:
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
)
186 else if (sscanf (number
, "%f%c", &x
, tmp
) == 1)
193 is_positive (char *number
)
195 if (is_numeric (number
) && atof (number
) > 0.0)
202 is_negative (char *number
)
204 if (is_numeric (number
) && atof (number
) < 0.0)
211 is_nonnegative (char *number
)
213 if (is_numeric (number
) && atof (number
) >= 0.0)
220 is_percentage (char *number
)
223 if (is_numeric (number
) && (x
= atof (number
)) >= 0 && x
<= 100)
230 is_integer (char *number
)
234 if (!number
|| (strspn (number
, "-0123456789 ") != strlen (number
)))
237 n
= strtol (number
, NULL
, 10);
239 if (errno
!= ERANGE
&& n
>= INT_MIN
&& n
<= INT_MAX
)
246 is_intpos (char *number
)
248 if (is_integer (number
) && atoi (number
) > 0)
255 is_intneg (char *number
)
257 if (is_integer (number
) && atoi (number
) < 0)
264 is_intnonneg (char *number
)
266 if (is_integer (number
) && atoi (number
) >= 0)
273 is_intpercent (char *number
)
276 if (is_integer (number
) && (i
= atoi (number
)) >= 0 && i
<= 100)
283 is_option (char *str
)
287 else if (strspn (str
, "-") == 1 || strspn (str
, "-") == 2)
293 #ifdef NEED_GETTIMEOFDAY
295 gettimeofday (struct timeval
*tv
, struct timezone
*tz
)
298 tv
->tv_sec
= (long) time ((time_t) 0);
305 delta_time (struct timeval tv
)
309 gettimeofday (&now
, NULL
);
310 return ((double)(now
.tv_sec
- tv
.tv_sec
) + (double)(now
.tv_usec
- tv
.tv_usec
) / (double)1000000);
316 deltime (struct timeval tv
)
319 gettimeofday (&now
, NULL
);
320 return (now
.tv_sec
- tv
.tv_sec
)*1000000 + now
.tv_usec
- tv
.tv_usec
;
332 for (x
= strlen (buffer
); x
>= 1; x
--) {
334 if (buffer
[i
] == ' ' ||
335 buffer
[i
] == '\r' || buffer
[i
] == '\n' || buffer
[i
] == '\t')
344 /******************************************************************************
346 * Copies one string to another. Any previously existing data in
347 * the destination string is lost.
352 * str = strscpy("This is a line of text with no trailing newline");
354 *****************************************************************************/
357 strscpy (char *dest
, const char *src
)
362 xasprintf (&dest
, "%s", src
);
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
379 * Given text as follows:
381 * ==============================
386 * multiline string buffer
387 * ==============================
392 * str = strscpy(str,"This\nis\r\na\n\nmultiline string buffer\n");
395 * printf("%d %s",i++,firstword(ptr));
399 * Produces the following:
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 *****************************************************************************/
425 str
= strpbrk (str
, "\r\n");
428 len
= strspn (str
, "\r\n");
429 if (str
[len
] == '\0')
432 if (strlen (str
) == 0)
438 /******************************************************************************
440 * Like strscpy, except only the portion of the source string up to
441 * the provided delimiter is copied.
445 * str = strpcpy(str,"This is a line of text with no trailing newline","x");
446 * printf("%s\n",str);
450 *This is a line of te
452 *****************************************************************************/
455 strpcpy (char *dest
, const char *src
, const char *str
)
460 len
= strcspn (src
, str
);
464 if (dest
== NULL
|| strlen (dest
) < len
)
465 dest
= realloc (dest
, len
+ 1);
467 die (STATE_UNKNOWN
, _("failed realloc in strpcpy\n"));
469 strncpy (dest
, src
, len
);
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 *****************************************************************************/
491 strpcat (char *dest
, const char *src
, const char *str
)
501 l2
= strcspn (src
, str
);
507 dest
= realloc (dest
, len
+ l2
+ 1);
509 die (STATE_UNKNOWN
, _("failed malloc in strscat\n"));
511 strncpy (dest
+ len
, src
, l2
);
512 dest
[len
+ l2
] = '\0';
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"));
534 xasprintf (char **strp
, const char *fmt
, ...)
539 result
= xvasprintf (strp
, fmt
, ap
);
544 /******************************************************************************
546 * Print perfdata in a standard format
548 ******************************************************************************/
550 char *perfdata (const char *label
,
564 if (strpbrk (label
, "'= "))
565 xasprintf (&data
, "'%s'=%ld%s;", label
, val
, uom
);
567 xasprintf (&data
, "%s=%ld%s;", label
, val
, uom
);
570 xasprintf (&data
, "%s%ld;", data
, warn
);
572 xasprintf (&data
, "%s;", data
);
575 xasprintf (&data
, "%s%ld;", data
, crit
);
577 xasprintf (&data
, "%s;", data
);
580 xasprintf (&data
, "%s%ld", data
, minv
);
583 xasprintf (&data
, "%s;%ld", data
, maxv
);
589 char *fperfdata (const char *label
,
603 if (strpbrk (label
, "'= "))
604 xasprintf (&data
, "'%s'=", label
);
606 xasprintf (&data
, "%s=", label
);
608 xasprintf (&data
, "%s%f", data
, val
);
609 xasprintf (&data
, "%s%s;", data
, uom
);
612 xasprintf (&data
, "%s%f", data
, warn
);
614 xasprintf (&data
, "%s;", data
);
617 xasprintf (&data
, "%s%f", data
, crit
);
619 xasprintf (&data
, "%s;", data
);
622 xasprintf (&data
, "%s%f", data
, minv
);
625 xasprintf (&data
, "%s;", data
);
626 xasprintf (&data
, "%s%f", data
, maxv
);