Code

config.h is redundant (common.h includes it)
[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 }
77 void
78 support (void)
79 {
80         printf (_("\n\
81 Send email to nagios-users@lists.sourceforge.net if you have questions\n\
82 regarding use of this software. To submit patches or suggest improvements,\n\
83 send email to nagiosplug-devel@lists.sourceforge.net\n"));
84 }
87 char *
88 clean_revstring (const char *revstring)
89 {
90         char plugin_revision[STRLEN];
91         if (sscanf (revstring,"$Revision: %[0-9.]",plugin_revision) == 1)
92                 return strscpy (NULL, plugin_revision);
93         else
94           return strscpy (NULL, "N/A");
95 }
97 void
98 print_revision (const char *command_name, const char *revision_string)
99 {
100         char plugin_revision[STRLEN];
102         if (sscanf (revision_string, "$Revision: %[0-9.]", plugin_revision) != 1)
103                 strncpy (plugin_revision, "N/A", STRLEN);
104         printf ("%s (%s %s) %s\n",
105                                         command_name, PACKAGE, VERSION, plugin_revision);
106         printf (_("\
107 The nagios plugins come with ABSOLUTELY NO WARRANTY. You may redistribute\n\
108 copies of the plugins under the terms of the GNU General Public License.\n\
109 For more information about these matters, see the file named COPYING.\n"));
113 const char *
114 state_text (int result)
116         switch (result) {
117         case STATE_OK:
118                 return "OK";
119         case STATE_WARNING:
120                 return "WARNING";
121         case STATE_CRITICAL:
122                 return "CRITICAL";
123         case STATE_DEPENDENT:
124                 return "DEPENDENT";
125         default:
126                 return "UNKNOWN";
127         }
130 void
131 die (int result, const char *fmt, ...)
133         va_list ap;
134         va_start (ap, fmt);
135         vprintf (fmt, ap);
136         va_end (ap);
137         exit (result);
140 void
141 timeout_alarm_handler (int signo)
143         if (signo == SIGALRM) {
144                 printf ("CRITICAL - Plugin timed out after %d seconds\n",
145                                                 timeout_interval);
146                 exit (STATE_CRITICAL);
147         }
150 int
151 is_numeric (char *number)
153         char tmp[1];
154         float x;
156         if (!number)
157                 return FALSE;
158         else if (sscanf (number, "%f%c", &x, tmp) == 1)
159                 return TRUE;
160         else
161                 return FALSE;
164 int
165 is_positive (char *number)
167         if (is_numeric (number) && atof (number) > 0.0)
168                 return TRUE;
169         else
170                 return FALSE;
173 int
174 is_negative (char *number)
176         if (is_numeric (number) && atof (number) < 0.0)
177                 return TRUE;
178         else
179                 return FALSE;
182 int
183 is_nonnegative (char *number)
185         if (is_numeric (number) && atof (number) >= 0.0)
186                 return TRUE;
187         else
188                 return FALSE;
191 int
192 is_percentage (char *number)
194         int x;
195         if (is_numeric (number) && (x = atof (number)) >= 0 && x <= 100)
196                 return TRUE;
197         else
198                 return FALSE;
201 int
202 is_integer (char *number)
204         long int n;
206         if (!number || (strspn (number, "-0123456789 ") != strlen (number)))
207                 return FALSE;
209         n = strtol (number, NULL, 10);
211         if (errno != ERANGE && n >= INT_MIN && n <= INT_MAX)
212                 return TRUE;
213         else
214                 return FALSE;
217 int
218 is_intpos (char *number)
220         if (is_integer (number) && atoi (number) > 0)
221                 return TRUE;
222         else
223                 return FALSE;
226 int
227 is_intneg (char *number)
229         if (is_integer (number) && atoi (number) < 0)
230                 return TRUE;
231         else
232                 return FALSE;
235 int
236 is_intnonneg (char *number)
238         if (is_integer (number) && atoi (number) >= 0)
239                 return TRUE;
240         else
241                 return FALSE;
244 int
245 is_intpercent (char *number)
247         int i;
248         if (is_integer (number) && (i = atoi (number)) >= 0 && i <= 100)
249                 return TRUE;
250         else
251                 return FALSE;
254 int
255 is_option (char *str)
257         if (!str)
258                 return FALSE;
259         else if (strspn (str, "-") == 1 || strspn (str, "-") == 2)
260                 return TRUE;
261         else
262                 return FALSE;
267 #ifdef NEED_GETTIMEOFDAY
268 int
269 gettimeofday (struct timeval *tv, struct timezone *tz)
271         tv->tv_usec = 0;
272         tv->tv_sec = (long) time ((time_t) 0);
274 #endif
278 double
279 delta_time (struct timeval tv)
281         struct timeval now;
283         gettimeofday (&now, NULL);
284         return ((double)(now.tv_sec - tv.tv_sec) + (double)(now.tv_usec - tv.tv_usec) / (double)1000000);
289 long
290 deltime (struct timeval tv)
292         struct timeval now;
293         gettimeofday (&now, NULL);
294         return (now.tv_sec - tv.tv_sec)*1000000 + now.tv_usec - tv.tv_usec;
300 void
301 strip (char *buffer)
303         size_t x;
304         int i;
306         for (x = strlen (buffer); x >= 1; x--) {
307                 i = x - 1;
308                 if (buffer[i] == ' ' ||
309                                 buffer[i] == '\r' || buffer[i] == '\n' || buffer[i] == '\t')
310                         buffer[i] = '\0';
311                 else
312                         break;
313         }
314         return;
321 /******************************************************************************
322  *
323  * Copies one string to another. Any previously existing data in
324  * the destination string is lost.
325  *
326  * Example:
327  *
328  * char *str=NULL;
329  * str = strscpy("This is a line of text with no trailing newline");
330  *
331  *****************************************************************************/
333 char *
334 strscpy (char *dest, const char *src)
336         if (src == NULL)
337                 return NULL;
339         asprintf (&dest, "%s", src);
341         return dest;
348 /******************************************************************************
349  *
350  * Returns a pointer to the next line of a multiline string buffer
351  *
352  * Given a pointer string, find the text following the next sequence
353  * of \r and \n characters. This has the effect of skipping blank
354  * lines as well
355  *
356  * Example:
357  *
358  * Given text as follows:
359  *
360  * ==============================
361  * This
362  * is
363  * a
364  * 
365  * multiline string buffer
366  * ==============================
367  *
368  * int i=0;
369  * char *str=NULL;
370  * char *ptr=NULL;
371  * str = strscpy(str,"This\nis\r\na\n\nmultiline string buffer\n");
372  * ptr = str;
373  * while (ptr) {
374  *   printf("%d %s",i++,firstword(ptr));
375  *   ptr = strnl(ptr);
376  * }
377  * 
378  * Produces the following:
379  *
380  * 1 This
381  * 2 is
382  * 3 a
383  * 4 multiline
384  *
385  * NOTE: The 'firstword()' function is conceptual only and does not
386  *       exist in this package.
387  *
388  * NOTE: Although the second 'ptr' variable is not strictly needed in
389  *       this example, it is good practice with these utilities. Once
390  *       the * pointer is advance in this manner, it may no longer be
391  *       handled with * realloc(). So at the end of the code fragment
392  *       above, * strscpy(str,"foo") work perfectly fine, but
393  *       strscpy(ptr,"foo") will * cause the the program to crash with
394  *       a segmentation fault.
395  *
396  *****************************************************************************/
398 char *
399 strnl (char *str)
401         size_t len;
402         if (str == NULL)
403                 return NULL;
404         str = strpbrk (str, "\r\n");
405         if (str == NULL)
406                 return NULL;
407         len = strspn (str, "\r\n");
408         if (str[len] == '\0')
409                 return NULL;
410         str += len;
411         if (strlen (str) == 0)
412                 return NULL;
413         return str;
420 /******************************************************************************
421  *
422  * Like strscpy, except only the portion of the source string up to
423  * the provided delimiter is copied.
424  *
425  * Example:
426  *
427  * str = strpcpy(str,"This is a line of text with no trailing newline","x");
428  * printf("%s\n",str);
429  *
430  * Produces:
431  *
432  *This is a line of te
433  *
434  *****************************************************************************/
436 char *
437 strpcpy (char *dest, const char *src, const char *str)
439         size_t len;
441         if (src)
442                 len = strcspn (src, str);
443         else
444                 return NULL;
446         if (dest == NULL || strlen (dest) < len)
447                 dest = realloc (dest, len + 1);
448         if (dest == NULL)
449                 die (STATE_UNKNOWN, "failed realloc in strpcpy\n");
451         strncpy (dest, src, len);
452         dest[len] = '\0';
454         return dest;
461 /******************************************************************************
462  *
463  * Like strscat, except only the portion of the source string up to
464  * the provided delimiter is copied.
465  *
466  * str = strpcpy(str,"This is a line of text with no trailing newline","x");
467  * str = strpcat(str,"This is a line of text with no trailing newline","x");
468  * printf("%s\n",str);
469  * 
470  *This is a line of texThis is a line of tex
471  *
472  *****************************************************************************/
474 char *
475 strpcat (char *dest, const char *src, const char *str)
477         size_t len, l2;
479         if (dest)
480                 len = strlen (dest);
481         else
482                 len = 0;
484         if (src) {
485                 l2 = strcspn (src, str);
486         }
487         else {
488                 return dest;
489         }
491         dest = realloc (dest, len + l2 + 1);
492         if (dest == NULL)
493                 die (STATE_UNKNOWN, "failed malloc in strscat\n");
495         strncpy (dest + len, src, l2);
496         dest[len + l2] = '\0';
498         return dest;