summaryrefslogtreecommitdiffstats
path: root/lib/utils_base.c
diff options
context:
space:
mode:
Diffstat (limited to 'lib/utils_base.c')
-rw-r--r--lib/utils_base.c451
1 files changed, 222 insertions, 229 deletions
diff --git a/lib/utils_base.c b/lib/utils_base.c
index f8592f4..90a4aaa 100644
--- a/lib/utils_base.c
+++ b/lib/utils_base.c
@@ -1,28 +1,28 @@
1/***************************************************************************** 1/*****************************************************************************
2* 2 *
3* utils_base.c 3 * utils_base.c
4* 4 *
5* License: GPL 5 * License: GPL
6* Copyright (c) 2006 Monitoring Plugins Development Team 6 * Copyright (c) 2006 - 2024 Monitoring Plugins Development Team
7* 7 *
8* Library of useful functions for plugins 8 * Library of useful functions for plugins
9* 9 *
10* 10 *
11* This program is free software: you can redistribute it and/or modify 11 * This program is free software: you can redistribute it and/or modify
12* it under the terms of the GNU General Public License as published by 12 * it under the terms of the GNU General Public License as published by
13* the Free Software Foundation, either version 3 of the License, or 13 * the Free Software Foundation, either version 3 of the License, or
14* (at your option) any later version. 14 * (at your option) any later version.
15* 15 *
16* This program is distributed in the hope that it will be useful, 16 * This program is distributed in the hope that it will be useful,
17* but WITHOUT ANY WARRANTY; without even the implied warranty of 17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19* GNU General Public License for more details. 19 * GNU General Public License for more details.
20* 20 *
21* You should have received a copy of the GNU General Public License 21 * You should have received a copy of the GNU General Public License
22* along with this program. If not, see <http://www.gnu.org/licenses/>. 22 * along with this program. If not, see <http://www.gnu.org/licenses/>.
23* 23 *
24* 24 *
25*****************************************************************************/ 25 *****************************************************************************/
26 26
27#include "../plugins/common.h" 27#include "../plugins/common.h"
28#include <stdarg.h> 28#include <stdarg.h>
@@ -33,43 +33,47 @@
33#include <unistd.h> 33#include <unistd.h>
34#include <sys/types.h> 34#include <sys/types.h>
35 35
36#define np_free(ptr) { if(ptr) { free(ptr); ptr = NULL; } } 36#define np_free(ptr) \
37 { \
38 if (ptr) { \
39 free(ptr); \
40 ptr = NULL; \
41 } \
42 }
37 43
38monitoring_plugin *this_monitoring_plugin=NULL; 44monitoring_plugin *this_monitoring_plugin = NULL;
39 45
40int timeout_state = STATE_CRITICAL; 46int timeout_state = STATE_CRITICAL;
41unsigned int timeout_interval = DEFAULT_SOCKET_TIMEOUT; 47unsigned int timeout_interval = DEFAULT_SOCKET_TIMEOUT;
42 48
43bool _np_state_read_file(FILE *); 49bool _np_state_read_file(FILE *);
44 50
45void np_init( char *plugin_name, int argc, char **argv ) { 51void np_init(char *plugin_name, int argc, char **argv) {
46 if (this_monitoring_plugin==NULL) { 52 if (this_monitoring_plugin == NULL) {
47 this_monitoring_plugin = calloc(1, sizeof(monitoring_plugin)); 53 this_monitoring_plugin = calloc(1, sizeof(monitoring_plugin));
48 if (this_monitoring_plugin==NULL) { 54 if (this_monitoring_plugin == NULL) {
49 die(STATE_UNKNOWN, _("Cannot allocate memory: %s"), 55 die(STATE_UNKNOWN, _("Cannot allocate memory: %s"), strerror(errno));
50 strerror(errno));
51 } 56 }
52 this_monitoring_plugin->plugin_name = strdup(plugin_name); 57 this_monitoring_plugin->plugin_name = strdup(plugin_name);
53 if (this_monitoring_plugin->plugin_name==NULL) 58 if (this_monitoring_plugin->plugin_name == NULL)
54 die(STATE_UNKNOWN, _("Cannot execute strdup: %s"), strerror(errno)); 59 die(STATE_UNKNOWN, _("Cannot execute strdup: %s"), strerror(errno));
55 this_monitoring_plugin->argc = argc; 60 this_monitoring_plugin->argc = argc;
56 this_monitoring_plugin->argv = argv; 61 this_monitoring_plugin->argv = argv;
57 } 62 }
58} 63}
59 64
60void np_set_args( int argc, char **argv ) { 65void np_set_args(int argc, char **argv) {
61 if (this_monitoring_plugin==NULL) 66 if (this_monitoring_plugin == NULL)
62 die(STATE_UNKNOWN, _("This requires np_init to be called")); 67 die(STATE_UNKNOWN, _("This requires np_init to be called"));
63 68
64 this_monitoring_plugin->argc = argc; 69 this_monitoring_plugin->argc = argc;
65 this_monitoring_plugin->argv = argv; 70 this_monitoring_plugin->argv = argv;
66} 71}
67 72
68
69void np_cleanup() { 73void np_cleanup() {
70 if (this_monitoring_plugin!=NULL) { 74 if (this_monitoring_plugin != NULL) {
71 if(this_monitoring_plugin->state!=NULL) { 75 if (this_monitoring_plugin->state != NULL) {
72 if(this_monitoring_plugin->state->state_data) { 76 if (this_monitoring_plugin->state->state_data) {
73 np_free(this_monitoring_plugin->state->state_data->data); 77 np_free(this_monitoring_plugin->state->state_data->data);
74 np_free(this_monitoring_plugin->state->state_data); 78 np_free(this_monitoring_plugin->state->state_data);
75 } 79 }
@@ -79,48 +83,43 @@ void np_cleanup() {
79 np_free(this_monitoring_plugin->plugin_name); 83 np_free(this_monitoring_plugin->plugin_name);
80 np_free(this_monitoring_plugin); 84 np_free(this_monitoring_plugin);
81 } 85 }
82 this_monitoring_plugin=NULL; 86 this_monitoring_plugin = NULL;
83} 87}
84 88
85/* Hidden function to get a pointer to this_monitoring_plugin for testing */ 89/* Hidden function to get a pointer to this_monitoring_plugin for testing */
86void _get_monitoring_plugin( monitoring_plugin **pointer ){ 90void _get_monitoring_plugin(monitoring_plugin **pointer) { *pointer = this_monitoring_plugin; }
87 *pointer = this_monitoring_plugin;
88}
89 91
90void 92void die(int result, const char *fmt, ...) {
91die (int result, const char *fmt, ...) 93 if (fmt != NULL) {
92{
93 if(fmt!=NULL) {
94 va_list ap; 94 va_list ap;
95 va_start (ap, fmt); 95 va_start(ap, fmt);
96 vprintf (fmt, ap); 96 vprintf(fmt, ap);
97 va_end (ap); 97 va_end(ap);
98 } 98 }
99 99
100 if(this_monitoring_plugin!=NULL) { 100 if (this_monitoring_plugin != NULL) {
101 np_cleanup(); 101 np_cleanup();
102 } 102 }
103 exit (result); 103 exit(result);
104} 104}
105 105
106void set_range_start (range *this, double value) { 106void set_range_start(range *this, double value) {
107 this->start = value; 107 this->start = value;
108 this->start_infinity = false; 108 this->start_infinity = false;
109} 109}
110 110
111void set_range_end (range *this, double value) { 111void set_range_end(range *this, double value) {
112 this->end = value; 112 this->end = value;
113 this->end_infinity = false; 113 this->end_infinity = false;
114} 114}
115 115
116range 116range *parse_range_string(char *str) {
117*parse_range_string (char *str) {
118 range *temp_range; 117 range *temp_range;
119 double start; 118 double start;
120 double end; 119 double end;
121 char *end_str; 120 char *end_str;
122 121
123 temp_range = (range *) calloc(1, sizeof(range)); 122 temp_range = (range *)calloc(1, sizeof(range));
124 123
125 /* Set defaults */ 124 /* Set defaults */
126 temp_range->start = 0; 125 temp_range->start = 0;
@@ -140,10 +139,10 @@ range
140 if (str[0] == '~') { 139 if (str[0] == '~') {
141 temp_range->start_infinity = true; 140 temp_range->start_infinity = true;
142 } else { 141 } else {
143 start = strtod(str, NULL); /* Will stop at the ':' */ 142 start = strtod(str, NULL); /* Will stop at the ':' */
144 set_range_start(temp_range, start); 143 set_range_start(temp_range, start);
145 } 144 }
146 end_str++; /* Move past the ':' */ 145 end_str++; /* Move past the ':' */
147 } else { 146 } else {
148 end_str = str; 147 end_str = str;
149 } 148 }
@@ -152,9 +151,7 @@ range
152 set_range_end(temp_range, end); 151 set_range_end(temp_range, end);
153 } 152 }
154 153
155 if (temp_range->start_infinity == true || 154 if (temp_range->start_infinity == true || temp_range->end_infinity == true || temp_range->start <= temp_range->end) {
156 temp_range->end_infinity == true ||
157 temp_range->start <= temp_range->end) {
158 return temp_range; 155 return temp_range;
159 } 156 }
160 free(temp_range); 157 free(temp_range);
@@ -162,14 +159,11 @@ range
162} 159}
163 160
164/* returns 0 if okay, otherwise 1 */ 161/* returns 0 if okay, otherwise 1 */
165int 162int _set_thresholds(thresholds **my_thresholds, char *warn_string, char *critical_string) {
166_set_thresholds(thresholds **my_thresholds, char *warn_string, char *critical_string)
167{
168 thresholds *temp_thresholds = NULL; 163 thresholds *temp_thresholds = NULL;
169 164
170 if ((temp_thresholds = calloc(1, sizeof(thresholds))) == NULL) 165 if ((temp_thresholds = calloc(1, sizeof(thresholds))) == NULL)
171 die(STATE_UNKNOWN, _("Cannot allocate memory: %s"), 166 die(STATE_UNKNOWN, _("Cannot allocate memory: %s"), strerror(errno));
172 strerror(errno));
173 167
174 temp_thresholds->warning = NULL; 168 temp_thresholds->warning = NULL;
175 temp_thresholds->critical = NULL; 169 temp_thresholds->critical = NULL;
@@ -190,9 +184,7 @@ _set_thresholds(thresholds **my_thresholds, char *warn_string, char *critical_st
190 return 0; 184 return 0;
191} 185}
192 186
193void 187void set_thresholds(thresholds **my_thresholds, char *warn_string, char *critical_string) {
194set_thresholds(thresholds **my_thresholds, char *warn_string, char *critical_string)
195{
196 switch (_set_thresholds(my_thresholds, warn_string, critical_string)) { 188 switch (_set_thresholds(my_thresholds, warn_string, critical_string)) {
197 case 0: 189 case 0:
198 return; 190 return;
@@ -206,7 +198,7 @@ set_thresholds(thresholds **my_thresholds, char *warn_string, char *critical_str
206 198
207void print_thresholds(const char *threshold_name, thresholds *my_threshold) { 199void print_thresholds(const char *threshold_name, thresholds *my_threshold) {
208 printf("%s - ", threshold_name); 200 printf("%s - ", threshold_name);
209 if (! my_threshold) { 201 if (!my_threshold) {
210 printf("Threshold not set"); 202 printf("Threshold not set");
211 } else { 203 } else {
212 if (my_threshold->warning) { 204 if (my_threshold->warning) {
@@ -224,8 +216,7 @@ void print_thresholds(const char *threshold_name, thresholds *my_threshold) {
224} 216}
225 217
226/* Returns true if alert should be raised based on the range */ 218/* Returns true if alert should be raised based on the range */
227bool check_range(double value, range *my_range) 219bool check_range(double value, range *my_range) {
228{
229 bool no = false; 220 bool no = false;
230 bool yes = true; 221 bool yes = true;
231 222
@@ -258,9 +249,7 @@ bool check_range(double value, range *my_range)
258} 249}
259 250
260/* Returns status */ 251/* Returns status */
261int 252int get_status(double value, thresholds *my_thresholds) {
262get_status(double value, thresholds *my_thresholds)
263{
264 if (my_thresholds->critical != NULL) { 253 if (my_thresholds->critical != NULL) {
265 if (check_range(value, my_thresholds->critical) == true) { 254 if (check_range(value, my_thresholds->critical) == true) {
266 return STATE_CRITICAL; 255 return STATE_CRITICAL;
@@ -274,27 +263,27 @@ get_status(double value, thresholds *my_thresholds)
274 return STATE_OK; 263 return STATE_OK;
275} 264}
276 265
277char *np_escaped_string (const char *string) { 266char *np_escaped_string(const char *string) {
278 char *data; 267 char *data;
279 int i, j=0; 268 int i, j = 0;
280 data = strdup(string); 269 data = strdup(string);
281 for (i=0; data[i]; i++) { 270 for (i = 0; data[i]; i++) {
282 if (data[i] == '\\') { 271 if (data[i] == '\\') {
283 switch(data[++i]) { 272 switch (data[++i]) {
284 case 'n': 273 case 'n':
285 data[j++] = '\n'; 274 data[j++] = '\n';
286 break; 275 break;
287 case 'r': 276 case 'r':
288 data[j++] = '\r'; 277 data[j++] = '\r';
289 break; 278 break;
290 case 't': 279 case 't':
291 data[j++] = '\t'; 280 data[j++] = '\t';
292 break; 281 break;
293 case '\\': 282 case '\\':
294 data[j++] = '\\'; 283 data[j++] = '\\';
295 break; 284 break;
296 default: 285 default:
297 data[j++] = data[i]; 286 data[j++] = data[i];
298 } 287 }
299 } else { 288 } else {
300 data[j++] = data[i]; 289 data[j++] = data[i];
@@ -313,33 +302,38 @@ int np_check_if_root(void) { return (geteuid() == 0); }
313 * data strings. 302 * data strings.
314 */ 303 */
315char *np_extract_value(const char *varlist, const char *name, char sep) { 304char *np_extract_value(const char *varlist, const char *name, char sep) {
316 char *tmp=NULL, *value=NULL; 305 char *tmp = NULL, *value = NULL;
317 int i; 306 int i;
318 307
319 while (1) { 308 while (1) {
320 /* Strip any leading space */ 309 /* Strip any leading space */
321 for (; isspace(varlist[0]); varlist++); 310 for (; isspace(varlist[0]); varlist++)
311 ;
322 312
323 if (strncmp(name, varlist, strlen(name)) == 0) { 313 if (strncmp(name, varlist, strlen(name)) == 0) {
324 varlist += strlen(name); 314 varlist += strlen(name);
325 /* strip trailing spaces */ 315 /* strip trailing spaces */
326 for (; isspace(varlist[0]); varlist++); 316 for (; isspace(varlist[0]); varlist++)
317 ;
327 318
328 if (varlist[0] == '=') { 319 if (varlist[0] == '=') {
329 /* We matched the key, go past the = sign */ 320 /* We matched the key, go past the = sign */
330 varlist++; 321 varlist++;
331 /* strip leading spaces */ 322 /* strip leading spaces */
332 for (; isspace(varlist[0]); varlist++); 323 for (; isspace(varlist[0]); varlist++)
324 ;
333 325
334 if ((tmp = index(varlist, sep))) { 326 if ((tmp = index(varlist, sep))) {
335 /* Value is delimited by a comma */ 327 /* Value is delimited by a comma */
336 if (tmp-varlist == 0) continue; 328 if (tmp - varlist == 0)
337 value = (char *)calloc(1, tmp-varlist+1); 329 continue;
338 strncpy(value, varlist, tmp-varlist); 330 value = (char *)calloc(1, tmp - varlist + 1);
339 value[tmp-varlist] = '\0'; 331 strncpy(value, varlist, tmp - varlist);
332 value[tmp - varlist] = '\0';
340 } else { 333 } else {
341 /* Value is delimited by a \0 */ 334 /* Value is delimited by a \0 */
342 if (strlen(varlist) == 0) continue; 335 if (strlen(varlist) == 0)
336 continue;
343 value = (char *)calloc(1, strlen(varlist) + 1); 337 value = (char *)calloc(1, strlen(varlist) + 1);
344 strncpy(value, varlist, strlen(varlist)); 338 strncpy(value, varlist, strlen(varlist));
345 value[strlen(varlist)] = '\0'; 339 value[strlen(varlist)] = '\0';
@@ -357,14 +351,14 @@ char *np_extract_value(const char *varlist, const char *name, char sep) {
357 } 351 }
358 352
359 /* Clean-up trailing spaces/newlines */ 353 /* Clean-up trailing spaces/newlines */
360 if (value) for (i=strlen(value)-1; isspace(value[i]); i--) value[i] = '\0'; 354 if (value)
355 for (i = strlen(value) - 1; isspace(value[i]); i--)
356 value[i] = '\0';
361 357
362 return value; 358 return value;
363} 359}
364 360
365const char * 361const char *state_text(int result) {
366state_text (int result)
367{
368 switch (result) { 362 switch (result) {
369 case STATE_OK: 363 case STATE_OK:
370 return "OK"; 364 return "OK";
@@ -383,14 +377,14 @@ state_text (int result)
383 * Read a string representing a state (ok, warning... or numeric: 0, 1) and 377 * Read a string representing a state (ok, warning... or numeric: 0, 1) and
384 * return the corresponding STATE_ value or ERROR) 378 * return the corresponding STATE_ value or ERROR)
385 */ 379 */
386int mp_translate_state (char *state_text) { 380int mp_translate_state(char *state_text) {
387 if (!strcasecmp(state_text,"OK") || !strcmp(state_text,"0")) 381 if (!strcasecmp(state_text, "OK") || !strcmp(state_text, "0"))
388 return STATE_OK; 382 return STATE_OK;
389 if (!strcasecmp(state_text,"WARNING") || !strcmp(state_text,"1")) 383 if (!strcasecmp(state_text, "WARNING") || !strcmp(state_text, "1"))
390 return STATE_WARNING; 384 return STATE_WARNING;
391 if (!strcasecmp(state_text,"CRITICAL") || !strcmp(state_text,"2")) 385 if (!strcasecmp(state_text, "CRITICAL") || !strcmp(state_text, "2"))
392 return STATE_CRITICAL; 386 return STATE_CRITICAL;
393 if (!strcasecmp(state_text,"UNKNOWN") || !strcmp(state_text,"3")) 387 if (!strcasecmp(state_text, "UNKNOWN") || !strcmp(state_text, "3"))
394 return STATE_UNKNOWN; 388 return STATE_UNKNOWN;
395 return ERROR; 389 return ERROR;
396} 390}
@@ -404,7 +398,7 @@ char *_np_state_generate_key() {
404 int i; 398 int i;
405 char **argv = this_monitoring_plugin->argv; 399 char **argv = this_monitoring_plugin->argv;
406 char keyname[41]; 400 char keyname[41];
407 char *p=NULL; 401 char *p = NULL;
408 402
409 unsigned char result[256]; 403 unsigned char result[256];
410 404
@@ -418,7 +412,7 @@ char *_np_state_generate_key() {
418 412
419 EVP_DigestInit(ctx, EVP_sha256()); 413 EVP_DigestInit(ctx, EVP_sha256());
420 414
421 for(i=0; i<this_monitoring_plugin->argc; i++) { 415 for (i = 0; i < this_monitoring_plugin->argc; i++) {
422 EVP_DigestUpdate(ctx, argv[i], strlen(argv[i])); 416 EVP_DigestUpdate(ctx, argv[i], strlen(argv[i]));
423 } 417 }
424 418
@@ -427,28 +421,28 @@ char *_np_state_generate_key() {
427 421
428 struct sha256_ctx ctx; 422 struct sha256_ctx ctx;
429 423
430 for(i=0; i<this_monitoring_plugin->argc; i++) { 424 for (i = 0; i < this_monitoring_plugin->argc; i++) {
431 sha256_process_bytes(argv[i], strlen(argv[i]), &ctx); 425 sha256_process_bytes(argv[i], strlen(argv[i]), &ctx);
432 } 426 }
433 427
434 sha256_finish_ctx(&ctx, result); 428 sha256_finish_ctx(&ctx, result);
435#endif // FOUNDOPENSSL 429#endif // FOUNDOPENSSL
436 430
437 for (i=0; i<20; ++i) { 431 for (i = 0; i < 20; ++i) {
438 sprintf(&keyname[2*i], "%02x", result[i]); 432 sprintf(&keyname[2 * i], "%02x", result[i]);
439 } 433 }
440 434
441 keyname[40]='\0'; 435 keyname[40] = '\0';
442 436
443 p = strdup(keyname); 437 p = strdup(keyname);
444 if(p==NULL) { 438 if (p == NULL) {
445 die(STATE_UNKNOWN, _("Cannot execute strdup: %s"), strerror(errno)); 439 die(STATE_UNKNOWN, _("Cannot execute strdup: %s"), strerror(errno));
446 } 440 }
447 return p; 441 return p;
448} 442}
449 443
450void _cleanup_state_data() { 444void _cleanup_state_data() {
451 if (this_monitoring_plugin->state->state_data!=NULL) { 445 if (this_monitoring_plugin->state->state_data != NULL) {
452 np_free(this_monitoring_plugin->state->state_data->data); 446 np_free(this_monitoring_plugin->state->state_data->data);
453 np_free(this_monitoring_plugin->state->state_data); 447 np_free(this_monitoring_plugin->state->state_data);
454 } 448 }
@@ -459,18 +453,18 @@ void _cleanup_state_data() {
459 * envvar NAGIOS_PLUGIN_STATE_DIRECTORY 453 * envvar NAGIOS_PLUGIN_STATE_DIRECTORY
460 * statically compiled shared state directory 454 * statically compiled shared state directory
461 */ 455 */
462char* _np_state_calculate_location_prefix(){ 456char *_np_state_calculate_location_prefix() {
463 char *env_dir; 457 char *env_dir;
464 458
465 /* Do not allow passing MP_STATE_PATH in setuid plugins 459 /* Do not allow passing MP_STATE_PATH in setuid plugins
466 * for security reasons */ 460 * for security reasons */
467 if (!mp_suid()) { 461 if (!mp_suid()) {
468 env_dir = getenv("MP_STATE_PATH"); 462 env_dir = getenv("MP_STATE_PATH");
469 if(env_dir && env_dir[0] != '\0') 463 if (env_dir && env_dir[0] != '\0')
470 return env_dir; 464 return env_dir;
471 /* This is the former ENV, for backward-compatibility */ 465 /* This is the former ENV, for backward-compatibility */
472 env_dir = getenv("NAGIOS_PLUGIN_STATE_DIRECTORY"); 466 env_dir = getenv("NAGIOS_PLUGIN_STATE_DIRECTORY");
473 if(env_dir && env_dir[0] != '\0') 467 if (env_dir && env_dir[0] != '\0')
474 return env_dir; 468 return env_dir;
475 } 469 }
476 470
@@ -486,46 +480,43 @@ void np_enable_state(char *keyname, int expected_data_version) {
486 state_key *this_state = NULL; 480 state_key *this_state = NULL;
487 char *temp_filename = NULL; 481 char *temp_filename = NULL;
488 char *temp_keyname = NULL; 482 char *temp_keyname = NULL;
489 char *p=NULL; 483 char *p = NULL;
490 int ret; 484 int ret;
491 485
492 if(this_monitoring_plugin==NULL) 486 if (this_monitoring_plugin == NULL)
493 die(STATE_UNKNOWN, _("This requires np_init to be called")); 487 die(STATE_UNKNOWN, _("This requires np_init to be called"));
494 488
495 this_state = (state_key *) calloc(1, sizeof(state_key)); 489 this_state = (state_key *)calloc(1, sizeof(state_key));
496 if(this_state==NULL) 490 if (this_state == NULL)
497 die(STATE_UNKNOWN, _("Cannot allocate memory: %s"), 491 die(STATE_UNKNOWN, _("Cannot allocate memory: %s"), strerror(errno));
498 strerror(errno));
499 492
500 if(keyname==NULL) { 493 if (keyname == NULL) {
501 temp_keyname = _np_state_generate_key(); 494 temp_keyname = _np_state_generate_key();
502 } else { 495 } else {
503 temp_keyname = strdup(keyname); 496 temp_keyname = strdup(keyname);
504 if(temp_keyname==NULL) 497 if (temp_keyname == NULL)
505 die(STATE_UNKNOWN, _("Cannot execute strdup: %s"), strerror(errno)); 498 die(STATE_UNKNOWN, _("Cannot execute strdup: %s"), strerror(errno));
506 } 499 }
507 /* Die if invalid characters used for keyname */ 500 /* Die if invalid characters used for keyname */
508 p = temp_keyname; 501 p = temp_keyname;
509 while(*p!='\0') { 502 while (*p != '\0') {
510 if(! (isalnum(*p) || *p == '_')) { 503 if (!(isalnum(*p) || *p == '_')) {
511 die(STATE_UNKNOWN, _("Invalid character for keyname - only alphanumerics or '_'")); 504 die(STATE_UNKNOWN, _("Invalid character for keyname - only alphanumerics or '_'"));
512 } 505 }
513 p++; 506 p++;
514 } 507 }
515 this_state->name=temp_keyname; 508 this_state->name = temp_keyname;
516 this_state->plugin_name=this_monitoring_plugin->plugin_name; 509 this_state->plugin_name = this_monitoring_plugin->plugin_name;
517 this_state->data_version=expected_data_version; 510 this_state->data_version = expected_data_version;
518 this_state->state_data=NULL; 511 this_state->state_data = NULL;
519 512
520 /* Calculate filename */ 513 /* Calculate filename */
521 ret = asprintf(&temp_filename, "%s/%lu/%s/%s", 514 ret = asprintf(&temp_filename, "%s/%lu/%s/%s", _np_state_calculate_location_prefix(), (unsigned long)geteuid(),
522 _np_state_calculate_location_prefix(), (unsigned long)geteuid(), 515 this_monitoring_plugin->plugin_name, this_state->name);
523 this_monitoring_plugin->plugin_name, this_state->name);
524 if (ret < 0) 516 if (ret < 0)
525 die(STATE_UNKNOWN, _("Cannot allocate memory: %s"), 517 die(STATE_UNKNOWN, _("Cannot allocate memory: %s"), strerror(errno));
526 strerror(errno));
527 518
528 this_state->_filename=temp_filename; 519 this_state->_filename = temp_filename;
529 520
530 this_monitoring_plugin->state = this_state; 521 this_monitoring_plugin->state = this_state;
531} 522}
@@ -538,23 +529,22 @@ void np_enable_state(char *keyname, int expected_data_version) {
538 * if exceptional error. 529 * if exceptional error.
539 */ 530 */
540state_data *np_state_read() { 531state_data *np_state_read() {
541 state_data *this_state_data=NULL; 532 state_data *this_state_data = NULL;
542 FILE *statefile; 533 FILE *statefile;
543 bool rc = false; 534 bool rc = false;
544 535
545 if(this_monitoring_plugin==NULL) 536 if (this_monitoring_plugin == NULL)
546 die(STATE_UNKNOWN, _("This requires np_init to be called")); 537 die(STATE_UNKNOWN, _("This requires np_init to be called"));
547 538
548 /* Open file. If this fails, no previous state found */ 539 /* Open file. If this fails, no previous state found */
549 statefile = fopen( this_monitoring_plugin->state->_filename, "r" ); 540 statefile = fopen(this_monitoring_plugin->state->_filename, "r");
550 if(statefile!=NULL) { 541 if (statefile != NULL) {
551 542
552 this_state_data = (state_data *) calloc(1, sizeof(state_data)); 543 this_state_data = (state_data *)calloc(1, sizeof(state_data));
553 if(this_state_data==NULL) 544 if (this_state_data == NULL)
554 die(STATE_UNKNOWN, _("Cannot allocate memory: %s"), 545 die(STATE_UNKNOWN, _("Cannot allocate memory: %s"), strerror(errno));
555 strerror(errno));
556 546
557 this_state_data->data=NULL; 547 this_state_data->data = NULL;
558 this_monitoring_plugin->state->state_data = this_state_data; 548 this_monitoring_plugin->state->state_data = this_state_data;
559 549
560 rc = _np_state_read_file(statefile); 550 rc = _np_state_read_file(statefile);
@@ -562,7 +552,7 @@ state_data *np_state_read() {
562 fclose(statefile); 552 fclose(statefile);
563 } 553 }
564 554
565 if(!rc) { 555 if (!rc) {
566 _cleanup_state_data(); 556 _cleanup_state_data();
567 } 557 }
568 558
@@ -577,60 +567,65 @@ bool _np_state_read_file(FILE *f) {
577 size_t pos; 567 size_t pos;
578 char *line; 568 char *line;
579 int i; 569 int i;
580 int failure=0; 570 int failure = 0;
581 time_t current_time, data_time; 571 time_t current_time, data_time;
582 enum { STATE_FILE_VERSION, STATE_DATA_VERSION, STATE_DATA_TIME, STATE_DATA_TEXT, STATE_DATA_END } expected=STATE_FILE_VERSION; 572 enum {
573 STATE_FILE_VERSION,
574 STATE_DATA_VERSION,
575 STATE_DATA_TIME,
576 STATE_DATA_TEXT,
577 STATE_DATA_END
578 } expected = STATE_FILE_VERSION;
583 579
584 time(&current_time); 580 time(&current_time);
585 581
586 /* Note: This introduces a limit of 1024 bytes in the string data */ 582 /* Note: This introduces a limit of 1024 bytes in the string data */
587 line = (char *) calloc(1, 1024); 583 line = (char *)calloc(1, 1024);
588 if(line==NULL) 584 if (line == NULL)
589 die(STATE_UNKNOWN, _("Cannot allocate memory: %s"), 585 die(STATE_UNKNOWN, _("Cannot allocate memory: %s"), strerror(errno));
590 strerror(errno)); 586
591 587 while (!failure && (fgets(line, 1024, f)) != NULL) {
592 while(!failure && (fgets(line,1024,f))!=NULL){ 588 pos = strlen(line);
593 pos=strlen(line); 589 if (line[pos - 1] == '\n') {
594 if(line[pos-1]=='\n') { 590 line[pos - 1] = '\0';
595 line[pos-1]='\0';
596 } 591 }
597 592
598 if(line[0] == '#') continue; 593 if (line[0] == '#')
594 continue;
599 595
600 switch(expected) { 596 switch (expected) {
601 case STATE_FILE_VERSION: 597 case STATE_FILE_VERSION:
602 i=atoi(line); 598 i = atoi(line);
603 if(i!=NP_STATE_FORMAT_VERSION) 599 if (i != NP_STATE_FORMAT_VERSION)
604 failure++; 600 failure++;
605 else 601 else
606 expected=STATE_DATA_VERSION; 602 expected = STATE_DATA_VERSION;
607 break; 603 break;
608 case STATE_DATA_VERSION: 604 case STATE_DATA_VERSION:
609 i=atoi(line); 605 i = atoi(line);
610 if(i != this_monitoring_plugin->state->data_version) 606 if (i != this_monitoring_plugin->state->data_version)
611 failure++; 607 failure++;
612 else 608 else
613 expected=STATE_DATA_TIME; 609 expected = STATE_DATA_TIME;
614 break; 610 break;
615 case STATE_DATA_TIME: 611 case STATE_DATA_TIME:
616 /* If time > now, error */ 612 /* If time > now, error */
617 data_time=strtoul(line,NULL,10); 613 data_time = strtoul(line, NULL, 10);
618 if(data_time > current_time) 614 if (data_time > current_time)
619 failure++; 615 failure++;
620 else { 616 else {
621 this_monitoring_plugin->state->state_data->time = data_time; 617 this_monitoring_plugin->state->state_data->time = data_time;
622 expected=STATE_DATA_TEXT; 618 expected = STATE_DATA_TEXT;
623 } 619 }
624 break; 620 break;
625 case STATE_DATA_TEXT: 621 case STATE_DATA_TEXT:
626 this_monitoring_plugin->state->state_data->data = strdup(line); 622 this_monitoring_plugin->state->state_data->data = strdup(line);
627 if(this_monitoring_plugin->state->state_data->data==NULL) 623 if (this_monitoring_plugin->state->state_data->data == NULL)
628 die(STATE_UNKNOWN, _("Cannot execute strdup: %s"), strerror(errno)); 624 die(STATE_UNKNOWN, _("Cannot execute strdup: %s"), strerror(errno));
629 expected=STATE_DATA_END; 625 expected = STATE_DATA_END;
630 status=true; 626 status = true;
631 break; 627 break;
632 case STATE_DATA_END: 628 case STATE_DATA_END:;
633 ;
634 } 629 }
635 } 630 }
636 631
@@ -647,77 +642,75 @@ bool _np_state_read_file(FILE *f) {
647 */ 642 */
648void np_state_write_string(time_t data_time, char *data_string) { 643void np_state_write_string(time_t data_time, char *data_string) {
649 FILE *fp; 644 FILE *fp;
650 char *temp_file=NULL; 645 char *temp_file = NULL;
651 int fd=0, result=0; 646 int fd = 0, result = 0;
652 time_t current_time; 647 time_t current_time;
653 char *directories=NULL; 648 char *directories = NULL;
654 char *p=NULL; 649 char *p = NULL;
655 650
656 if(data_time==0) 651 if (data_time == 0)
657 time(&current_time); 652 time(&current_time);
658 else 653 else
659 current_time=data_time; 654 current_time = data_time;
660 655
661 /* If file doesn't currently exist, create directories */ 656 /* If file doesn't currently exist, create directories */
662 if(access(this_monitoring_plugin->state->_filename,F_OK)!=0) { 657 if (access(this_monitoring_plugin->state->_filename, F_OK) != 0) {
663 result = asprintf(&directories, "%s", this_monitoring_plugin->state->_filename); 658 result = asprintf(&directories, "%s", this_monitoring_plugin->state->_filename);
664 if(result < 0) 659 if (result < 0)
665 die(STATE_UNKNOWN, _("Cannot allocate memory: %s"), 660 die(STATE_UNKNOWN, _("Cannot allocate memory: %s"), strerror(errno));
666 strerror(errno)); 661
667 662 for (p = directories + 1; *p; p++) {
668 for(p=directories+1; *p; p++) { 663 if (*p == '/') {
669 if(*p=='/') { 664 *p = '\0';
670 *p='\0'; 665 if ((access(directories, F_OK) != 0) && (mkdir(directories, S_IRWXU) != 0)) {
671 if((access(directories,F_OK)!=0) && (mkdir(directories, S_IRWXU)!=0)) {
672 /* Can't free this! Otherwise error message is wrong! */ 666 /* Can't free this! Otherwise error message is wrong! */
673 /* np_free(directories); */ 667 /* np_free(directories); */
674 die(STATE_UNKNOWN, _("Cannot create directory: %s"), directories); 668 die(STATE_UNKNOWN, _("Cannot create directory: %s"), directories);
675 } 669 }
676 *p='/'; 670 *p = '/';
677 } 671 }
678 } 672 }
679 np_free(directories); 673 np_free(directories);
680 } 674 }
681 675
682 result = asprintf(&temp_file,"%s.XXXXXX",this_monitoring_plugin->state->_filename); 676 result = asprintf(&temp_file, "%s.XXXXXX", this_monitoring_plugin->state->_filename);
683 if(result < 0) 677 if (result < 0)
684 die(STATE_UNKNOWN, _("Cannot allocate memory: %s"), 678 die(STATE_UNKNOWN, _("Cannot allocate memory: %s"), strerror(errno));
685 strerror(errno));
686 679
687 if((fd=mkstemp(temp_file))==-1) { 680 if ((fd = mkstemp(temp_file)) == -1) {
688 np_free(temp_file); 681 np_free(temp_file);
689 die(STATE_UNKNOWN, _("Cannot create temporary filename")); 682 die(STATE_UNKNOWN, _("Cannot create temporary filename"));
690 } 683 }
691 684
692 fp=(FILE *)fdopen(fd,"w"); 685 fp = (FILE *)fdopen(fd, "w");
693 if(fp==NULL) { 686 if (fp == NULL) {
694 close(fd); 687 close(fd);
695 unlink(temp_file); 688 unlink(temp_file);
696 np_free(temp_file); 689 np_free(temp_file);
697 die(STATE_UNKNOWN, _("Unable to open temporary state file")); 690 die(STATE_UNKNOWN, _("Unable to open temporary state file"));
698 } 691 }
699 692
700 fprintf(fp,"# NP State file\n"); 693 fprintf(fp, "# NP State file\n");
701 fprintf(fp,"%d\n",NP_STATE_FORMAT_VERSION); 694 fprintf(fp, "%d\n", NP_STATE_FORMAT_VERSION);
702 fprintf(fp,"%d\n",this_monitoring_plugin->state->data_version); 695 fprintf(fp, "%d\n", this_monitoring_plugin->state->data_version);
703 fprintf(fp,"%lu\n",current_time); 696 fprintf(fp, "%lu\n", current_time);
704 fprintf(fp,"%s\n",data_string); 697 fprintf(fp, "%s\n", data_string);
705 698
706 fchmod(fd, S_IRUSR | S_IWUSR | S_IRGRP); 699 fchmod(fd, S_IRUSR | S_IWUSR | S_IRGRP);
707 700
708 fflush(fp); 701 fflush(fp);
709 702
710 result=fclose(fp); 703 result = fclose(fp);
711 704
712 fsync(fd); 705 fsync(fd);
713 706
714 if(result!=0) { 707 if (result != 0) {
715 unlink(temp_file); 708 unlink(temp_file);
716 np_free(temp_file); 709 np_free(temp_file);
717 die(STATE_UNKNOWN, _("Error writing temp file")); 710 die(STATE_UNKNOWN, _("Error writing temp file"));
718 } 711 }
719 712
720 if(rename(temp_file, this_monitoring_plugin->state->_filename)!=0) { 713 if (rename(temp_file, this_monitoring_plugin->state->_filename) != 0) {
721 unlink(temp_file); 714 unlink(temp_file);
722 np_free(temp_file); 715 np_free(temp_file);
723 die(STATE_UNKNOWN, _("Cannot rename state temp file")); 716 die(STATE_UNKNOWN, _("Cannot rename state temp file"));