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.c167
1 files changed, 118 insertions, 49 deletions
diff --git a/lib/utils_base.c b/lib/utils_base.c
index 90a4aaa5..ff9540c7 100644
--- a/lib/utils_base.c
+++ b/lib/utils_base.c
@@ -55,22 +55,24 @@ void np_init(char *plugin_name, int argc, char **argv) {
55 die(STATE_UNKNOWN, _("Cannot allocate memory: %s"), strerror(errno)); 55 die(STATE_UNKNOWN, _("Cannot allocate memory: %s"), strerror(errno));
56 } 56 }
57 this_monitoring_plugin->plugin_name = strdup(plugin_name); 57 this_monitoring_plugin->plugin_name = strdup(plugin_name);
58 if (this_monitoring_plugin->plugin_name == NULL) 58 if (this_monitoring_plugin->plugin_name == NULL) {
59 die(STATE_UNKNOWN, _("Cannot execute strdup: %s"), strerror(errno)); 59 die(STATE_UNKNOWN, _("Cannot execute strdup: %s"), strerror(errno));
60 }
60 this_monitoring_plugin->argc = argc; 61 this_monitoring_plugin->argc = argc;
61 this_monitoring_plugin->argv = argv; 62 this_monitoring_plugin->argv = argv;
62 } 63 }
63} 64}
64 65
65void np_set_args(int argc, char **argv) { 66void np_set_args(int argc, char **argv) {
66 if (this_monitoring_plugin == NULL) 67 if (this_monitoring_plugin == NULL) {
67 die(STATE_UNKNOWN, _("This requires np_init to be called")); 68 die(STATE_UNKNOWN, _("This requires np_init to be called"));
69 }
68 70
69 this_monitoring_plugin->argc = argc; 71 this_monitoring_plugin->argc = argc;
70 this_monitoring_plugin->argv = argv; 72 this_monitoring_plugin->argv = argv;
71} 73}
72 74
73void np_cleanup() { 75void np_cleanup(void) {
74 if (this_monitoring_plugin != NULL) { 76 if (this_monitoring_plugin != NULL) {
75 if (this_monitoring_plugin->state != NULL) { 77 if (this_monitoring_plugin->state != NULL) {
76 if (this_monitoring_plugin->state->state_data) { 78 if (this_monitoring_plugin->state->state_data) {
@@ -162,8 +164,9 @@ range *parse_range_string(char *str) {
162int _set_thresholds(thresholds **my_thresholds, char *warn_string, char *critical_string) { 164int _set_thresholds(thresholds **my_thresholds, char *warn_string, char *critical_string) {
163 thresholds *temp_thresholds = NULL; 165 thresholds *temp_thresholds = NULL;
164 166
165 if ((temp_thresholds = calloc(1, sizeof(thresholds))) == NULL) 167 if ((temp_thresholds = calloc(1, sizeof(thresholds))) == NULL) {
166 die(STATE_UNKNOWN, _("Cannot allocate memory: %s"), strerror(errno)); 168 die(STATE_UNKNOWN, _("Cannot allocate memory: %s"), strerror(errno));
169 }
167 170
168 temp_thresholds->warning = NULL; 171 temp_thresholds->warning = NULL;
169 temp_thresholds->critical = NULL; 172 temp_thresholds->critical = NULL;
@@ -215,6 +218,46 @@ void print_thresholds(const char *threshold_name, thresholds *my_threshold) {
215 printf("\n"); 218 printf("\n");
216} 219}
217 220
221/* Returns true if alert should be raised based on the range, false otherwise */
222bool mp_check_range(const mp_perfdata_value value, const mp_range my_range) {
223 bool is_inside = false;
224
225 if (my_range.end_infinity == false && my_range.start_infinity == false) {
226 // range: .........|---inside---|...........
227 // value
228 if ((cmp_perfdata_value(my_range.start, value) < 1) && (cmp_perfdata_value(value, my_range.end) <= 0)) {
229 is_inside = true;
230 } else {
231 is_inside = false;
232 }
233 } else if (my_range.start_infinity == false && my_range.end_infinity == true) {
234 // range: .........|---inside---------
235 // value
236 if (cmp_perfdata_value(my_range.start, value) < 0) {
237 is_inside = true;
238 } else {
239 is_inside = false;
240 }
241 } else if (my_range.start_infinity == true && my_range.end_infinity == false) {
242 // range: -inside--------|....................
243 // value
244 if (cmp_perfdata_value(value, my_range.end) == -1) {
245 is_inside = true;
246 } else {
247 is_inside = false;
248 }
249 } else {
250 // range from -inf to inf, so always inside
251 is_inside = true;
252 }
253
254 if ((is_inside && my_range.alert_on_inside_range == INSIDE) || (!is_inside && my_range.alert_on_inside_range == OUTSIDE)) {
255 return true;
256 }
257
258 return false;
259}
260
218/* Returns true if alert should be raised based on the range */ 261/* Returns true if alert should be raised based on the range */
219bool check_range(double value, range *my_range) { 262bool check_range(double value, range *my_range) {
220 bool no = false; 263 bool no = false;
@@ -228,24 +271,24 @@ bool check_range(double value, range *my_range) {
228 if (my_range->end_infinity == false && my_range->start_infinity == false) { 271 if (my_range->end_infinity == false && my_range->start_infinity == false) {
229 if ((my_range->start <= value) && (value <= my_range->end)) { 272 if ((my_range->start <= value) && (value <= my_range->end)) {
230 return no; 273 return no;
231 } else {
232 return yes;
233 } 274 }
234 } else if (my_range->start_infinity == false && my_range->end_infinity == true) { 275 return yes;
276 }
277
278 if (my_range->start_infinity == false && my_range->end_infinity == true) {
235 if (my_range->start <= value) { 279 if (my_range->start <= value) {
236 return no; 280 return no;
237 } else {
238 return yes;
239 } 281 }
240 } else if (my_range->start_infinity == true && my_range->end_infinity == false) { 282 return yes;
283 }
284
285 if (my_range->start_infinity == true && my_range->end_infinity == false) {
241 if (value <= my_range->end) { 286 if (value <= my_range->end) {
242 return no; 287 return no;
243 } else {
244 return yes;
245 } 288 }
246 } else { 289 return yes;
247 return no;
248 } 290 }
291 return no;
249} 292}
250 293
251/* Returns status */ 294/* Returns status */
@@ -265,7 +308,8 @@ int get_status(double value, thresholds *my_thresholds) {
265 308
266char *np_escaped_string(const char *string) { 309char *np_escaped_string(const char *string) {
267 char *data; 310 char *data;
268 int i, j = 0; 311 int i;
312 int j = 0;
269 data = strdup(string); 313 data = strdup(string);
270 for (i = 0; data[i]; i++) { 314 for (i = 0; data[i]; i++) {
271 if (data[i] == '\\') { 315 if (data[i] == '\\') {
@@ -302,7 +346,8 @@ int np_check_if_root(void) { return (geteuid() == 0); }
302 * data strings. 346 * data strings.
303 */ 347 */
304char *np_extract_value(const char *varlist, const char *name, char sep) { 348char *np_extract_value(const char *varlist, const char *name, char sep) {
305 char *tmp = NULL, *value = NULL; 349 char *tmp = NULL;
350 char *value = NULL;
306 int i; 351 int i;
307 352
308 while (1) { 353 while (1) {
@@ -325,15 +370,17 @@ char *np_extract_value(const char *varlist, const char *name, char sep) {
325 370
326 if ((tmp = index(varlist, sep))) { 371 if ((tmp = index(varlist, sep))) {
327 /* Value is delimited by a comma */ 372 /* Value is delimited by a comma */
328 if (tmp - varlist == 0) 373 if (tmp - varlist == 0) {
329 continue; 374 continue;
375 }
330 value = (char *)calloc(1, tmp - varlist + 1); 376 value = (char *)calloc(1, tmp - varlist + 1);
331 strncpy(value, varlist, tmp - varlist); 377 strncpy(value, varlist, tmp - varlist);
332 value[tmp - varlist] = '\0'; 378 value[tmp - varlist] = '\0';
333 } else { 379 } else {
334 /* Value is delimited by a \0 */ 380 /* Value is delimited by a \0 */
335 if (strlen(varlist) == 0) 381 if (strlen(varlist) == 0) {
336 continue; 382 continue;
383 }
337 value = (char *)calloc(1, strlen(varlist) + 1); 384 value = (char *)calloc(1, strlen(varlist) + 1);
338 strncpy(value, varlist, strlen(varlist)); 385 strncpy(value, varlist, strlen(varlist));
339 value[strlen(varlist)] = '\0'; 386 value[strlen(varlist)] = '\0';
@@ -351,9 +398,11 @@ char *np_extract_value(const char *varlist, const char *name, char sep) {
351 } 398 }
352 399
353 /* Clean-up trailing spaces/newlines */ 400 /* Clean-up trailing spaces/newlines */
354 if (value) 401 if (value) {
355 for (i = strlen(value) - 1; isspace(value[i]); i--) 402 for (i = strlen(value) - 1; isspace(value[i]); i--) {
356 value[i] = '\0'; 403 value[i] = '\0';
404 }
405 }
357 406
358 return value; 407 return value;
359} 408}
@@ -378,14 +427,18 @@ const char *state_text(int result) {
378 * return the corresponding STATE_ value or ERROR) 427 * return the corresponding STATE_ value or ERROR)
379 */ 428 */
380int mp_translate_state(char *state_text) { 429int mp_translate_state(char *state_text) {
381 if (!strcasecmp(state_text, "OK") || !strcmp(state_text, "0")) 430 if (!strcasecmp(state_text, "OK") || !strcmp(state_text, "0")) {
382 return STATE_OK; 431 return STATE_OK;
383 if (!strcasecmp(state_text, "WARNING") || !strcmp(state_text, "1")) 432 }
433 if (!strcasecmp(state_text, "WARNING") || !strcmp(state_text, "1")) {
384 return STATE_WARNING; 434 return STATE_WARNING;
385 if (!strcasecmp(state_text, "CRITICAL") || !strcmp(state_text, "2")) 435 }
436 if (!strcasecmp(state_text, "CRITICAL") || !strcmp(state_text, "2")) {
386 return STATE_CRITICAL; 437 return STATE_CRITICAL;
387 if (!strcasecmp(state_text, "UNKNOWN") || !strcmp(state_text, "3")) 438 }
439 if (!strcasecmp(state_text, "UNKNOWN") || !strcmp(state_text, "3")) {
388 return STATE_UNKNOWN; 440 return STATE_UNKNOWN;
441 }
389 return ERROR; 442 return ERROR;
390} 443}
391 444
@@ -394,7 +447,7 @@ int mp_translate_state(char *state_text) {
394 * hopefully a unique key per service/plugin invocation. Use the extra-opts 447 * hopefully a unique key per service/plugin invocation. Use the extra-opts
395 * parse of argv, so that uniqueness in parameters are reflected there. 448 * parse of argv, so that uniqueness in parameters are reflected there.
396 */ 449 */
397char *_np_state_generate_key() { 450char *_np_state_generate_key(void) {
398 int i; 451 int i;
399 char **argv = this_monitoring_plugin->argv; 452 char **argv = this_monitoring_plugin->argv;
400 char keyname[41]; 453 char keyname[41];
@@ -441,7 +494,7 @@ char *_np_state_generate_key() {
441 return p; 494 return p;
442} 495}
443 496
444void _cleanup_state_data() { 497void _cleanup_state_data(void) {
445 if (this_monitoring_plugin->state->state_data != NULL) { 498 if (this_monitoring_plugin->state->state_data != NULL) {
446 np_free(this_monitoring_plugin->state->state_data->data); 499 np_free(this_monitoring_plugin->state->state_data->data);
447 np_free(this_monitoring_plugin->state->state_data); 500 np_free(this_monitoring_plugin->state->state_data);
@@ -453,19 +506,21 @@ void _cleanup_state_data() {
453 * envvar NAGIOS_PLUGIN_STATE_DIRECTORY 506 * envvar NAGIOS_PLUGIN_STATE_DIRECTORY
454 * statically compiled shared state directory 507 * statically compiled shared state directory
455 */ 508 */
456char *_np_state_calculate_location_prefix() { 509char *_np_state_calculate_location_prefix(void) {
457 char *env_dir; 510 char *env_dir;
458 511
459 /* Do not allow passing MP_STATE_PATH in setuid plugins 512 /* Do not allow passing MP_STATE_PATH in setuid plugins
460 * for security reasons */ 513 * for security reasons */
461 if (!mp_suid()) { 514 if (!mp_suid()) {
462 env_dir = getenv("MP_STATE_PATH"); 515 env_dir = getenv("MP_STATE_PATH");
463 if (env_dir && env_dir[0] != '\0') 516 if (env_dir && env_dir[0] != '\0') {
464 return env_dir; 517 return env_dir;
518 }
465 /* This is the former ENV, for backward-compatibility */ 519 /* This is the former ENV, for backward-compatibility */
466 env_dir = getenv("NAGIOS_PLUGIN_STATE_DIRECTORY"); 520 env_dir = getenv("NAGIOS_PLUGIN_STATE_DIRECTORY");
467 if (env_dir && env_dir[0] != '\0') 521 if (env_dir && env_dir[0] != '\0') {
468 return env_dir; 522 return env_dir;
523 }
469 } 524 }
470 525
471 return NP_STATE_DIR_PREFIX; 526 return NP_STATE_DIR_PREFIX;
@@ -483,19 +538,22 @@ void np_enable_state(char *keyname, int expected_data_version) {
483 char *p = NULL; 538 char *p = NULL;
484 int ret; 539 int ret;
485 540
486 if (this_monitoring_plugin == NULL) 541 if (this_monitoring_plugin == NULL) {
487 die(STATE_UNKNOWN, _("This requires np_init to be called")); 542 die(STATE_UNKNOWN, _("This requires np_init to be called"));
543 }
488 544
489 this_state = (state_key *)calloc(1, sizeof(state_key)); 545 this_state = (state_key *)calloc(1, sizeof(state_key));
490 if (this_state == NULL) 546 if (this_state == NULL) {
491 die(STATE_UNKNOWN, _("Cannot allocate memory: %s"), strerror(errno)); 547 die(STATE_UNKNOWN, _("Cannot allocate memory: %s"), strerror(errno));
548 }
492 549
493 if (keyname == NULL) { 550 if (keyname == NULL) {
494 temp_keyname = _np_state_generate_key(); 551 temp_keyname = _np_state_generate_key();
495 } else { 552 } else {
496 temp_keyname = strdup(keyname); 553 temp_keyname = strdup(keyname);
497 if (temp_keyname == NULL) 554 if (temp_keyname == NULL) {
498 die(STATE_UNKNOWN, _("Cannot execute strdup: %s"), strerror(errno)); 555 die(STATE_UNKNOWN, _("Cannot execute strdup: %s"), strerror(errno));
556 }
499 } 557 }
500 /* Die if invalid characters used for keyname */ 558 /* Die if invalid characters used for keyname */
501 p = temp_keyname; 559 p = temp_keyname;
@@ -513,8 +571,9 @@ void np_enable_state(char *keyname, int expected_data_version) {
513 /* Calculate filename */ 571 /* Calculate filename */
514 ret = asprintf(&temp_filename, "%s/%lu/%s/%s", _np_state_calculate_location_prefix(), (unsigned long)geteuid(), 572 ret = asprintf(&temp_filename, "%s/%lu/%s/%s", _np_state_calculate_location_prefix(), (unsigned long)geteuid(),
515 this_monitoring_plugin->plugin_name, this_state->name); 573 this_monitoring_plugin->plugin_name, this_state->name);
516 if (ret < 0) 574 if (ret < 0) {
517 die(STATE_UNKNOWN, _("Cannot allocate memory: %s"), strerror(errno)); 575 die(STATE_UNKNOWN, _("Cannot allocate memory: %s"), strerror(errno));
576 }
518 577
519 this_state->_filename = temp_filename; 578 this_state->_filename = temp_filename;
520 579
@@ -528,21 +587,23 @@ void np_enable_state(char *keyname, int expected_data_version) {
528 * If numerically lower, then return as no previous state. die with UNKNOWN 587 * If numerically lower, then return as no previous state. die with UNKNOWN
529 * if exceptional error. 588 * if exceptional error.
530 */ 589 */
531state_data *np_state_read() { 590state_data *np_state_read(void) {
532 state_data *this_state_data = NULL; 591 state_data *this_state_data = NULL;
533 FILE *statefile; 592 FILE *statefile;
534 bool rc = false; 593 bool rc = false;
535 594
536 if (this_monitoring_plugin == NULL) 595 if (this_monitoring_plugin == NULL) {
537 die(STATE_UNKNOWN, _("This requires np_init to be called")); 596 die(STATE_UNKNOWN, _("This requires np_init to be called"));
597 }
538 598
539 /* Open file. If this fails, no previous state found */ 599 /* Open file. If this fails, no previous state found */
540 statefile = fopen(this_monitoring_plugin->state->_filename, "r"); 600 statefile = fopen(this_monitoring_plugin->state->_filename, "r");
541 if (statefile != NULL) { 601 if (statefile != NULL) {
542 602
543 this_state_data = (state_data *)calloc(1, sizeof(state_data)); 603 this_state_data = (state_data *)calloc(1, sizeof(state_data));
544 if (this_state_data == NULL) 604 if (this_state_data == NULL) {
545 die(STATE_UNKNOWN, _("Cannot allocate memory: %s"), strerror(errno)); 605 die(STATE_UNKNOWN, _("Cannot allocate memory: %s"), strerror(errno));
606 }
546 607
547 this_state_data->data = NULL; 608 this_state_data->data = NULL;
548 this_monitoring_plugin->state->state_data = this_state_data; 609 this_monitoring_plugin->state->state_data = this_state_data;
@@ -581,8 +642,9 @@ bool _np_state_read_file(FILE *f) {
581 642
582 /* Note: This introduces a limit of 1024 bytes in the string data */ 643 /* Note: This introduces a limit of 1024 bytes in the string data */
583 line = (char *)calloc(1, 1024); 644 line = (char *)calloc(1, 1024);
584 if (line == NULL) 645 if (line == NULL) {
585 die(STATE_UNKNOWN, _("Cannot allocate memory: %s"), strerror(errno)); 646 die(STATE_UNKNOWN, _("Cannot allocate memory: %s"), strerror(errno));
647 }
586 648
587 while (!failure && (fgets(line, 1024, f)) != NULL) { 649 while (!failure && (fgets(line, 1024, f)) != NULL) {
588 pos = strlen(line); 650 pos = strlen(line);
@@ -590,38 +652,42 @@ bool _np_state_read_file(FILE *f) {
590 line[pos - 1] = '\0'; 652 line[pos - 1] = '\0';
591 } 653 }
592 654
593 if (line[0] == '#') 655 if (line[0] == '#') {
594 continue; 656 continue;
657 }
595 658
596 switch (expected) { 659 switch (expected) {
597 case STATE_FILE_VERSION: 660 case STATE_FILE_VERSION:
598 i = atoi(line); 661 i = atoi(line);
599 if (i != NP_STATE_FORMAT_VERSION) 662 if (i != NP_STATE_FORMAT_VERSION) {
600 failure++; 663 failure++;
601 else 664 } else {
602 expected = STATE_DATA_VERSION; 665 expected = STATE_DATA_VERSION;
666 }
603 break; 667 break;
604 case STATE_DATA_VERSION: 668 case STATE_DATA_VERSION:
605 i = atoi(line); 669 i = atoi(line);
606 if (i != this_monitoring_plugin->state->data_version) 670 if (i != this_monitoring_plugin->state->data_version) {
607 failure++; 671 failure++;
608 else 672 } else {
609 expected = STATE_DATA_TIME; 673 expected = STATE_DATA_TIME;
674 }
610 break; 675 break;
611 case STATE_DATA_TIME: 676 case STATE_DATA_TIME:
612 /* If time > now, error */ 677 /* If time > now, error */
613 data_time = strtoul(line, NULL, 10); 678 data_time = strtoul(line, NULL, 10);
614 if (data_time > current_time) 679 if (data_time > current_time) {
615 failure++; 680 failure++;
616 else { 681 } else {
617 this_monitoring_plugin->state->state_data->time = data_time; 682 this_monitoring_plugin->state->state_data->time = data_time;
618 expected = STATE_DATA_TEXT; 683 expected = STATE_DATA_TEXT;
619 } 684 }
620 break; 685 break;
621 case STATE_DATA_TEXT: 686 case STATE_DATA_TEXT:
622 this_monitoring_plugin->state->state_data->data = strdup(line); 687 this_monitoring_plugin->state->state_data->data = strdup(line);
623 if (this_monitoring_plugin->state->state_data->data == NULL) 688 if (this_monitoring_plugin->state->state_data->data == NULL) {
624 die(STATE_UNKNOWN, _("Cannot execute strdup: %s"), strerror(errno)); 689 die(STATE_UNKNOWN, _("Cannot execute strdup: %s"), strerror(errno));
690 }
625 expected = STATE_DATA_END; 691 expected = STATE_DATA_END;
626 status = true; 692 status = true;
627 break; 693 break;
@@ -648,16 +714,18 @@ void np_state_write_string(time_t data_time, char *data_string) {
648 char *directories = NULL; 714 char *directories = NULL;
649 char *p = NULL; 715 char *p = NULL;
650 716
651 if (data_time == 0) 717 if (data_time == 0) {
652 time(&current_time); 718 time(&current_time);
653 else 719 } else {
654 current_time = data_time; 720 current_time = data_time;
721 }
655 722
656 /* If file doesn't currently exist, create directories */ 723 /* If file doesn't currently exist, create directories */
657 if (access(this_monitoring_plugin->state->_filename, F_OK) != 0) { 724 if (access(this_monitoring_plugin->state->_filename, F_OK) != 0) {
658 result = asprintf(&directories, "%s", this_monitoring_plugin->state->_filename); 725 result = asprintf(&directories, "%s", this_monitoring_plugin->state->_filename);
659 if (result < 0) 726 if (result < 0) {
660 die(STATE_UNKNOWN, _("Cannot allocate memory: %s"), strerror(errno)); 727 die(STATE_UNKNOWN, _("Cannot allocate memory: %s"), strerror(errno));
728 }
661 729
662 for (p = directories + 1; *p; p++) { 730 for (p = directories + 1; *p; p++) {
663 if (*p == '/') { 731 if (*p == '/') {
@@ -674,8 +742,9 @@ void np_state_write_string(time_t data_time, char *data_string) {
674 } 742 }
675 743
676 result = asprintf(&temp_file, "%s.XXXXXX", this_monitoring_plugin->state->_filename); 744 result = asprintf(&temp_file, "%s.XXXXXX", this_monitoring_plugin->state->_filename);
677 if (result < 0) 745 if (result < 0) {
678 die(STATE_UNKNOWN, _("Cannot allocate memory: %s"), strerror(errno)); 746 die(STATE_UNKNOWN, _("Cannot allocate memory: %s"), strerror(errno));
747 }
679 748
680 if ((fd = mkstemp(temp_file)) == -1) { 749 if ((fd = mkstemp(temp_file)) == -1) {
681 np_free(temp_file); 750 np_free(temp_file);