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 char plugin_revision
[STRLEN
];
149 printf ("%s v%s (%s %s)\n",
150 command_name
, revision
, PACKAGE
, VERSION
);
154 state_text (int result
)
163 case STATE_DEPENDENT
:
171 timeout_alarm_handler (int signo
)
173 if (signo
== SIGALRM
) {
174 printf (_("%s - Plugin timed out after %d seconds\n"),
175 state_text(timeout_state
), timeout_interval
);
176 exit (timeout_state
);
181 is_numeric (char *number
)
188 else if (sscanf (number
, "%f%c", &x
, tmp
) == 1)
195 is_positive (char *number
)
197 if (is_numeric (number
) && atof (number
) > 0.0)
204 is_negative (char *number
)
206 if (is_numeric (number
) && atof (number
) < 0.0)
213 is_nonnegative (char *number
)
215 if (is_numeric (number
) && atof (number
) >= 0.0)
222 is_percentage (char *number
)
225 if (is_numeric (number
) && (x
= atof (number
)) >= 0 && x
<= 100)
232 is_integer (char *number
)
236 if (!number
|| (strspn (number
, "-0123456789 ") != strlen (number
)))
239 n
= strtol (number
, NULL
, 10);
241 if (errno
!= ERANGE
&& n
>= INT_MIN
&& n
<= INT_MAX
)
248 is_intpos (char *number
)
250 if (is_integer (number
) && atoi (number
) > 0)
257 is_intneg (char *number
)
259 if (is_integer (number
) && atoi (number
) < 0)
266 is_intnonneg (char *number
)
268 if (is_integer (number
) && atoi (number
) >= 0)
275 is_intpercent (char *number
)
278 if (is_integer (number
) && (i
= atoi (number
)) >= 0 && i
<= 100)
285 is_option (char *str
)
289 else if (strspn (str
, "-") == 1 || strspn (str
, "-") == 2)
295 #ifdef NEED_GETTIMEOFDAY
297 gettimeofday (struct timeval
*tv
, struct timezone
*tz
)
300 tv
->tv_sec
= (long) time ((time_t) 0);
307 delta_time (struct timeval tv
)
311 gettimeofday (&now
, NULL
);
312 return ((double)(now
.tv_sec
- tv
.tv_sec
) + (double)(now
.tv_usec
- tv
.tv_usec
) / (double)1000000);
318 deltime (struct timeval tv
)
321 gettimeofday (&now
, NULL
);
322 return (now
.tv_sec
- tv
.tv_sec
)*1000000 + now
.tv_usec
- tv
.tv_usec
;
334 for (x
= strlen (buffer
); x
>= 1; x
--) {
336 if (buffer
[i
] == ' ' ||
337 buffer
[i
] == '\r' || buffer
[i
] == '\n' || buffer
[i
] == '\t')
346 /******************************************************************************
348 * Copies one string to another. Any previously existing data in
349 * the destination string is lost.
354 * str = strscpy("This is a line of text with no trailing newline");
356 *****************************************************************************/
359 strscpy (char *dest
, const char *src
)
364 xasprintf (&dest
, "%s", src
);
371 /******************************************************************************
373 * Returns a pointer to the next line of a multiline string buffer
375 * Given a pointer string, find the text following the next sequence
376 * of \r and \n characters. This has the effect of skipping blank
381 * Given text as follows:
383 * ==============================
388 * multiline string buffer
389 * ==============================
394 * str = strscpy(str,"This\nis\r\na\n\nmultiline string buffer\n");
397 * printf("%d %s",i++,firstword(ptr));
401 * Produces the following:
408 * NOTE: The 'firstword()' function is conceptual only and does not
409 * exist in this package.
411 * NOTE: Although the second 'ptr' variable is not strictly needed in
412 * this example, it is good practice with these utilities. Once
413 * the * pointer is advance in this manner, it may no longer be
414 * handled with * realloc(). So at the end of the code fragment
415 * above, * strscpy(str,"foo") work perfectly fine, but
416 * strscpy(ptr,"foo") will * cause the the program to crash with
417 * a segmentation fault.
419 *****************************************************************************/
427 str
= strpbrk (str
, "\r\n");
430 len
= strspn (str
, "\r\n");
431 if (str
[len
] == '\0')
434 if (strlen (str
) == 0)
440 /******************************************************************************
442 * Like strscpy, except only the portion of the source string up to
443 * the provided delimiter is copied.
447 * str = strpcpy(str,"This is a line of text with no trailing newline","x");
448 * printf("%s\n",str);
452 *This is a line of te
454 *****************************************************************************/
457 strpcpy (char *dest
, const char *src
, const char *str
)
462 len
= strcspn (src
, str
);
466 if (dest
== NULL
|| strlen (dest
) < len
)
467 dest
= realloc (dest
, len
+ 1);
469 die (STATE_UNKNOWN
, _("failed realloc in strpcpy\n"));
471 strncpy (dest
, src
, len
);
479 /******************************************************************************
481 * Like strscat, except only the portion of the source string up to
482 * the provided delimiter is copied.
484 * str = strpcpy(str,"This is a line of text with no trailing newline","x");
485 * str = strpcat(str,"This is a line of text with no trailing newline","x");
486 * printf("%s\n",str);
488 *This is a line of texThis is a line of tex
490 *****************************************************************************/
493 strpcat (char *dest
, const char *src
, const char *str
)
503 l2
= strcspn (src
, str
);
509 dest
= realloc (dest
, len
+ l2
+ 1);
511 die (STATE_UNKNOWN
, _("failed malloc in strscat\n"));
513 strncpy (dest
+ len
, src
, l2
);
514 dest
[len
+ l2
] = '\0';
520 /******************************************************************************
522 * asprintf, but die on failure
524 ******************************************************************************/
527 xvasprintf (char **strp
, const char *fmt
, va_list ap
)
529 int result
= vasprintf (strp
, fmt
, ap
);
530 if (result
== -1 || *strp
== NULL
)
531 die (STATE_UNKNOWN
, _("failed malloc in xvasprintf\n"));
536 xasprintf (char **strp
, const char *fmt
, ...)
541 result
= xvasprintf (strp
, fmt
, ap
);
546 /******************************************************************************
548 * Print perfdata in a standard format
550 ******************************************************************************/
552 char *perfdata (const char *label
,
566 if (strpbrk (label
, "'= "))
567 xasprintf (&data
, "'%s'=%ld%s;", label
, val
, uom
);
569 xasprintf (&data
, "%s=%ld%s;", label
, val
, uom
);
572 xasprintf (&data
, "%s%ld;", data
, warn
);
574 xasprintf (&data
, "%s;", data
);
577 xasprintf (&data
, "%s%ld;", data
, crit
);
579 xasprintf (&data
, "%s;", data
);
582 xasprintf (&data
, "%s%ld", data
, minv
);
585 xasprintf (&data
, "%s;%ld", data
, maxv
);
591 char *fperfdata (const char *label
,
605 if (strpbrk (label
, "'= "))
606 xasprintf (&data
, "'%s'=", label
);
608 xasprintf (&data
, "%s=", label
);
610 xasprintf (&data
, "%s%f", data
, val
);
611 xasprintf (&data
, "%s%s;", data
, uom
);
614 xasprintf (&data
, "%s%f", data
, warn
);
616 xasprintf (&data
, "%s;", data
);
619 xasprintf (&data
, "%s%f", data
, crit
);
621 xasprintf (&data
, "%s;", data
);
624 xasprintf (&data
, "%s%f", data
, minv
);
627 xasprintf (&data
, "%s;", data
);
628 xasprintf (&data
, "%s%f", data
, maxv
);