1 /*****************************************************************************
5 * Library of useful functions for plugins
7 * Copyright (c) 2000 Karl DeBisschop (karl@debisschop.net)
8 * Copyright (c) 2006 Nagios Plugin Development Team
13 ****************************************************************************/
15 #define LOCAL_TIMEOUT_ALARM_HANDLER
19 #include "utils_base.h"
23 #include <arpa/inet.h>
25 extern void print_usage (void);
26 extern const char *progname
;
31 /* **************************************************************************
32 * max_state(STATE_x, STATE_y)
33 * compares STATE_x to STATE_y and returns result based on the following
34 * STATE_UNKNOWN < STATE_OK < STATE_WARNING < STATE_CRITICAL
36 * Note that numerically the above does not hold
37 ****************************************************************************/
40 max_state (int a
, int b
)
42 if (a
== STATE_CRITICAL
|| b
== STATE_CRITICAL
)
43 return STATE_CRITICAL
;
44 else if (a
== STATE_WARNING
|| b
== STATE_WARNING
)
46 else if (a
== STATE_OK
|| b
== STATE_OK
)
48 else if (a
== STATE_UNKNOWN
|| b
== STATE_UNKNOWN
)
50 else if (a
== STATE_DEPENDENT
|| b
== STATE_DEPENDENT
)
51 return STATE_DEPENDENT
;
56 void usage (const char *msg
)
63 void usage_va (const char *fmt
, ...)
66 printf("%s: ", progname
);
74 void usage2(const char *msg
, const char *arg
)
76 printf ("%s: %s - %s\n", progname
, msg
, arg
?arg
:"(null)" );
82 usage3 (const char *msg
, int arg
)
84 printf ("%s: %s - %c\n", progname
, msg
, arg
);
90 usage4 (const char *msg
)
92 printf ("%s: %s\n", progname
, msg
);
101 exit (STATE_UNKNOWN
);
105 clean_revstring (const char *revstring
)
107 char plugin_revision
[STRLEN
];
108 if (sscanf (revstring
,"$Revision: %[0-9.]",plugin_revision
) == 1)
109 return strscpy (NULL
, plugin_revision
);
111 return strscpy (NULL
, "N/A");
115 print_revision (const char *command_name
, const char *revision_string
)
117 char plugin_revision
[STRLEN
];
119 if (sscanf (revision_string
, "$Revision: %[0-9.]", plugin_revision
) != 1)
120 strncpy (plugin_revision
, "N/A", STRLEN
);
121 printf ("%s (%s %s) %s\n",
122 command_name
, PACKAGE
, VERSION
, plugin_revision
);
126 state_text (int result
)
135 case STATE_DEPENDENT
:
143 timeout_alarm_handler (int signo
)
145 if (signo
== SIGALRM
) {
146 printf (_("CRITICAL - Plugin timed out after %d seconds\n"),
148 exit (STATE_CRITICAL
);
153 is_numeric (char *number
)
160 else if (sscanf (number
, "%f%c", &x
, tmp
) == 1)
167 is_positive (char *number
)
169 if (is_numeric (number
) && atof (number
) > 0.0)
176 is_negative (char *number
)
178 if (is_numeric (number
) && atof (number
) < 0.0)
185 is_nonnegative (char *number
)
187 if (is_numeric (number
) && atof (number
) >= 0.0)
194 is_percentage (char *number
)
197 if (is_numeric (number
) && (x
= atof (number
)) >= 0 && x
<= 100)
204 is_integer (char *number
)
208 if (!number
|| (strspn (number
, "-0123456789 ") != strlen (number
)))
211 n
= strtol (number
, NULL
, 10);
213 if (errno
!= ERANGE
&& n
>= INT_MIN
&& n
<= INT_MAX
)
220 is_intpos (char *number
)
222 if (is_integer (number
) && atoi (number
) > 0)
229 is_intneg (char *number
)
231 if (is_integer (number
) && atoi (number
) < 0)
238 is_intnonneg (char *number
)
240 if (is_integer (number
) && atoi (number
) >= 0)
247 is_intpercent (char *number
)
250 if (is_integer (number
) && (i
= atoi (number
)) >= 0 && i
<= 100)
257 is_option (char *str
)
261 else if (strspn (str
, "-") == 1 || strspn (str
, "-") == 2)
267 #ifdef NEED_GETTIMEOFDAY
269 gettimeofday (struct timeval
*tv
, struct timezone
*tz
)
272 tv
->tv_sec
= (long) time ((time_t) 0);
279 delta_time (struct timeval tv
)
283 gettimeofday (&now
, NULL
);
284 return ((double)(now
.tv_sec
- tv
.tv_sec
) + (double)(now
.tv_usec
- tv
.tv_usec
) / (double)1000000);
290 deltime (struct timeval tv
)
293 gettimeofday (&now
, NULL
);
294 return (now
.tv_sec
- tv
.tv_sec
)*1000000 + now
.tv_usec
- tv
.tv_usec
;
306 for (x
= strlen (buffer
); x
>= 1; x
--) {
308 if (buffer
[i
] == ' ' ||
309 buffer
[i
] == '\r' || buffer
[i
] == '\n' || buffer
[i
] == '\t')
318 /******************************************************************************
320 * Copies one string to another. Any previously existing data in
321 * the destination string is lost.
326 * str = strscpy("This is a line of text with no trailing newline");
328 *****************************************************************************/
331 strscpy (char *dest
, const char *src
)
336 asprintf (&dest
, "%s", src
);
343 /******************************************************************************
345 * Returns a pointer to the next line of a multiline string buffer
347 * Given a pointer string, find the text following the next sequence
348 * of \r and \n characters. This has the effect of skipping blank
353 * Given text as follows:
355 * ==============================
360 * multiline string buffer
361 * ==============================
366 * str = strscpy(str,"This\nis\r\na\n\nmultiline string buffer\n");
369 * printf("%d %s",i++,firstword(ptr));
373 * Produces the following:
380 * NOTE: The 'firstword()' function is conceptual only and does not
381 * exist in this package.
383 * NOTE: Although the second 'ptr' variable is not strictly needed in
384 * this example, it is good practice with these utilities. Once
385 * the * pointer is advance in this manner, it may no longer be
386 * handled with * realloc(). So at the end of the code fragment
387 * above, * strscpy(str,"foo") work perfectly fine, but
388 * strscpy(ptr,"foo") will * cause the the program to crash with
389 * a segmentation fault.
391 *****************************************************************************/
399 str
= strpbrk (str
, "\r\n");
402 len
= strspn (str
, "\r\n");
403 if (str
[len
] == '\0')
406 if (strlen (str
) == 0)
412 /******************************************************************************
414 * Like strscpy, except only the portion of the source string up to
415 * the provided delimiter is copied.
419 * str = strpcpy(str,"This is a line of text with no trailing newline","x");
420 * printf("%s\n",str);
424 *This is a line of te
426 *****************************************************************************/
429 strpcpy (char *dest
, const char *src
, const char *str
)
434 len
= strcspn (src
, str
);
438 if (dest
== NULL
|| strlen (dest
) < len
)
439 dest
= realloc (dest
, len
+ 1);
441 die (STATE_UNKNOWN
, _("failed realloc in strpcpy\n"));
443 strncpy (dest
, src
, len
);
451 /******************************************************************************
453 * Like strscat, except only the portion of the source string up to
454 * the provided delimiter is copied.
456 * str = strpcpy(str,"This is a line of text with no trailing newline","x");
457 * str = strpcat(str,"This is a line of text with no trailing newline","x");
458 * printf("%s\n",str);
460 *This is a line of texThis is a line of tex
462 *****************************************************************************/
465 strpcat (char *dest
, const char *src
, const char *str
)
475 l2
= strcspn (src
, str
);
481 dest
= realloc (dest
, len
+ l2
+ 1);
483 die (STATE_UNKNOWN
, _("failed malloc in strscat\n"));
485 strncpy (dest
+ len
, src
, l2
);
486 dest
[len
+ l2
] = '\0';
491 /******************************************************************************
493 * Print perfdata in a standard format
495 ******************************************************************************/
497 char *perfdata (const char *label
,
511 if (strpbrk (label
, "'= "))
512 asprintf (&data
, "'%s'=%ld%s;", label
, val
, uom
);
514 asprintf (&data
, "%s=%ld%s;", label
, val
, uom
);
517 asprintf (&data
, "%s%ld;", data
, warn
);
519 asprintf (&data
, "%s;", data
);
522 asprintf (&data
, "%s%ld;", data
, crit
);
524 asprintf (&data
, "%s;", data
);
527 asprintf (&data
, "%s%ld", data
, minv
);
530 asprintf (&data
, "%s;%ld", data
, maxv
);
536 char *fperfdata (const char *label
,
550 if (strpbrk (label
, "'= "))
551 asprintf (&data
, "'%s'=", label
);
553 asprintf (&data
, "%s=", label
);
555 asprintf (&data
, "%s%f", data
, val
);
556 asprintf (&data
, "%s%s;", data
, uom
);
559 asprintf (&data
, "%s%f", data
, warn
);
561 asprintf (&data
, "%s;", data
);
564 asprintf (&data
, "%s%f", data
, crit
);
566 asprintf (&data
, "%s;", data
);
569 asprintf (&data
, "%s%f", data
, minv
);
572 asprintf (&data
, "%s;", data
);
573 asprintf (&data
, "%s%f", data
, maxv
);