Code

standardize localization string
[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;
318 /******************************************************************************
319  *
320  * Copies one string to another. Any previously existing data in
321  * the destination string is lost.
322  *
323  * Example:
324  *
325  * char *str=NULL;
326  * str = strscpy("This is a line of text with no trailing newline");
327  *
328  *****************************************************************************/
330 char *
331 strscpy (char *dest, const char *src)
333         if (src == NULL)
334                 return NULL;
336         asprintf (&dest, "%s", src);
338         return dest;
343 /******************************************************************************
344  *
345  * Returns a pointer to the next line of a multiline string buffer
346  *
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
349  * lines as well
350  *
351  * Example:
352  *
353  * Given text as follows:
354  *
355  * ==============================
356  * This
357  * is
358  * a
359  * 
360  * multiline string buffer
361  * ==============================
362  *
363  * int i=0;
364  * char *str=NULL;
365  * char *ptr=NULL;
366  * str = strscpy(str,"This\nis\r\na\n\nmultiline string buffer\n");
367  * ptr = str;
368  * while (ptr) {
369  *   printf("%d %s",i++,firstword(ptr));
370  *   ptr = strnl(ptr);
371  * }
372  * 
373  * Produces the following:
374  *
375  * 1 This
376  * 2 is
377  * 3 a
378  * 4 multiline
379  *
380  * NOTE: The 'firstword()' function is conceptual only and does not
381  *       exist in this package.
382  *
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.
390  *
391  *****************************************************************************/
393 char *
394 strnl (char *str)
396         size_t len;
397         if (str == NULL)
398                 return NULL;
399         str = strpbrk (str, "\r\n");
400         if (str == NULL)
401                 return NULL;
402         len = strspn (str, "\r\n");
403         if (str[len] == '\0')
404                 return NULL;
405         str += len;
406         if (strlen (str) == 0)
407                 return NULL;
408         return str;
412 /******************************************************************************
413  *
414  * Like strscpy, except only the portion of the source string up to
415  * the provided delimiter is copied.
416  *
417  * Example:
418  *
419  * str = strpcpy(str,"This is a line of text with no trailing newline","x");
420  * printf("%s\n",str);
421  *
422  * Produces:
423  *
424  *This is a line of te
425  *
426  *****************************************************************************/
428 char *
429 strpcpy (char *dest, const char *src, const char *str)
431         size_t len;
433         if (src)
434                 len = strcspn (src, str);
435         else
436                 return NULL;
438         if (dest == NULL || strlen (dest) < len)
439                 dest = realloc (dest, len + 1);
440         if (dest == NULL)
441                 die (STATE_UNKNOWN, "failed realloc in strpcpy\n");
443         strncpy (dest, src, len);
444         dest[len] = '\0';
446         return dest;
451 /******************************************************************************
452  *
453  * Like strscat, except only the portion of the source string up to
454  * the provided delimiter is copied.
455  *
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);
459  * 
460  *This is a line of texThis is a line of tex
461  *
462  *****************************************************************************/
464 char *
465 strpcat (char *dest, const char *src, const char *str)
467         size_t len, l2;
469         if (dest)
470                 len = strlen (dest);
471         else
472                 len = 0;
474         if (src) {
475                 l2 = strcspn (src, str);
476         }
477         else {
478                 return dest;
479         }
481         dest = realloc (dest, len + l2 + 1);
482         if (dest == NULL)
483                 die (STATE_UNKNOWN, "failed malloc in strscat\n");
485         strncpy (dest + len, src, l2);
486         dest[len + l2] = '\0';
488         return dest;
492 /******************************************************************************
493  *
494  * Print perfdata in a standard format
495  *
496  ******************************************************************************/
498 char *perfdata (const char *label,
499  long int val,
500  const char *uom,
501  int warnp,
502  long int warn,
503  int critp,
504  long int crit,
505  int minp,
506  long int minv,
507  int maxp,
508  long int maxv)
510         char *data = NULL;
512         if (strpbrk (label, "'= "))
513                 asprintf (&data, "'%s'=%ld%s;", label, val, uom);
514         else
515                 asprintf (&data, "%s=%ld%s;", label, val, uom);
517         if (warnp)
518                 asprintf (&data, "%s%ld;", data, warn);
519         else
520                 asprintf (&data, "%s;", data);
522         if (critp)
523                 asprintf (&data, "%s%ld;", data, crit);
524         else
525                 asprintf (&data, "%s;", data);
527         if (minp)
528                 asprintf (&data, "%s%ld", data, minv);
530         if (maxp)
531                 asprintf (&data, "%s;%ld", data, maxv);
533         return data;
537 char *fperfdata (const char *label,
538  double val,
539  const char *uom,
540  int warnp,
541  double warn,
542  int critp,
543  double crit,
544  int minp,
545  double minv,
546  int maxp,
547  double maxv)
549         char *data = NULL;
551         if (strpbrk (label, "'= "))
552                 asprintf (&data, "'%s'=", label);
553         else
554                 asprintf (&data, "%s=", label);
556         asprintf (&data, "%s%f", data, val);
557         asprintf (&data, "%s%s;", data, uom);
559         if (warnp)
560                 asprintf (&data, "%s%f", data, warn);
562         asprintf (&data, "%s;", data);
564         if (critp)
565                 asprintf (&data, "%s%f", data, crit);
567         asprintf (&data, "%s;", data);
569         if (minp)
570                 asprintf (&data, "%s%f", data, minv);
572         if (maxp) {
573                 asprintf (&data, "%s;", data);
574                 asprintf (&data, "%s%f", data, maxv);
575         }
577         return data;