1 /*****************************************************************************
2 *
3 * utils_base.c
4 *
5 * Library of useful functions for plugins
6 * These functions are tested with libtap. See tests/ directory
7 *
8 * Copyright (c) 2006 Nagios Plugin Development Team
9 * License: GPL
10 *
11 * $Revision$
12 * $Date$
13 ****************************************************************************/
15 #include <stdarg.h>
16 #include "common.h"
17 #include "utils_base.h"
19 void
20 die (int result, const char *fmt, ...)
21 {
22 va_list ap;
23 va_start (ap, fmt);
24 vprintf (fmt, ap);
25 va_end (ap);
26 exit (result);
27 }
29 void set_range_start (range *this, double value) {
30 this->start = value;
31 this->start_infinity = FALSE;
32 }
34 void set_range_end (range *this, double value) {
35 this->end = value;
36 this->end_infinity = FALSE;
37 }
39 range
40 *parse_range_string (char *str) {
41 range *temp_range;
42 double start;
43 double end;
44 char *end_str;
46 temp_range = (range *) malloc(sizeof(range));
48 /* Set defaults */
49 temp_range->start = 0;
50 temp_range->start_infinity = FALSE;
51 temp_range->end = 0;
52 temp_range->end_infinity = TRUE;
53 temp_range->alert_on = OUTSIDE;
55 if (str[0] == '@') {
56 temp_range->alert_on = INSIDE;
57 str++;
58 }
60 end_str = index(str, ':');
61 if (end_str != NULL) {
62 if (str[0] == '~') {
63 temp_range->start_infinity = TRUE;
64 } else {
65 start = strtod(str, NULL); /* Will stop at the ':' */
66 set_range_start(temp_range, start);
67 }
68 end_str++; /* Move past the ':' */
69 } else {
70 end_str = str;
71 }
72 end = strtod(end_str, NULL);
73 if (strcmp(end_str, "") != 0) {
74 set_range_end(temp_range, end);
75 }
77 if (temp_range->start_infinity == TRUE ||
78 temp_range->end_infinity == TRUE ||
79 temp_range->start <= temp_range->end) {
80 return temp_range;
81 }
82 free(temp_range);
83 return NULL;
84 }
86 /* returns 0 if okay, otherwise 1 */
87 int
88 _set_thresholds(thresholds **my_thresholds, char *warn_string, char *critical_string)
89 {
90 thresholds *temp_thresholds = NULL;
92 temp_thresholds = malloc(sizeof(temp_thresholds));
94 temp_thresholds->warning = NULL;
95 temp_thresholds->critical = NULL;
97 if (warn_string != NULL) {
98 if ((temp_thresholds->warning = parse_range_string(warn_string)) == NULL) {
99 return 1;
100 }
101 }
102 if (critical_string != NULL) {
103 if ((temp_thresholds->critical = parse_range_string(critical_string)) == NULL) {
104 return 1;
105 }
106 }
108 if (*my_thresholds > 0) { /* Not sure why, but sometimes could be -1 */
109 /* printf("Freeing here: %d\n", *my_thresholds); */
110 free(*my_thresholds);
111 }
112 *my_thresholds = temp_thresholds;
114 return 0;
115 }
117 void
118 set_thresholds(thresholds **my_thresholds, char *warn_string, char *critical_string)
119 {
120 if (_set_thresholds(my_thresholds, warn_string, critical_string) == 0) {
121 return;
122 } else {
123 die(STATE_UNKNOWN, _("Range format incorrect"));
124 }
125 }
127 void print_thresholds(const char *threshold_name, thresholds *my_threshold) {
128 printf("%s - ", threshold_name);
129 if (! my_threshold) {
130 printf("Threshold not set");
131 } else {
132 if (my_threshold->warning) {
133 printf("Warning: start=%g end=%g; ", my_threshold->warning->start, my_threshold->warning->end);
134 } else {
135 printf("Warning not set; ");
136 }
137 if (my_threshold->critical) {
138 printf("Critical: start=%g end=%g", my_threshold->critical->start, my_threshold->critical->end);
139 } else {
140 printf("Critical not set");
141 }
142 }
143 printf("\n");
144 }
146 /* Returns TRUE if alert should be raised based on the range */
147 int
148 check_range(double value, range *my_range)
149 {
150 int false = FALSE;
151 int true = TRUE;
153 if (my_range->alert_on == INSIDE) {
154 false = TRUE;
155 true = FALSE;
156 }
158 if (my_range->end_infinity == FALSE && my_range->start_infinity == FALSE) {
159 if ((my_range->start <= value) && (value <= my_range->end)) {
160 return false;
161 } else {
162 return true;
163 }
164 } else if (my_range->start_infinity == FALSE && my_range->end_infinity == TRUE) {
165 if (my_range->start <= value) {
166 return false;
167 } else {
168 return true;
169 }
170 } else if (my_range->start_infinity == TRUE && my_range->end_infinity == FALSE) {
171 if (value <= my_range->end) {
172 return false;
173 } else {
174 return true;
175 }
176 } else {
177 return false;
178 }
179 }
181 /* Returns status */
182 int
183 get_status(double value, thresholds *my_thresholds)
184 {
185 if (my_thresholds->critical != NULL) {
186 if (check_range(value, my_thresholds->critical) == TRUE) {
187 return STATE_CRITICAL;
188 }
189 }
190 if (my_thresholds->warning != NULL) {
191 if (check_range(value, my_thresholds->warning) == TRUE) {
192 return STATE_WARNING;
193 }
194 }
195 return STATE_OK;
196 }
198 char *np_escaped_string (const char *string) {
199 char *data;
200 int i, j=0;
201 data = strdup(string);
202 for (i=0; data[i]; i++) {
203 if (data[i] == '\\') {
204 switch(data[++i]) {
205 case 'n':
206 data[j++] = '\n';
207 break;
208 case 'r':
209 data[j++] = '\r';
210 break;
211 case 't':
212 data[j++] = '\t';
213 break;
214 case '\\':
215 data[j++] = '\\';
216 break;
217 default:
218 data[j++] = data[i];
219 }
220 } else {
221 data[j++] = data[i];
222 }
223 }
224 data[j] = '\0';
225 return data;
226 }