Addition to help to state that -f will always return OK if ssh command
[monitoring-plugins.git] / plugins / utils.c
blobc8f3a00dd4c8cd297cfed5fba4532f1cb3811c2e
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 Nagios Plugin Development Team
8 *
9 * Last Modified: $Date$
12 * This program is free software: you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License as published by
14 * the Free Software Foundation, either version 3 of the License, or
15 * (at your option) any later version.
17 * This program is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 * GNU General Public License for more details.
22 * You should have received a copy of the GNU General Public License
23 * along with this program. If not, see <http://www.gnu.org/licenses/>.
25 * $Id$
27 *****************************************************************************/
29 #define LOCAL_TIMEOUT_ALARM_HANDLER
31 #include "common.h"
32 #include "utils.h"
33 #include "utils_base.h"
34 #include <stdarg.h>
35 #include <limits.h>
37 #include <arpa/inet.h>
39 extern void print_usage (void);
40 extern const char *progname;
42 #define STRLEN 64
43 #define TXTBLK 128
45 /* **************************************************************************
46 * max_state(STATE_x, STATE_y)
47 * compares STATE_x to STATE_y and returns result based on the following
48 * STATE_UNKNOWN < STATE_OK < STATE_WARNING < STATE_CRITICAL
50 * Note that numerically the above does not hold
51 ****************************************************************************/
53 int
54 max_state (int a, int b)
56 if (a == STATE_CRITICAL || b == STATE_CRITICAL)
57 return STATE_CRITICAL;
58 else if (a == STATE_WARNING || b == STATE_WARNING)
59 return STATE_WARNING;
60 else if (a == STATE_OK || b == STATE_OK)
61 return STATE_OK;
62 else if (a == STATE_UNKNOWN || b == STATE_UNKNOWN)
63 return STATE_UNKNOWN;
64 else if (a == STATE_DEPENDENT || b == STATE_DEPENDENT)
65 return STATE_DEPENDENT;
66 else
67 return max (a, b);
70 /* **************************************************************************
71 * max_state_alt(STATE_x, STATE_y)
72 * compares STATE_x to STATE_y and returns result based on the following
73 * STATE_OK < STATE_DEPENDENT < STATE_UNKNOWN < STATE_WARNING < STATE_CRITICAL
75 * The main difference between max_state_alt and max_state it that it doesn't
76 * allow setting a default to UNKNOWN. It will instead prioritixe any valid
77 * non-OK state.
78 ****************************************************************************/
80 int
81 max_state_alt (int a, int b)
83 if (a == STATE_CRITICAL || b == STATE_CRITICAL)
84 return STATE_CRITICAL;
85 else if (a == STATE_WARNING || b == STATE_WARNING)
86 return STATE_WARNING;
87 else if (a == STATE_UNKNOWN || b == STATE_UNKNOWN)
88 return STATE_UNKNOWN;
89 else if (a == STATE_DEPENDENT || b == STATE_DEPENDENT)
90 return STATE_DEPENDENT;
91 else if (a == STATE_OK || b == STATE_OK)
92 return STATE_OK;
93 else
94 return max (a, b);
97 void usage (const char *msg)
99 printf ("%s\n", msg);
100 print_usage ();
101 exit (STATE_UNKNOWN);
104 void usage_va (const char *fmt, ...)
106 va_list ap;
107 printf("%s: ", progname);
108 va_start(ap, fmt);
109 vprintf(fmt, ap);
110 va_end(ap);
111 printf("\n");
112 exit (STATE_UNKNOWN);
115 void usage2(const char *msg, const char *arg)
117 printf ("%s: %s - %s\n", progname, msg, arg?arg:"(null)" );
118 print_usage ();
119 exit (STATE_UNKNOWN);
122 void
123 usage3 (const char *msg, int arg)
125 printf ("%s: %s - %c\n", progname, msg, arg);
126 print_usage();
127 exit (STATE_UNKNOWN);
130 void
131 usage4 (const char *msg)
133 printf ("%s: %s\n", progname, msg);
134 print_usage();
135 exit (STATE_UNKNOWN);
138 void
139 usage5 (void)
141 print_usage();
142 exit (STATE_UNKNOWN);
145 char *
146 clean_revstring (const char *revstring)
148 char plugin_revision[STRLEN];
149 plugin_revision[0] = 'v';
150 if (sscanf (revstring,"$Revision: %[0-9.]", plugin_revision + 1) == 1)
151 return strscpy (NULL, plugin_revision);
152 else
153 return strscpy (NULL, "N/A");
156 void
157 print_revision (const char *command_name, const char *revision_string)
159 char plugin_revision[STRLEN];
161 printf ("%s %s (%s %s)\n",
162 command_name, clean_revstring(revision_string), PACKAGE, VERSION);
165 const char *
166 state_text (int result)
168 switch (result) {
169 case STATE_OK:
170 return "OK";
171 case STATE_WARNING:
172 return "WARNING";
173 case STATE_CRITICAL:
174 return "CRITICAL";
175 case STATE_DEPENDENT:
176 return "DEPENDENT";
177 default:
178 return "UNKNOWN";
182 void
183 timeout_alarm_handler (int signo)
185 if (signo == SIGALRM) {
186 printf (_("CRITICAL - Plugin timed out after %d seconds\n"),
187 timeout_interval);
188 exit (STATE_CRITICAL);
193 is_numeric (char *number)
195 char tmp[1];
196 float x;
198 if (!number)
199 return FALSE;
200 else if (sscanf (number, "%f%c", &x, tmp) == 1)
201 return TRUE;
202 else
203 return FALSE;
207 is_positive (char *number)
209 if (is_numeric (number) && atof (number) > 0.0)
210 return TRUE;
211 else
212 return FALSE;
216 is_negative (char *number)
218 if (is_numeric (number) && atof (number) < 0.0)
219 return TRUE;
220 else
221 return FALSE;
225 is_nonnegative (char *number)
227 if (is_numeric (number) && atof (number) >= 0.0)
228 return TRUE;
229 else
230 return FALSE;
234 is_percentage (char *number)
236 int x;
237 if (is_numeric (number) && (x = atof (number)) >= 0 && x <= 100)
238 return TRUE;
239 else
240 return FALSE;
244 is_integer (char *number)
246 long int n;
248 if (!number || (strspn (number, "-0123456789 ") != strlen (number)))
249 return FALSE;
251 n = strtol (number, NULL, 10);
253 if (errno != ERANGE && n >= INT_MIN && n <= INT_MAX)
254 return TRUE;
255 else
256 return FALSE;
260 is_intpos (char *number)
262 if (is_integer (number) && atoi (number) > 0)
263 return TRUE;
264 else
265 return FALSE;
269 is_intneg (char *number)
271 if (is_integer (number) && atoi (number) < 0)
272 return TRUE;
273 else
274 return FALSE;
278 is_intnonneg (char *number)
280 if (is_integer (number) && atoi (number) >= 0)
281 return TRUE;
282 else
283 return FALSE;
287 is_intpercent (char *number)
289 int i;
290 if (is_integer (number) && (i = atoi (number)) >= 0 && i <= 100)
291 return TRUE;
292 else
293 return FALSE;
297 is_option (char *str)
299 if (!str)
300 return FALSE;
301 else if (strspn (str, "-") == 1 || strspn (str, "-") == 2)
302 return TRUE;
303 else
304 return FALSE;
307 #ifdef NEED_GETTIMEOFDAY
309 gettimeofday (struct timeval *tv, struct timezone *tz)
311 tv->tv_usec = 0;
312 tv->tv_sec = (long) time ((time_t) 0);
314 #endif
318 double
319 delta_time (struct timeval tv)
321 struct timeval now;
323 gettimeofday (&now, NULL);
324 return ((double)(now.tv_sec - tv.tv_sec) + (double)(now.tv_usec - tv.tv_usec) / (double)1000000);
329 long
330 deltime (struct timeval tv)
332 struct timeval now;
333 gettimeofday (&now, NULL);
334 return (now.tv_sec - tv.tv_sec)*1000000 + now.tv_usec - tv.tv_usec;
340 void
341 strip (char *buffer)
343 size_t x;
344 int i;
346 for (x = strlen (buffer); x >= 1; x--) {
347 i = x - 1;
348 if (buffer[i] == ' ' ||
349 buffer[i] == '\r' || buffer[i] == '\n' || buffer[i] == '\t')
350 buffer[i] = '\0';
351 else
352 break;
354 return;
358 /******************************************************************************
360 * Copies one string to another. Any previously existing data in
361 * the destination string is lost.
363 * Example:
365 * char *str=NULL;
366 * str = strscpy("This is a line of text with no trailing newline");
368 *****************************************************************************/
370 char *
371 strscpy (char *dest, const char *src)
373 if (src == NULL)
374 return NULL;
376 asprintf (&dest, "%s", src);
378 return dest;
383 /******************************************************************************
385 * Returns a pointer to the next line of a multiline string buffer
387 * Given a pointer string, find the text following the next sequence
388 * of \r and \n characters. This has the effect of skipping blank
389 * lines as well
391 * Example:
393 * Given text as follows:
395 * ==============================
396 * This
397 * is
400 * multiline string buffer
401 * ==============================
403 * int i=0;
404 * char *str=NULL;
405 * char *ptr=NULL;
406 * str = strscpy(str,"This\nis\r\na\n\nmultiline string buffer\n");
407 * ptr = str;
408 * while (ptr) {
409 * printf("%d %s",i++,firstword(ptr));
410 * ptr = strnl(ptr);
413 * Produces the following:
415 * 1 This
416 * 2 is
417 * 3 a
418 * 4 multiline
420 * NOTE: The 'firstword()' function is conceptual only and does not
421 * exist in this package.
423 * NOTE: Although the second 'ptr' variable is not strictly needed in
424 * this example, it is good practice with these utilities. Once
425 * the * pointer is advance in this manner, it may no longer be
426 * handled with * realloc(). So at the end of the code fragment
427 * above, * strscpy(str,"foo") work perfectly fine, but
428 * strscpy(ptr,"foo") will * cause the the program to crash with
429 * a segmentation fault.
431 *****************************************************************************/
433 char *
434 strnl (char *str)
436 size_t len;
437 if (str == NULL)
438 return NULL;
439 str = strpbrk (str, "\r\n");
440 if (str == NULL)
441 return NULL;
442 len = strspn (str, "\r\n");
443 if (str[len] == '\0')
444 return NULL;
445 str += len;
446 if (strlen (str) == 0)
447 return NULL;
448 return str;
452 /******************************************************************************
454 * Like strscpy, except only the portion of the source string up to
455 * the provided delimiter is copied.
457 * Example:
459 * str = strpcpy(str,"This is a line of text with no trailing newline","x");
460 * printf("%s\n",str);
462 * Produces:
464 *This is a line of te
466 *****************************************************************************/
468 char *
469 strpcpy (char *dest, const char *src, const char *str)
471 size_t len;
473 if (src)
474 len = strcspn (src, str);
475 else
476 return NULL;
478 if (dest == NULL || strlen (dest) < len)
479 dest = realloc (dest, len + 1);
480 if (dest == NULL)
481 die (STATE_UNKNOWN, _("failed realloc in strpcpy\n"));
483 strncpy (dest, src, len);
484 dest[len] = '\0';
486 return dest;
491 /******************************************************************************
493 * Like strscat, except only the portion of the source string up to
494 * the provided delimiter is copied.
496 * str = strpcpy(str,"This is a line of text with no trailing newline","x");
497 * str = strpcat(str,"This is a line of text with no trailing newline","x");
498 * printf("%s\n",str);
500 *This is a line of texThis is a line of tex
502 *****************************************************************************/
504 char *
505 strpcat (char *dest, const char *src, const char *str)
507 size_t len, l2;
509 if (dest)
510 len = strlen (dest);
511 else
512 len = 0;
514 if (src) {
515 l2 = strcspn (src, str);
517 else {
518 return dest;
521 dest = realloc (dest, len + l2 + 1);
522 if (dest == NULL)
523 die (STATE_UNKNOWN, _("failed malloc in strscat\n"));
525 strncpy (dest + len, src, l2);
526 dest[len + l2] = '\0';
528 return dest;
531 /******************************************************************************
533 * Print perfdata in a standard format
535 ******************************************************************************/
537 char *perfdata (const char *label,
538 long int val,
539 const char *uom,
540 int warnp,
541 long int warn,
542 int critp,
543 long int crit,
544 int minp,
545 long int minv,
546 int maxp,
547 long int maxv)
549 char *data = NULL;
551 if (strpbrk (label, "'= "))
552 asprintf (&data, "'%s'=%ld%s;", label, val, uom);
553 else
554 asprintf (&data, "%s=%ld%s;", label, val, uom);
556 if (warnp)
557 asprintf (&data, "%s%ld;", data, warn);
558 else
559 asprintf (&data, "%s;", data);
561 if (critp)
562 asprintf (&data, "%s%ld;", data, crit);
563 else
564 asprintf (&data, "%s;", data);
566 if (minp)
567 asprintf (&data, "%s%ld", data, minv);
569 if (maxp)
570 asprintf (&data, "%s;%ld", data, maxv);
572 return data;
576 char *fperfdata (const char *label,
577 double val,
578 const char *uom,
579 int warnp,
580 double warn,
581 int critp,
582 double crit,
583 int minp,
584 double minv,
585 int maxp,
586 double maxv)
588 char *data = NULL;
590 if (strpbrk (label, "'= "))
591 asprintf (&data, "'%s'=", label);
592 else
593 asprintf (&data, "%s=", label);
595 asprintf (&data, "%s%f", data, val);
596 asprintf (&data, "%s%s;", data, uom);
598 if (warnp)
599 asprintf (&data, "%s%f", data, warn);
601 asprintf (&data, "%s;", data);
603 if (critp)
604 asprintf (&data, "%s%f", data, crit);
606 asprintf (&data, "%s;", data);
608 if (minp)
609 asprintf (&data, "%s%f", data, minv);
611 if (maxp) {
612 asprintf (&data, "%s;", data);
613 asprintf (&data, "%s%f", data, maxv);
616 return data;