Code

bump copyright year
[nagiosplug.git] / plugins / utils.c
1 /*****************************************************************************
2  *
3  * utils.c
4  *
5  * Library of useful functions for plugins
6  *
7  * Copyright (c) 2000 Karl DeBisschop (karl@debisschop.net)
8  * License: GPL
9  *
10  * $Revision$
11  * $Date$
12  ****************************************************************************/
14 #define LOCAL_TIMEOUT_ALARM_HANDLER
16 #include "common.h"
17 #include "utils.h"
18 #include <stdarg.h>
19 #include <limits.h>
21 #include <arpa/inet.h>
23 extern void print_usage (void);
24 extern const char *progname;
26 #define STRLEN 64
27 #define TXTBLK 128
29 /* **************************************************************************
30  * max_state(STATE_x, STATE_y)
31  * compares STATE_x to  STATE_y and returns result based on the following
32  * STATE_UNKNOWN < STATE_OK < STATE_WARNING < STATE_CRITICAL
33  *
34  * Note that numerically the above does not hold
35  ****************************************************************************/
37 int
38 max_state (int a, int b)
39 {
40         if (a == STATE_CRITICAL || b == STATE_CRITICAL)
41                 return STATE_CRITICAL;
42         else if (a == STATE_WARNING || b == STATE_WARNING)
43                 return STATE_WARNING;
44         else if (a == STATE_OK || b == STATE_OK)
45                 return STATE_OK;
46         else if (a == STATE_UNKNOWN || b == STATE_UNKNOWN)
47                 return STATE_UNKNOWN;
48         else if (a == STATE_DEPENDENT || b == STATE_DEPENDENT)
49                 return STATE_DEPENDENT;
50         else
51                 return max (a, b);
52 }
54 void usage (const char *msg)
55 {
56         printf ("%s", msg);
57         print_usage ();
58         exit (STATE_UNKNOWN);
59 }
61 void usage2(const char *msg, const char *arg)
62 {
63         printf ("%s: %s - %s\n",progname,msg,arg);
64         print_usage ();
65         exit (STATE_UNKNOWN);
66 }
68 void
69 usage3 (const char *msg, int arg)
70 {
71         printf ("%s: %s - %c\n", progname, msg, arg);
72         print_usage();
73         exit (STATE_UNKNOWN);
74 }
76 void
77 usage4 (const char *msg)
78 {
79         printf ("%s: %s\n", progname, msg);
80         print_usage();
81         exit (STATE_UNKNOWN);
82 }
84 void
85 support (void)
86 {
87         printf (_("\n\
88 Send email to nagios-users@lists.sourceforge.net if you have questions\n\
89 regarding use of this software. To submit patches or suggest improvements,\n\
90 send email to nagiosplug-devel@lists.sourceforge.net\n"));
91 }
94 char *
95 clean_revstring (const char *revstring)
96 {
97         char plugin_revision[STRLEN];
98         if (sscanf (revstring,"$Revision: %[0-9.]",plugin_revision) == 1)
99                 return strscpy (NULL, plugin_revision);
100         else
101           return strscpy (NULL, "N/A");
104 void
105 print_revision (const char *command_name, const char *revision_string)
107         char plugin_revision[STRLEN];
109         if (sscanf (revision_string, "$Revision: %[0-9.]", plugin_revision) != 1)
110                 strncpy (plugin_revision, "N/A", STRLEN);
111         printf ("%s (%s %s) %s\n",
112                                         command_name, PACKAGE, VERSION, plugin_revision);
113         printf (_("\
114 The nagios plugins come with ABSOLUTELY NO WARRANTY. You may redistribute\n\
115 copies of the plugins under the terms of the GNU General Public License.\n\
116 For more information about these matters, see the file named COPYING.\n"));
120 const char *
121 state_text (int result)
123         switch (result) {
124         case STATE_OK:
125                 return "OK";
126         case STATE_WARNING:
127                 return "WARNING";
128         case STATE_CRITICAL:
129                 return "CRITICAL";
130         case STATE_DEPENDENT:
131                 return "DEPENDENT";
132         default:
133                 return "UNKNOWN";
134         }
137 void
138 die (int result, const char *fmt, ...)
140         va_list ap;
141         va_start (ap, fmt);
142         vprintf (fmt, ap);
143         va_end (ap);
144         exit (result);
147 void
148 timeout_alarm_handler (int signo)
150         if (signo == SIGALRM) {
151                 printf ("CRITICAL - Plugin timed out after %d seconds\n",
152                                                 timeout_interval);
153                 exit (STATE_CRITICAL);
154         }
157 int
158 is_numeric (char *number)
160         char tmp[1];
161         float x;
163         if (!number)
164                 return FALSE;
165         else if (sscanf (number, "%f%c", &x, tmp) == 1)
166                 return TRUE;
167         else
168                 return FALSE;
171 int
172 is_positive (char *number)
174         if (is_numeric (number) && atof (number) > 0.0)
175                 return TRUE;
176         else
177                 return FALSE;
180 int
181 is_negative (char *number)
183         if (is_numeric (number) && atof (number) < 0.0)
184                 return TRUE;
185         else
186                 return FALSE;
189 int
190 is_nonnegative (char *number)
192         if (is_numeric (number) && atof (number) >= 0.0)
193                 return TRUE;
194         else
195                 return FALSE;
198 int
199 is_percentage (char *number)
201         int x;
202         if (is_numeric (number) && (x = atof (number)) >= 0 && x <= 100)
203                 return TRUE;
204         else
205                 return FALSE;
208 int
209 is_integer (char *number)
211         long int n;
213         if (!number || (strspn (number, "-0123456789 ") != strlen (number)))
214                 return FALSE;
216         n = strtol (number, NULL, 10);
218         if (errno != ERANGE && n >= INT_MIN && n <= INT_MAX)
219                 return TRUE;
220         else
221                 return FALSE;
224 int
225 is_intpos (char *number)
227         if (is_integer (number) && atoi (number) > 0)
228                 return TRUE;
229         else
230                 return FALSE;
233 int
234 is_intneg (char *number)
236         if (is_integer (number) && atoi (number) < 0)
237                 return TRUE;
238         else
239                 return FALSE;
242 int
243 is_intnonneg (char *number)
245         if (is_integer (number) && atoi (number) >= 0)
246                 return TRUE;
247         else
248                 return FALSE;
251 int
252 is_intpercent (char *number)
254         int i;
255         if (is_integer (number) && (i = atoi (number)) >= 0 && i <= 100)
256                 return TRUE;
257         else
258                 return FALSE;
261 int
262 is_option (char *str)
264         if (!str)
265                 return FALSE;
266         else if (strspn (str, "-") == 1 || strspn (str, "-") == 2)
267                 return TRUE;
268         else
269                 return FALSE;
274 #ifdef NEED_GETTIMEOFDAY
275 int
276 gettimeofday (struct timeval *tv, struct timezone *tz)
278         tv->tv_usec = 0;
279         tv->tv_sec = (long) time ((time_t) 0);
281 #endif
285 double
286 delta_time (struct timeval tv)
288         struct timeval now;
290         gettimeofday (&now, NULL);
291         return ((double)(now.tv_sec - tv.tv_sec) + (double)(now.tv_usec - tv.tv_usec) / (double)1000000);
296 long
297 deltime (struct timeval tv)
299         struct timeval now;
300         gettimeofday (&now, NULL);
301         return (now.tv_sec - tv.tv_sec)*1000000 + now.tv_usec - tv.tv_usec;
307 void
308 strip (char *buffer)
310         size_t x;
311         int i;
313         for (x = strlen (buffer); x >= 1; x--) {
314                 i = x - 1;
315                 if (buffer[i] == ' ' ||
316                                 buffer[i] == '\r' || buffer[i] == '\n' || buffer[i] == '\t')
317                         buffer[i] = '\0';
318                 else
319                         break;
320         }
321         return;
325 /******************************************************************************
326  *
327  * Copies one string to another. Any previously existing data in
328  * the destination string is lost.
329  *
330  * Example:
331  *
332  * char *str=NULL;
333  * str = strscpy("This is a line of text with no trailing newline");
334  *
335  *****************************************************************************/
337 char *
338 strscpy (char *dest, const char *src)
340         if (src == NULL)
341                 return NULL;
343         asprintf (&dest, "%s", src);
345         return dest;
350 /******************************************************************************
351  *
352  * Returns a pointer to the next line of a multiline string buffer
353  *
354  * Given a pointer string, find the text following the next sequence
355  * of \r and \n characters. This has the effect of skipping blank
356  * lines as well
357  *
358  * Example:
359  *
360  * Given text as follows:
361  *
362  * ==============================
363  * This
364  * is
365  * a
366  * 
367  * multiline string buffer
368  * ==============================
369  *
370  * int i=0;
371  * char *str=NULL;
372  * char *ptr=NULL;
373  * str = strscpy(str,"This\nis\r\na\n\nmultiline string buffer\n");
374  * ptr = str;
375  * while (ptr) {
376  *   printf("%d %s",i++,firstword(ptr));
377  *   ptr = strnl(ptr);
378  * }
379  * 
380  * Produces the following:
381  *
382  * 1 This
383  * 2 is
384  * 3 a
385  * 4 multiline
386  *
387  * NOTE: The 'firstword()' function is conceptual only and does not
388  *       exist in this package.
389  *
390  * NOTE: Although the second 'ptr' variable is not strictly needed in
391  *       this example, it is good practice with these utilities. Once
392  *       the * pointer is advance in this manner, it may no longer be
393  *       handled with * realloc(). So at the end of the code fragment
394  *       above, * strscpy(str,"foo") work perfectly fine, but
395  *       strscpy(ptr,"foo") will * cause the the program to crash with
396  *       a segmentation fault.
397  *
398  *****************************************************************************/
400 char *
401 strnl (char *str)
403         size_t len;
404         if (str == NULL)
405                 return NULL;
406         str = strpbrk (str, "\r\n");
407         if (str == NULL)
408                 return NULL;
409         len = strspn (str, "\r\n");
410         if (str[len] == '\0')
411                 return NULL;
412         str += len;
413         if (strlen (str) == 0)
414                 return NULL;
415         return str;
419 /******************************************************************************
420  *
421  * Like strscpy, except only the portion of the source string up to
422  * the provided delimiter is copied.
423  *
424  * Example:
425  *
426  * str = strpcpy(str,"This is a line of text with no trailing newline","x");
427  * printf("%s\n",str);
428  *
429  * Produces:
430  *
431  *This is a line of te
432  *
433  *****************************************************************************/
435 char *
436 strpcpy (char *dest, const char *src, const char *str)
438         size_t len;
440         if (src)
441                 len = strcspn (src, str);
442         else
443                 return NULL;
445         if (dest == NULL || strlen (dest) < len)
446                 dest = realloc (dest, len + 1);
447         if (dest == NULL)
448                 die (STATE_UNKNOWN, "failed realloc in strpcpy\n");
450         strncpy (dest, src, len);
451         dest[len] = '\0';
453         return dest;
458 /******************************************************************************
459  *
460  * Like strscat, except only the portion of the source string up to
461  * the provided delimiter is copied.
462  *
463  * str = strpcpy(str,"This is a line of text with no trailing newline","x");
464  * str = strpcat(str,"This is a line of text with no trailing newline","x");
465  * printf("%s\n",str);
466  * 
467  *This is a line of texThis is a line of tex
468  *
469  *****************************************************************************/
471 char *
472 strpcat (char *dest, const char *src, const char *str)
474         size_t len, l2;
476         if (dest)
477                 len = strlen (dest);
478         else
479                 len = 0;
481         if (src) {
482                 l2 = strcspn (src, str);
483         }
484         else {
485                 return dest;
486         }
488         dest = realloc (dest, len + l2 + 1);
489         if (dest == NULL)
490                 die (STATE_UNKNOWN, "failed malloc in strscat\n");
492         strncpy (dest + len, src, l2);
493         dest[len + l2] = '\0';
495         return dest;
499 /******************************************************************************
500  *
501  * Print perfdata in a standard format
502  *
503  ******************************************************************************/
505 char *perfdata (const char *label,
506  long int val,
507  const char *uom,
508  int warnp,
509  long int warn,
510  int critp,
511  long int crit,
512  int minp,
513  long int minv,
514  int maxp,
515  long int maxv)
517         char *data = NULL;
519         if (strpbrk (label, "'= "))
520                 asprintf (&data, "'%s'=%ld%s;", label, val, uom);
521         else
522                 asprintf (&data, "%s=%ld%s;", label, val, uom);
524         if (warnp)
525                 asprintf (&data, "%s%ld;", data, warn);
526         else
527                 asprintf (&data, "%s;", data);
529         if (critp)
530                 asprintf (&data, "%s%ld;", data, crit);
531         else
532                 asprintf (&data, "%s;", data);
534         if (minp)
535                 asprintf (&data, "%s%ld", data, minv);
537         if (maxp)
538                 asprintf (&data, "%s;%ld", data, maxv);
540         return data;
544 char *fperfdata (const char *label,
545  double val,
546  const char *uom,
547  int warnp,
548  double warn,
549  int critp,
550  double crit,
551  int minp,
552  double minv,
553  int maxp,
554  double maxv)
556         char *data = NULL;
558         if (strpbrk (label, "'= "))
559                 asprintf (&data, "'%s'=", label);
560         else
561                 asprintf (&data, "%s=", label);
563         asprintf (&data, "%s%f", data, val);
564         asprintf (&data, "%s%s;", data, uom);
566         if (warnp)
567                 asprintf (&data, "%s%f", data, warn);
569         asprintf (&data, "%s;", data);
571         if (critp)
572                 asprintf (&data, "%s%f", data, crit);
574         asprintf (&data, "%s;", data);
576         if (minp)
577                 asprintf (&data, "%s%f", data, minv);
579         if (maxp) {
580                 asprintf (&data, "%s;", data);
581                 asprintf (&data, "%s%f", data, maxv);
582         }
584         return data;