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 NP_RANGE_UNPARSEABLE;
100 }
101 }
102 if (critical_string != NULL) {
103 if ((temp_thresholds->critical = parse_range_string(critical_string)) == NULL) {
104 return NP_RANGE_UNPARSEABLE;
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 switch (_set_thresholds(my_thresholds, warn_string, critical_string)) {
121 case 0:
122 return;
123 case NP_RANGE_UNPARSEABLE:
124 die(STATE_UNKNOWN, _("Range format incorrect"));
125 case NP_WARN_WITHIN_CRIT:
126 die(STATE_UNKNOWN, _("Warning level is a subset of critical and will not be alerted"));
127 break;
128 }
129 }
131 void print_thresholds(const char *threshold_name, thresholds *my_threshold) {
132 printf("%s - ", threshold_name);
133 if (! my_threshold) {
134 printf("Threshold not set");
135 } else {
136 if (my_threshold->warning) {
137 printf("Warning: start=%g end=%g; ", my_threshold->warning->start, my_threshold->warning->end);
138 } else {
139 printf("Warning not set; ");
140 }
141 if (my_threshold->critical) {
142 printf("Critical: start=%g end=%g", my_threshold->critical->start, my_threshold->critical->end);
143 } else {
144 printf("Critical not set");
145 }
146 }
147 printf("\n");
148 }
150 /* Returns TRUE if alert should be raised based on the range */
151 int
152 check_range(double value, range *my_range)
153 {
154 int no = FALSE;
155 int yes = TRUE;
157 if (my_range->alert_on == INSIDE) {
158 no = TRUE;
159 yes = FALSE;
160 }
162 if (my_range->end_infinity == FALSE && my_range->start_infinity == FALSE) {
163 if ((my_range->start <= value) && (value <= my_range->end)) {
164 return no;
165 } else {
166 return yes;
167 }
168 } else if (my_range->start_infinity == FALSE && my_range->end_infinity == TRUE) {
169 if (my_range->start <= value) {
170 return no;
171 } else {
172 return yes;
173 }
174 } else if (my_range->start_infinity == TRUE && my_range->end_infinity == FALSE) {
175 if (value <= my_range->end) {
176 return no;
177 } else {
178 return yes;
179 }
180 } else {
181 return no;
182 }
183 }
185 /* Returns status */
186 int
187 get_status(double value, thresholds *my_thresholds)
188 {
189 if (my_thresholds->critical != NULL) {
190 if (check_range(value, my_thresholds->critical) == TRUE) {
191 return STATE_CRITICAL;
192 }
193 }
194 if (my_thresholds->warning != NULL) {
195 if (check_range(value, my_thresholds->warning) == TRUE) {
196 return STATE_WARNING;
197 }
198 }
199 return STATE_OK;
200 }
202 char *np_escaped_string (const char *string) {
203 char *data;
204 int i, j=0;
205 data = strdup(string);
206 for (i=0; data[i]; i++) {
207 if (data[i] == '\\') {
208 switch(data[++i]) {
209 case 'n':
210 data[j++] = '\n';
211 break;
212 case 'r':
213 data[j++] = '\r';
214 break;
215 case 't':
216 data[j++] = '\t';
217 break;
218 case '\\':
219 data[j++] = '\\';
220 break;
221 default:
222 data[j++] = data[i];
223 }
224 } else {
225 data[j++] = data[i];
226 }
227 }
228 data[j] = '\0';
229 return data;
230 }
232 int np_check_if_root(void) { return (geteuid() == 0); }
234 int np_warn_if_not_root(void) {
235 int status = np_check_if_root();
236 if(!status) {
237 printf(_("Warning: "));
238 printf(_("This plugin must be either run as root or setuid root.\n"));
239 printf(_("To run as root, you can use a tool like sudo.\n"));
240 printf(_("To set the setuid permissions, use the command:\n"));
241 /* XXX could we use something like progname? */
242 printf("\tchmod u+s yourpluginfile\n");
243 }
244 return status;
245 }