summaryrefslogtreecommitdiffstats
path: root/plugins/utils.c
diff options
context:
space:
mode:
Diffstat (limited to 'plugins/utils.c')
-rw-r--r--plugins/utils.c610
1 files changed, 610 insertions, 0 deletions
diff --git a/plugins/utils.c b/plugins/utils.c
new file mode 100644
index 00000000..49e4d3d7
--- /dev/null
+++ b/plugins/utils.c
@@ -0,0 +1,610 @@
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 ****************************************************************************/
13
14#include "config.h"
15#include "common.h"
16#include "version.h"
17#include <stdarg.h>
18#include <limits.h>
19
20extern int timeout_interval;
21
22char *my_basename (char *);
23void support (void);
24char *clean_revstring (const char *);
25void print_revision (char *, const char *);
26void terminate (int, const char *fmt, ...);
27RETSIGTYPE timeout_alarm_handler (int);
28
29int is_host (char *);
30int is_dotted_quad (char *);
31int is_hostname (char *);
32
33int is_integer (char *);
34int is_intpos (char *);
35int is_intneg (char *);
36int is_intnonneg (char *);
37int is_intpercent (char *);
38
39int is_numeric (char *);
40int is_positive (char *);
41int is_negative (char *);
42int is_nonnegative (char *);
43int is_percentage (char *);
44
45int is_option (char *str);
46
47void strip (char *);
48char *strscpy (char *dest, const char *src);
49char *strscat (char *dest, const char *src);
50char *strnl (char *str);
51char *ssprintf (char *str, const char *fmt, ...);
52char *strpcpy (char *dest, const char *src, const char *str);
53char *strpcat (char *dest, const char *src, const char *str);
54
55#define LABELLEN 63
56#define STRLEN 64
57#define TXTBLK 128
58
59#define max(a,b) ((a)>(b))?(a):(b)
60
61char *
62my_basename (char *path)
63{
64 if (!strstr (path, "/"))
65 return path;
66 else
67 return 1 + strrchr (path, '/');
68}
69
70
71void
72support (void)
73{
74 printf
75 ("Send email to nagios-users@lists.sourceforge.net if you have questions\n"
76 "regarding use of this software. To submit patches or suggest improvements,\n"
77 "send email to nagiosplug-devel@lists.sourceforge.net\n");
78}
79
80
81char *
82clean_revstring (const char *revstring)
83{
84 char plugin_revision[STRLEN];
85 if (sscanf (revstring,"$Revision: %[0-9.]",plugin_revision) == 1)
86 return strscpy (NULL, plugin_revision);
87 else
88 return strscpy (NULL, "N/A");
89}
90
91void
92print_revision (char *command_name, const char *revision_string)
93{
94 char plugin_revision[STRLEN];
95
96 if (sscanf (revision_string, "$Revision: %[0-9.]", plugin_revision) != 1)
97 strncpy (plugin_revision, "N/A", STRLEN);
98 printf ("%s (nagios-plugins %s) %s\n",
99 my_basename (command_name), VERSION, plugin_revision);
100 printf
101 ("The nagios plugins come with ABSOLUTELY NO WARRANTY. You may redistribute\n"
102 "copies of the plugins under the terms of the GNU General Public License.\n"
103 "For more information about these matters, see the file named COPYING.\n");
104
105}
106
107
108void
109terminate (int result, const char *fmt, ...)
110{
111 va_list ap;
112 va_start (ap, fmt);
113 vprintf (fmt, ap);
114 va_end (ap);
115 exit (result);
116}
117
118void
119timeout_alarm_handler (int signo)
120{
121 if (signo == SIGALRM) {
122 printf ("CRITICAL - Plugin timed out after %d seconds\n",
123 timeout_interval);
124 exit (STATE_CRITICAL);
125 }
126}
127
128int
129is_host (char *address)
130{
131 if (is_dotted_quad (address) || is_hostname (address))
132 return (TRUE);
133 return (FALSE);
134}
135
136int
137is_dotted_quad (char *address)
138{
139 int o1, o2, o3, o4;
140 char c[1];
141
142 if (sscanf (address, "%d.%d.%d.%d%c", &o1, &o2, &o3, &o4, c) != 4)
143 return FALSE;
144 else if (o1 > 255 || o2 > 255 || o3 > 255 || o4 > 255)
145 return FALSE;
146 else if (o1 < 0 || o2 < 0 || o3 < 0 || o4 < 0)
147 return FALSE;
148 else
149 return TRUE;
150}
151
152/* from RFC-1035
153 *
154 * The labels must follow the rules for ARPANET host names. They must
155 * start with a letter, end with a letter or digit, and have as interior
156 * characters only letters, digits, and hyphen. There are also some
157 * restrictions on the length. Labels must be 63 characters or less. */
158
159int
160is_hostname (char *s1)
161{
162 if (strlen (s1) > 63)
163 return FALSE;
164 if (strcspn
165 (s1,
166 "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUWVXYZ0123456789-.") !=
167 0) return FALSE;
168 if (strspn (s1, "0123456789-.") == 1)
169 return FALSE;
170 while ((s1 = index (s1, '.'))) {
171 s1++;
172 if (strspn (s1, "0123456789-.") == 1) {
173 printf ("%s\n", s1);
174 return FALSE;
175 }
176 }
177 return TRUE;
178}
179
180int
181is_numeric (char *number)
182{
183 char tmp[1];
184 float x;
185 if (sscanf (number, "%f%c", &x, tmp) == 1)
186 return (TRUE);
187 return (FALSE);
188}
189
190int
191is_positive (char *number)
192{
193 if (is_numeric (number) && atof (number) > 0.0)
194 return (TRUE);
195 return (FALSE);
196}
197
198int
199is_negative (char *number)
200{
201 if (is_numeric (number) && atof (number) < 0.0)
202 return (TRUE);
203 return (FALSE);
204}
205
206int
207is_nonnegative (char *number)
208{
209 if (is_numeric (number) && atof (number) >= 0.0)
210 return (TRUE);
211 return (FALSE);
212}
213
214int
215is_percentage (char *number)
216{
217 int x;
218 if (is_numeric (number) && (x = atof (number)) >= 0 && x <= 100)
219 return (TRUE);
220 return (FALSE);
221}
222
223int
224is_integer (char *number)
225{
226 long int n;
227
228 if (strspn (number, "-0123456789 ") != strlen (number))
229 return (FALSE);
230
231 n = strtol (number, NULL, 10);
232 if (errno != ERANGE && n >= INT_MIN && n <= INT_MAX)
233 return (TRUE);
234 return (FALSE);
235}
236
237int
238is_intpos (char *number)
239{
240 if (is_integer (number) && atoi (number) > 0)
241 return (TRUE);
242 return (FALSE);
243}
244
245int
246is_intneg (char *number)
247{
248 if (is_integer (number) && atoi (number) < 0)
249 return (TRUE);
250 return (FALSE);
251}
252
253int
254is_intnonneg (char *number)
255{
256 if (is_integer (number) && atoi (number) >= 0)
257 return (TRUE);
258 return (FALSE);
259}
260
261int
262is_intpercent (char *number)
263{
264 int i;
265 if (is_integer (number) && (i = atoi (number)) >= 0 && i <= 100)
266 return (TRUE);
267 return (FALSE);
268}
269
270int
271is_option (char *str)
272{
273 if (strspn (str, "-") == 1 || strspn (str, "-") == 2)
274 return TRUE;
275 return FALSE;
276}
277
278
279
280
281
282void
283strip (char *buffer)
284{
285 size_t x;
286 int i;
287
288 for (x = strlen (buffer); x >= 1; x--) {
289 i = x - 1;
290 if (buffer[i] == ' ' ||
291 buffer[i] == '\r' || buffer[i] == '\n' || buffer[i] == '\t')
292 buffer[i] = '\0';
293 else
294 break;
295 }
296 return;
297}
298
299
300
301
302
303/******************************************************************************
304 *
305 * Copies one string to another
306 *
307 * Given a pointer destination string, which may or may not already
308 * hold some text, and a source string with additional text (possibly
309 * NULL or empty), returns a pointer to a a copy of the source
310 * string. Uses realloc to free memory held by the dest argument if
311 * new storage space is required, and any previously existing data in
312 * the destination string is lost.
313 *
314 * Example:
315 *
316 * char *str=NULL;
317 * str = strscpy("This is a line of text with no trailing newline");
318 *
319 *****************************************************************************/
320
321char *
322strscpy (char *dest, const char *src)
323{
324 size_t len;
325
326 if (src == NULL)
327 return dest;
328
329 len = strlen (src) + 1;
330 if (dest == NULL)
331 dest = malloc (len);
332 else if (strlen (dest) < len)
333 dest = realloc (dest, len);
334 if (dest == NULL)
335 terminate (STATE_UNKNOWN, "failed realloc in strscpy\n");
336
337 strncpy (dest, src, len);
338
339 return dest;
340}
341
342
343
344
345
346/******************************************************************************
347 *
348 * Concatenates one string to the end of another
349 *
350 * Given a pointer destination string, which may or may not already
351 * hold some text, and a source string with additional text (possibly
352 * NULL or empty), returns a pointer to a string that is the first
353 * string with the second concatenated to it. Uses realloc to free
354 * memory held by the dest argument if new storage space is required.
355 *
356 * Example:
357 *
358 * char *str=NULL;
359 * str = strscpy("This is a line of text with no trailing newline");
360 * str = strscat(str,"\n");
361 *
362 *****************************************************************************/
363
364char *
365strscat (char *dest, const char *src)
366{
367 size_t len, l2;
368
369 if (src)
370 l2 = strlen (src);
371 else
372 return dest;
373
374 if (dest)
375 len = strlen (dest);
376 else
377 len = 0;
378
379 dest = realloc (dest, len + l2 + 1);
380 if (dest == NULL)
381 terminate (STATE_UNKNOWN, "failed malloc in strscat\n");
382
383 strncpy (dest + len, src, l2);
384 dest[len + l2] = '\0';
385
386 return dest;
387}
388
389
390
391
392
393/******************************************************************************
394 *
395 * Returns a pointer to the next line of a multiline string buffer
396 *
397 * Given a pointer string, find the text following the next sequence
398 * of \r and \n characters. This has the effect of skipping blank
399 * lines as well
400 *
401 * Example:
402 *
403 * Given text as follows:
404 *
405 * ==============================
406 * This
407 * is
408 * a
409 *
410 * multiline string buffer
411 * ==============================
412 *
413 * int i=0;
414 * char *str=NULL;
415 * char *ptr=NULL;
416 * str = strscpy(str,"This\nis\r\na\n\nmultiline string buffer\n");
417 * ptr = str;
418 * while (ptr) {
419 * printf("%d %s",i++,firstword(ptr));
420 * ptr = strnl(ptr);
421 * }
422 *
423 * Produces the following:
424 *
425 * 1 This
426 * 2 is
427 * 3 a
428 * 4 multiline
429 *
430 * NOTE: The 'firstword()' function is conceptual only and does not
431 * exist in this package.
432 *
433 * NOTE: Although the second 'ptr' variable is not strictly needed in
434 * this example, it is good practice with these utilities. Once
435 * the * pointer is advance in this manner, it may no longer be
436 * handled with * realloc(). So at the end of the code fragment
437 * above, * strscpy(str,"foo") work perfectly fine, but
438 * strscpy(ptr,"foo") will * cause the the program to crash with
439 * a segmentation fault.
440 *
441 *****************************************************************************/
442
443char *
444strnl (char *str)
445{
446 size_t len;
447 if (str == NULL)
448 return NULL;
449 str = strpbrk (str, "\r\n");
450 if (str == NULL)
451 return NULL;
452 len = strspn (str, "\r\n");
453 if (str[len] == '\0')
454 return NULL;
455 str += len;
456 if (strlen (str) == 0)
457 return NULL;
458 return str;
459}
460
461
462
463
464
465/******************************************************************************
466 *
467 * Does a formatted print to a string variable
468 *
469 * Given a pointer destination string, which may or may not already
470 * hold some text, and a source string with additional text (possibly
471 * NULL or empty), returns a pointer to a string that cntains the
472 * results of the specified formatted print
473 *
474 * Example:
475 *
476 * char *str=NULL;
477 * str = ssprintf(str,"%d %s",1,"string");
478 *
479 *****************************************************************************/
480
481char *
482ssprintf (char *ptr, const char *fmt, ...)
483{
484 va_list ap;
485 int nchars;
486 size_t size;
487 char *str = NULL;
488
489 if (str == NULL) {
490 str = malloc (TXTBLK);
491 if (str == NULL)
492 terminate (STATE_UNKNOWN, "malloc failed in ssprintf");
493 size = TXTBLK;
494 }
495 else
496 size = max (strlen (str), TXTBLK);
497
498 va_start (ap, fmt);
499
500 while (1) {
501
502 nchars = vsnprintf (str, size, fmt, ap);
503
504 if (nchars > -1)
505 if (nchars < (int) size) {
506 va_end (ap);
507 str[nchars] = '\0';
508 if (ptr)
509 free (ptr);
510 return str;
511 }
512 else {
513 size = (size_t) (nchars + 1);
514 }
515
516 else
517 size *= 2;
518
519 str = realloc (str, size);
520
521 if (str == NULL)
522 terminate (STATE_UNKNOWN, "realloc failed in ssprintf");
523 }
524
525}
526
527
528
529
530
531/******************************************************************************
532 *
533 * Like strscpy, except only the portion of the source string up to
534 * the provided delimiter is copied.
535 *
536 * Example:
537 *
538 * str = strpcpy(str,"This is a line of text with no trailing newline","x");
539 * printf("%s\n",str);
540 *
541 * Produces:
542 *
543 *This is a line of te
544 *
545 *****************************************************************************/
546
547char *
548strpcpy (char *dest, const char *src, const char *str)
549{
550 size_t len;
551
552 if (src)
553 len = strcspn (src, str);
554 else
555 return NULL;
556
557 if (dest == NULL || strlen (dest) < len)
558 dest = realloc (dest, len + 1);
559 if (dest == NULL)
560 terminate (STATE_UNKNOWN, "failed realloc in strpcpy\n");
561
562 strncpy (dest, src, len);
563 dest[len] = '\0';
564
565 return dest;
566}
567
568
569
570
571
572/******************************************************************************
573 *
574 * Like strscat, except only the portion of the source string up to
575 * the provided delimiter is copied.
576 *
577 * str = strpcpy(str,"This is a line of text with no trailing newline","x");
578 * str = strpcat(str,"This is a line of text with no trailing newline","x");
579 * printf("%s\n",str);
580 *
581 *This is a line of texThis is a line of tex
582 *
583 *****************************************************************************/
584
585char *
586strpcat (char *dest, const char *src, const char *str)
587{
588 size_t len, l2;
589
590 if (dest)
591 len = strlen (dest);
592 else
593 len = 0;
594
595 if (src) {
596 l2 = strcspn (src, str);
597 }
598 else {
599 return dest;
600 }
601
602 dest = realloc (dest, len + l2 + 1);
603 if (dest == NULL)
604 terminate (STATE_UNKNOWN, "failed malloc in strscat\n");
605
606 strncpy (dest + len, src, l2);
607 dest[len + l2] = '\0';
608
609 return dest;
610}