Code

checkins for internationalization
[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 #include "config.h"
15 #include "common.h"
16 #include <stdarg.h>
17 #include <limits.h>
19 #include <arpa/inet.h>
21 extern int timeout_interval;
22 extern const char *progname;
24 void support (void);
25 char *clean_revstring (const char *);
26 void print_revision (const char *, const char *);
27 void die (int result, const char *fmt, ...);
28 void terminate (int result, const char *fmt, ...);
29 RETSIGTYPE timeout_alarm_handler (int);
31 int is_integer (char *);
32 int is_intpos (char *);
33 int is_intneg (char *);
34 int is_intnonneg (char *);
35 int is_intpercent (char *);
37 int is_numeric (char *);
38 int is_positive (char *);
39 int is_negative (char *);
40 int is_nonnegative (char *);
41 int is_percentage (char *);
43 int is_option (char *str);
45 double delta_time (struct timeval tv);
47 void strip (char *);
48 char *strscpy (char *dest, const char *src);
49 char *strscat (char *dest, char *src);
50 char *strnl (char *str);
51 char *strpcpy (char *dest, const char *src, const char *str);
52 char *strpcat (char *dest, const char *src, const char *str);
54 char *state_text (int result);
56 #define STRLEN 64
57 #define TXTBLK 128
59 /* **************************************************************************
60  /* max_state(STATE_x, STATE_y)
61  * compares STATE_x to  STATE_y and returns result based on the following
62  * STATE_UNKNOWN < STATE_OK < STATE_WARNING < STATE_CRITICAL
63  *
64  * Note that numerically the above does not hold
65  ****************************************************************************/
67 #define max(a,b) (((a)>(b))?(a):(b))
69 int
70 max_state (int a, int b)
71 {
72         if (a == STATE_CRITICAL || b == STATE_CRITICAL)
73                 return STATE_CRITICAL;
74         else if (a == STATE_WARNING || b == STATE_WARNING)
75                 return STATE_WARNING;
76         else if (a == STATE_OK || b == STATE_OK)
77                 return STATE_OK;
78         else if (a == STATE_UNKNOWN || b == STATE_UNKNOWN)
79                 return STATE_UNKNOWN;
80         else if (a == STATE_DEPENDENT || b == STATE_DEPENDENT)
81                 return STATE_DEPENDENT;
82         else
83                 return max (a, b);
84 }
86 void usage (char *msg)
87 {
88         printf (msg);
89         print_usage ();
90         exit (STATE_UNKNOWN);
91 }
93 void usage2(char *msg, char *arg)
94 {
95         printf ("%s: %s - %s\n",progname,msg,arg);
96         print_usage ();
97         exit (STATE_UNKNOWN);
98 }
100 void
101 usage3 (char *msg, char arg)
103         printf ("%s: %s - %c\n", progname, msg, arg);
104         print_usage();
105         exit (STATE_UNKNOWN);
109 void
110 support (void)
112         printf
113                 ("Send email to nagios-users@lists.sourceforge.net if you have questions\n"
114                  "regarding use of this software. To submit patches or suggest improvements,\n"
115                  "send email to nagiosplug-devel@lists.sourceforge.net\n");
119 char *
120 clean_revstring (const char *revstring)
122         char plugin_revision[STRLEN];
123         if (sscanf (revstring,"$Revision: %[0-9.]",plugin_revision) == 1)
124                 return strscpy (NULL, plugin_revision);
125         else
126           return strscpy (NULL, "N/A");
129 void
130 print_revision (const char *command_name, const char *revision_string)
132         char plugin_revision[STRLEN];
134         if (sscanf (revision_string, "$Revision: %[0-9.]", plugin_revision) != 1)
135                 strncpy (plugin_revision, "N/A", STRLEN);
136         printf ("%s (%s %s) %s\n",
137                                         progname, PACKAGE, VERSION, plugin_revision);
138         printf
139                 ("The nagios plugins come with ABSOLUTELY NO WARRANTY. You may redistribute\n"
140                  "copies of the plugins under the terms of the GNU General Public License.\n"
141                  "For more information about these matters, see the file named COPYING.\n");
145 char *
146 state_text (int result)
148         switch (result) {
149         case STATE_OK:
150                 return "OK";
151         case STATE_WARNING:
152                 return "WARNING";
153         case STATE_CRITICAL:
154                 return "CRITICAL";
155         case STATE_DEPENDENT:
156                 return "DEPENDENT";
157         default:
158                 return "UNKNOWN";
159         }
162 void
163 die (int result, const char *fmt, ...)
165         va_list ap;
166         printf ("%s %s: ", sizeof (char) + index(progname, '_'), state_text(result));
167         va_start (ap, fmt);
168         vprintf (fmt, ap);
169         va_end (ap);
170         exit (result);
173 void
174 terminate (int result, const char *fmt, ...)
176         va_list ap;
177         va_start (ap, fmt);
178         vprintf (fmt, ap);
179         va_end (ap);
180         exit (result);
183 void
184 timeout_alarm_handler (int signo)
186         if (signo == SIGALRM) {
187                 printf ("CRITICAL - Plugin timed out after %d seconds\n",
188                                                 timeout_interval);
189                 exit (STATE_CRITICAL);
190         }
193 int
194 is_numeric (char *number)
196         char tmp[1];
197         float x;
199         if (!number)
200                 return FALSE;
201         else if (sscanf (number, "%f%c", &x, tmp) == 1)
202                 return TRUE;
203         else
204                 return FALSE;
207 int
208 is_positive (char *number)
210         if (is_numeric (number) && atof (number) > 0.0)
211                 return TRUE;
212         else
213                 return FALSE;
216 int
217 is_negative (char *number)
219         if (is_numeric (number) && atof (number) < 0.0)
220                 return TRUE;
221         else
222                 return FALSE;
225 int
226 is_nonnegative (char *number)
228         if (is_numeric (number) && atof (number) >= 0.0)
229                 return TRUE;
230         else
231                 return FALSE;
234 int
235 is_percentage (char *number)
237         int x;
238         if (is_numeric (number) && (x = atof (number)) >= 0 && x <= 100)
239                 return TRUE;
240         else
241                 return FALSE;
244 int
245 is_integer (char *number)
247         long int n;
249         if (!number || (strspn (number, "-0123456789 ") != strlen (number)))
250                 return FALSE;
252         n = strtol (number, NULL, 10);
254         if (errno != ERANGE && n >= INT_MIN && n <= INT_MAX)
255                 return TRUE;
256         else
257                 return FALSE;
260 int
261 is_intpos (char *number)
263         if (is_integer (number) && atoi (number) > 0)
264                 return TRUE;
265         else
266                 return FALSE;
269 int
270 is_intneg (char *number)
272         if (is_integer (number) && atoi (number) < 0)
273                 return TRUE;
274         else
275                 return FALSE;
278 int
279 is_intnonneg (char *number)
281         if (is_integer (number) && atoi (number) >= 0)
282                 return TRUE;
283         else
284                 return FALSE;
287 int
288 is_intpercent (char *number)
290         int i;
291         if (is_integer (number) && (i = atoi (number)) >= 0 && i <= 100)
292                 return TRUE;
293         else
294                 return FALSE;
297 int
298 is_option (char *str)
300         if (!str)
301                 return FALSE;
302         else if (strspn (str, "-") == 1 || strspn (str, "-") == 2)
303                 return TRUE;
304         else
305                 return FALSE;
310 #ifdef NEED_GETTIMEOFDAY
311 int
312 gettimeofday (struct timeval *tv, struct timezone *tz)
314         tv->tv_usec = 0;
315         tv->tv_sec = (long) time ((time_t) 0);
317 #endif
321 double
322 delta_time (struct timeval tv)
324         struct timeval now;
326         gettimeofday (&now, NULL);
327         return ((double)(now.tv_sec - tv.tv_sec) + (double)(now.tv_usec - tv.tv_usec) / (double)1000000);
333 void
334 strip (char *buffer)
336         size_t x;
337         int i;
339         for (x = strlen (buffer); x >= 1; x--) {
340                 i = x - 1;
341                 if (buffer[i] == ' ' ||
342                                 buffer[i] == '\r' || buffer[i] == '\n' || buffer[i] == '\t')
343                         buffer[i] = '\0';
344                 else
345                         break;
346         }
347         return;
354 /******************************************************************************
355  *
356  * Copies one string to another. Any previously existing data in
357  * the destination string is lost.
358  *
359  * Example:
360  *
361  * char *str=NULL;
362  * str = strscpy("This is a line of text with no trailing newline");
363  *
364  *****************************************************************************/
366 char *
367 strscpy (char *dest, const char *src)
369         if (src == NULL)
370                 return NULL;
372         asprintf (&dest, "%s", src);
374         return dest;
381 /******************************************************************************
382  *
383  * Concatenates one string to the end of another
384  *
385  * Given a pointer destination string, which may or may not already
386  * hold some text, and a source string with additional text (possibly
387  * NULL or empty), returns a pointer to a string that is the first
388  * string with the second concatenated to it. Uses realloc to free 
389  * memory held by the dest argument if new storage space is required.
390  *
391  * Example:
392  *
393  * char *str=NULL;
394  * str = strscpy("This is a line of text with no trailing newline");
395  * str = strscat(str,"\n");
396  *
397  *****************************************************************************/
399 char *
400 strscat (char *dest, char *src)
403         if (dest == NULL)
404                 return src;
405         if (src != NULL)
406                 asprintf (&dest, "%s%s", dest, src);
408         return dest;
415 /******************************************************************************
416  *
417  * Returns a pointer to the next line of a multiline string buffer
418  *
419  * Given a pointer string, find the text following the next sequence
420  * of \r and \n characters. This has the effect of skipping blank
421  * lines as well
422  *
423  * Example:
424  *
425  * Given text as follows:
426  *
427  * ==============================
428  * This
429  * is
430  * a
431  * 
432  * multiline string buffer
433  * ==============================
434  *
435  * int i=0;
436  * char *str=NULL;
437  * char *ptr=NULL;
438  * str = strscpy(str,"This\nis\r\na\n\nmultiline string buffer\n");
439  * ptr = str;
440  * while (ptr) {
441  *   printf("%d %s",i++,firstword(ptr));
442  *   ptr = strnl(ptr);
443  * }
444  * 
445  * Produces the following:
446  *
447  * 1 This
448  * 2 is
449  * 3 a
450  * 4 multiline
451  *
452  * NOTE: The 'firstword()' function is conceptual only and does not
453  *       exist in this package.
454  *
455  * NOTE: Although the second 'ptr' variable is not strictly needed in
456  *       this example, it is good practice with these utilities. Once
457  *       the * pointer is advance in this manner, it may no longer be
458  *       handled with * realloc(). So at the end of the code fragment
459  *       above, * strscpy(str,"foo") work perfectly fine, but
460  *       strscpy(ptr,"foo") will * cause the the program to crash with
461  *       a segmentation fault.
462  *
463  *****************************************************************************/
465 char *
466 strnl (char *str)
468         size_t len;
469         if (str == NULL)
470                 return NULL;
471         str = strpbrk (str, "\r\n");
472         if (str == NULL)
473                 return NULL;
474         len = strspn (str, "\r\n");
475         if (str[len] == '\0')
476                 return NULL;
477         str += len;
478         if (strlen (str) == 0)
479                 return NULL;
480         return str;
487 /******************************************************************************
488  *
489  * Like strscpy, except only the portion of the source string up to
490  * the provided delimiter is copied.
491  *
492  * Example:
493  *
494  * str = strpcpy(str,"This is a line of text with no trailing newline","x");
495  * printf("%s\n",str);
496  *
497  * Produces:
498  *
499  *This is a line of te
500  *
501  *****************************************************************************/
503 char *
504 strpcpy (char *dest, const char *src, const char *str)
506         size_t len;
508         if (src)
509                 len = strcspn (src, str);
510         else
511                 return NULL;
513         if (dest == NULL || strlen (dest) < len)
514                 dest = realloc (dest, len + 1);
515         if (dest == NULL)
516                 terminate (STATE_UNKNOWN, "failed realloc in strpcpy\n");
518         strncpy (dest, src, len);
519         dest[len] = '\0';
521         return dest;
528 /******************************************************************************
529  *
530  * Like strscat, except only the portion of the source string up to
531  * the provided delimiter is copied.
532  *
533  * str = strpcpy(str,"This is a line of text with no trailing newline","x");
534  * str = strpcat(str,"This is a line of text with no trailing newline","x");
535  * printf("%s\n",str);
536  * 
537  *This is a line of texThis is a line of tex
538  *
539  *****************************************************************************/
541 char *
542 strpcat (char *dest, const char *src, const char *str)
544         size_t len, l2;
546         if (dest)
547                 len = strlen (dest);
548         else
549                 len = 0;
551         if (src) {
552                 l2 = strcspn (src, str);
553         }
554         else {
555                 return dest;
556         }
558         dest = realloc (dest, len + l2 + 1);
559         if (dest == NULL)
560                 terminate (STATE_UNKNOWN, "failed malloc in strscat\n");
562         strncpy (dest + len, src, l2);
563         dest[len + l2] = '\0';
565         return dest;