/***************************************************************************** * * XRDDEFAULT.C - Default external state retention routines for Nagios * * * License: * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as * published by the Free Software Foundation. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * *****************************************************************************/ /*********** COMMON HEADER FILES ***********/ #include "../include/config.h" #include "../include/common.h" #include "../include/objects.h" #include "../include/statusdata.h" #include "../include/macros.h" #include "../include/nagios.h" #include "../include/sretention.h" #include "../include/comments.h" #include "../include/downtime.h" #include "xrddefault.h" /******************************************************************/ /********************* INIT/CLEANUP FUNCTIONS *********************/ /******************************************************************/ /* initialize retention data */ int xrddefault_initialize_retention_data(const char *cfgfile) { nagios_macros *mac; /* initialize locations if necessary */ if(retention_file == NULL) retention_file = (char *)strdup(DEFAULT_RETENTION_FILE); /* make sure we have everything */ if(retention_file == NULL) return ERROR; mac = get_global_macros(); /* save the retention file macro */ my_free(mac->x[MACRO_RETENTIONDATAFILE]); mac->x[MACRO_RETENTIONDATAFILE] = retention_file; if((mac->x[MACRO_RETENTIONDATAFILE] = (char *)strdup(retention_file))) strip(mac->x[MACRO_RETENTIONDATAFILE]); return OK; } /* cleanup retention data before terminating */ int xrddefault_cleanup_retention_data(void) { /* free memory */ my_free(retention_file); return OK; } /******************************************************************/ /**************** DEFAULT STATE OUTPUT FUNCTION *******************/ /******************************************************************/ int xrddefault_save_state_information(void) { char *tmp_file = NULL; customvariablesmember *temp_customvariablesmember = NULL; time_t current_time = 0L; int result = OK; FILE *fp = NULL; host *temp_host = NULL; service *temp_service = NULL; contact *temp_contact = NULL; nagios_comment *temp_comment = NULL; scheduled_downtime *temp_downtime = NULL; int x = 0; int fd = 0; unsigned long host_attribute_mask = 0L; unsigned long service_attribute_mask = 0L; unsigned long contact_attribute_mask = 0L; unsigned long contact_host_attribute_mask = 0L; unsigned long contact_service_attribute_mask = 0L; unsigned long process_host_attribute_mask = 0L; unsigned long process_service_attribute_mask = 0L; log_debug_info(DEBUGL_FUNCTIONS, 0, "xrddefault_save_state_information()\n"); /* make sure we have everything */ if(retention_file == NULL || temp_file == NULL) { logit(NSLOG_RUNTIME_ERROR, TRUE, "Error: We don't have the required file names to store retention data!\n"); return ERROR; } /* open a safe temp file for output */ asprintf(&tmp_file, "%sXXXXXX", temp_file); if(tmp_file == NULL) return ERROR; if((fd = mkstemp(tmp_file)) == -1) return ERROR; log_debug_info(DEBUGL_RETENTIONDATA, 2, "Writing retention data to temp file '%s'\n", tmp_file); fp = (FILE *)fdopen(fd, "w"); if(fp == NULL) { close(fd); unlink(tmp_file); logit(NSLOG_RUNTIME_ERROR, TRUE, "Error: Could not open temp state retention file '%s' for writing!\n", tmp_file); my_free(tmp_file); return ERROR; } /* what attributes should be masked out? */ /* NOTE: host/service/contact-specific values may be added in the future, but for now we only have global masks */ process_host_attribute_mask = retained_process_host_attribute_mask; process_service_attribute_mask = retained_process_service_attribute_mask; host_attribute_mask = retained_host_attribute_mask; service_attribute_mask = retained_service_attribute_mask; contact_host_attribute_mask = retained_contact_host_attribute_mask; contact_service_attribute_mask = retained_contact_service_attribute_mask; /* write version info to status file */ fprintf(fp, "########################################\n"); fprintf(fp, "# NAGIOS STATE RETENTION FILE\n"); fprintf(fp, "#\n"); fprintf(fp, "# THIS FILE IS AUTOMATICALLY GENERATED\n"); fprintf(fp, "# BY NAGIOS. DO NOT MODIFY THIS FILE!\n"); fprintf(fp, "########################################\n"); time(¤t_time); /* write file info */ fprintf(fp, "info {\n"); fprintf(fp, "created=%llu\n", (unsigned long long)current_time); fprintf(fp, "version=%s\n", PROGRAM_VERSION); fprintf(fp, "last_update_check=%llu\n", (unsigned long long)last_update_check); fprintf(fp, "update_available=%d\n", update_available); fprintf(fp, "update_uid=%lu\n", update_uid); fprintf(fp, "last_version=%s\n", (last_program_version == NULL) ? "" : last_program_version); fprintf(fp, "new_version=%s\n", (new_program_version == NULL) ? "" : new_program_version); fprintf(fp, "}\n"); /* save program state information */ fprintf(fp, "program {\n"); fprintf(fp, "modified_host_attributes=%lu\n", (modified_host_process_attributes & ~process_host_attribute_mask)); fprintf(fp, "modified_service_attributes=%lu\n", (modified_service_process_attributes & ~process_service_attribute_mask)); fprintf(fp, "enable_notifications=%d\n", enable_notifications); fprintf(fp, "active_service_checks_enabled=%d\n", execute_service_checks); fprintf(fp, "passive_service_checks_enabled=%d\n", accept_passive_service_checks); fprintf(fp, "active_host_checks_enabled=%d\n", execute_host_checks); fprintf(fp, "passive_host_checks_enabled=%d\n", accept_passive_host_checks); fprintf(fp, "enable_event_handlers=%d\n", enable_event_handlers); fprintf(fp, "obsess_over_services=%d\n", obsess_over_services); fprintf(fp, "obsess_over_hosts=%d\n", obsess_over_hosts); fprintf(fp, "check_service_freshness=%d\n", check_service_freshness); fprintf(fp, "check_host_freshness=%d\n", check_host_freshness); fprintf(fp, "enable_flap_detection=%d\n", enable_flap_detection); fprintf(fp, "process_performance_data=%d\n", process_performance_data); fprintf(fp, "global_host_event_handler=%s\n", (global_host_event_handler == NULL) ? "" : global_host_event_handler); fprintf(fp, "global_service_event_handler=%s\n", (global_service_event_handler == NULL) ? "" : global_service_event_handler); fprintf(fp, "next_comment_id=%lu\n", next_comment_id); fprintf(fp, "next_downtime_id=%lu\n", next_downtime_id); fprintf(fp, "next_event_id=%lu\n", next_event_id); fprintf(fp, "next_problem_id=%lu\n", next_problem_id); fprintf(fp, "next_notification_id=%lu\n", next_notification_id); fprintf(fp, "}\n"); /* save host state information */ for(temp_host = host_list; temp_host != NULL; temp_host = temp_host->next) { fprintf(fp, "host {\n"); fprintf(fp, "host_name=%s\n", temp_host->name); fprintf(fp, "modified_attributes=%lu\n", (temp_host->modified_attributes & ~host_attribute_mask)); fprintf(fp, "check_command=%s\n", (temp_host->check_command == NULL) ? "" : temp_host->check_command); fprintf(fp, "check_period=%s\n", (temp_host->check_period == NULL) ? "" : temp_host->check_period); fprintf(fp, "notification_period=%s\n", (temp_host->notification_period == NULL) ? "" : temp_host->notification_period); fprintf(fp, "event_handler=%s\n", (temp_host->event_handler == NULL) ? "" : temp_host->event_handler); fprintf(fp, "has_been_checked=%d\n", temp_host->has_been_checked); fprintf(fp, "check_execution_time=%.3f\n", temp_host->execution_time); fprintf(fp, "check_latency=%.3f\n", temp_host->latency); fprintf(fp, "check_type=%d\n", temp_host->check_type); fprintf(fp, "current_state=%d\n", temp_host->current_state); fprintf(fp, "last_state=%d\n", temp_host->last_state); fprintf(fp, "last_hard_state=%d\n", temp_host->last_hard_state); fprintf(fp, "last_event_id=%lu\n", temp_host->last_event_id); fprintf(fp, "current_event_id=%lu\n", temp_host->current_event_id); fprintf(fp, "current_problem_id=%lu\n", temp_host->current_problem_id); fprintf(fp, "last_problem_id=%lu\n", temp_host->last_problem_id); fprintf(fp, "plugin_output=%s\n", (temp_host->plugin_output == NULL) ? "" : temp_host->plugin_output); fprintf(fp, "long_plugin_output=%s\n", (temp_host->long_plugin_output == NULL) ? "" : temp_host->long_plugin_output); fprintf(fp, "performance_data=%s\n", (temp_host->perf_data == NULL) ? "" : temp_host->perf_data); fprintf(fp, "last_check=%llu\n", (unsigned long long)temp_host->last_check); fprintf(fp, "next_check=%llu\n", (unsigned long long)temp_host->next_check); fprintf(fp, "check_options=%d\n", temp_host->check_options); fprintf(fp, "current_attempt=%d\n", temp_host->current_attempt); fprintf(fp, "max_attempts=%d\n", temp_host->max_attempts); fprintf(fp, "check_interval=%f\n", temp_host->check_interval); fprintf(fp, "retry_interval=%f\n", temp_host->retry_interval); fprintf(fp, "state_type=%d\n", temp_host->state_type); fprintf(fp, "last_state_change=%llu\n", (unsigned long long)temp_host->last_state_change); fprintf(fp, "last_hard_state_change=%llu\n", (unsigned long long)temp_host->last_hard_state_change); fprintf(fp, "last_time_up=%llu\n", (unsigned long long)temp_host->last_time_up); fprintf(fp, "last_time_down=%llu\n", (unsigned long long)temp_host->last_time_down); fprintf(fp, "last_time_unreachable=%llu\n", (unsigned long long)temp_host->last_time_unreachable); fprintf(fp, "notified_on_down=%d\n", flag_isset(temp_host->notified_on, OPT_DOWN)); fprintf(fp, "notified_on_unreachable=%d\n", flag_isset(temp_host->notified_on, OPT_UNREACHABLE)); fprintf(fp, "last_notification=%llu\n", (unsigned long long)temp_host->last_notification); fprintf(fp, "current_notification_number=%d\n", temp_host->current_notification_number); fprintf(fp, "current_notification_id=%lu\n", temp_host->current_notification_id); fprintf(fp, "notifications_enabled=%d\n", temp_host->notifications_enabled); fprintf(fp, "problem_has_been_acknowledged=%d\n", temp_host->problem_has_been_acknowledged); fprintf(fp, "acknowledgement_type=%d\n", temp_host->acknowledgement_type); fprintf(fp, "active_checks_enabled=%d\n", temp_host->checks_enabled); fprintf(fp, "passive_checks_enabled=%d\n", temp_host->accept_passive_checks); fprintf(fp, "event_handler_enabled=%d\n", temp_host->event_handler_enabled); fprintf(fp, "flap_detection_enabled=%d\n", temp_host->flap_detection_enabled); fprintf(fp, "process_performance_data=%d\n", temp_host->process_performance_data); fprintf(fp, "obsess=%d\n", temp_host->obsess); fprintf(fp, "is_flapping=%d\n", temp_host->is_flapping); fprintf(fp, "percent_state_change=%.2f\n", temp_host->percent_state_change); fprintf(fp, "check_flapping_recovery_notification=%d\n", temp_host->check_flapping_recovery_notification); fprintf(fp, "state_history="); for(x = 0; x < MAX_STATE_HISTORY_ENTRIES; x++) fprintf(fp, "%s%d", (x > 0) ? "," : "", temp_host->state_history[(x + temp_host->state_history_index) % MAX_STATE_HISTORY_ENTRIES]); fprintf(fp, "\n"); /* custom variables */ for(temp_customvariablesmember = temp_host->custom_variables; temp_customvariablesmember != NULL; temp_customvariablesmember = temp_customvariablesmember->next) { if(temp_customvariablesmember->variable_name) fprintf(fp, "_%s=%d;%s\n", temp_customvariablesmember->variable_name, temp_customvariablesmember->has_been_modified, (temp_customvariablesmember->variable_value == NULL) ? "" : temp_customvariablesmember->variable_value); } fprintf(fp, "}\n"); } /* save service state information */ for(temp_service = service_list; temp_service != NULL; temp_service = temp_service->next) { fprintf(fp, "service {\n"); fprintf(fp, "host_name=%s\n", temp_service->host_name); fprintf(fp, "service_description=%s\n", temp_service->description); fprintf(fp, "modified_attributes=%lu\n", (temp_service->modified_attributes & ~service_attribute_mask)); fprintf(fp, "check_command=%s\n", (temp_service->check_command == NULL) ? "" : temp_service->check_command); fprintf(fp, "check_period=%s\n", (temp_service->check_period == NULL) ? "" : temp_service->check_period); fprintf(fp, "notification_period=%s\n", (temp_service->notification_period == NULL) ? "" : temp_service->notification_period); fprintf(fp, "event_handler=%s\n", (temp_service->event_handler == NULL) ? "" : temp_service->event_handler); fprintf(fp, "has_been_checked=%d\n", temp_service->has_been_checked); fprintf(fp, "check_execution_time=%.3f\n", temp_service->execution_time); fprintf(fp, "check_latency=%.3f\n", temp_service->latency); fprintf(fp, "check_type=%d\n", temp_service->check_type); fprintf(fp, "current_state=%d\n", temp_service->current_state); fprintf(fp, "last_state=%d\n", temp_service->last_state); fprintf(fp, "last_hard_state=%d\n", temp_service->last_hard_state); fprintf(fp, "last_event_id=%lu\n", temp_service->last_event_id); fprintf(fp, "current_event_id=%lu\n", temp_service->current_event_id); fprintf(fp, "current_problem_id=%lu\n", temp_service->current_problem_id); fprintf(fp, "last_problem_id=%lu\n", temp_service->last_problem_id); fprintf(fp, "current_attempt=%d\n", temp_service->current_attempt); fprintf(fp, "max_attempts=%d\n", temp_service->max_attempts); fprintf(fp, "check_interval=%f\n", temp_service->check_interval); fprintf(fp, "retry_interval=%f\n", temp_service->retry_interval); fprintf(fp, "state_type=%d\n", temp_service->state_type); fprintf(fp, "last_state_change=%llu\n", (unsigned long long)temp_service->last_state_change); fprintf(fp, "last_hard_state_change=%llu\n", (unsigned long long)temp_service->last_hard_state_change); fprintf(fp, "last_time_ok=%llu\n", (unsigned long long)temp_service->last_time_ok); fprintf(fp, "last_time_warning=%llu\n", (unsigned long long)temp_service->last_time_warning); fprintf(fp, "last_time_unknown=%llu\n", (unsigned long long)temp_service->last_time_unknown); fprintf(fp, "last_time_critical=%llu\n", (unsigned long long)temp_service->last_time_critical); fprintf(fp, "plugin_output=%s\n", (temp_service->plugin_output == NULL) ? "" : temp_service->plugin_output); fprintf(fp, "long_plugin_output=%s\n", (temp_service->long_plugin_output == NULL) ? "" : temp_service->long_plugin_output); fprintf(fp, "performance_data=%s\n", (temp_service->perf_data == NULL) ? "" : temp_service->perf_data); fprintf(fp, "last_check=%llu\n", (unsigned long long)temp_service->last_check); fprintf(fp, "next_check=%llu\n", (unsigned long long)temp_service->next_check); fprintf(fp, "check_options=%d\n", temp_service->check_options); fprintf(fp, "notified_on_unknown=%d\n", flag_isset(temp_service->notified_on, OPT_UNKNOWN)); fprintf(fp, "notified_on_warning=%d\n", flag_isset(temp_service->notified_on, OPT_WARNING)); fprintf(fp, "notified_on_critical=%d\n", flag_isset(temp_service->notified_on, OPT_CRITICAL)); fprintf(fp, "current_notification_number=%d\n", temp_service->current_notification_number); fprintf(fp, "current_notification_id=%lu\n", temp_service->current_notification_id); fprintf(fp, "last_notification=%llu\n", (unsigned long long)temp_service->last_notification); fprintf(fp, "notifications_enabled=%d\n", temp_service->notifications_enabled); fprintf(fp, "active_checks_enabled=%d\n", temp_service->checks_enabled); fprintf(fp, "passive_checks_enabled=%d\n", temp_service->accept_passive_checks); fprintf(fp, "event_handler_enabled=%d\n", temp_service->event_handler_enabled); fprintf(fp, "problem_has_been_acknowledged=%d\n", temp_service->problem_has_been_acknowledged); fprintf(fp, "acknowledgement_type=%d\n", temp_service->acknowledgement_type); fprintf(fp, "flap_detection_enabled=%d\n", temp_service->flap_detection_enabled); fprintf(fp, "process_performance_data=%d\n", temp_service->process_performance_data); fprintf(fp, "obsess=%d\n", temp_service->obsess); fprintf(fp, "is_flapping=%d\n", temp_service->is_flapping); fprintf(fp, "percent_state_change=%.2f\n", temp_service->percent_state_change); fprintf(fp, "check_flapping_recovery_notification=%d\n", temp_service->check_flapping_recovery_notification); fprintf(fp, "state_history="); for(x = 0; x < MAX_STATE_HISTORY_ENTRIES; x++) fprintf(fp, "%s%d", (x > 0) ? "," : "", temp_service->state_history[(x + temp_service->state_history_index) % MAX_STATE_HISTORY_ENTRIES]); fprintf(fp, "\n"); /* custom variables */ for(temp_customvariablesmember = temp_service->custom_variables; temp_customvariablesmember != NULL; temp_customvariablesmember = temp_customvariablesmember->next) { if(temp_customvariablesmember->variable_name) fprintf(fp, "_%s=%d;%s\n", temp_customvariablesmember->variable_name, temp_customvariablesmember->has_been_modified, (temp_customvariablesmember->variable_value == NULL) ? "" : temp_customvariablesmember->variable_value); } fprintf(fp, "}\n"); } /* save contact state information */ for(temp_contact = contact_list; temp_contact != NULL; temp_contact = temp_contact->next) { fprintf(fp, "contact {\n"); fprintf(fp, "contact_name=%s\n", temp_contact->name); fprintf(fp, "modified_attributes=%lu\n", (temp_contact->modified_attributes & ~contact_attribute_mask)); fprintf(fp, "modified_host_attributes=%lu\n", (temp_contact->modified_host_attributes & ~contact_host_attribute_mask)); fprintf(fp, "modified_service_attributes=%lu\n", (temp_contact->modified_service_attributes & ~contact_service_attribute_mask)); fprintf(fp, "host_notification_period=%s\n", (temp_contact->host_notification_period == NULL) ? "" : temp_contact->host_notification_period); fprintf(fp, "service_notification_period=%s\n", (temp_contact->service_notification_period == NULL) ? "" : temp_contact->service_notification_period); fprintf(fp, "last_host_notification=%llu\n", (unsigned long long)temp_contact->last_host_notification); fprintf(fp, "last_service_notification=%llu\n", (unsigned long long)temp_contact->last_service_notification); fprintf(fp, "host_notifications_enabled=%d\n", temp_contact->host_notifications_enabled); fprintf(fp, "service_notifications_enabled=%d\n", temp_contact->service_notifications_enabled); /* custom variables */ for(temp_customvariablesmember = temp_contact->custom_variables; temp_customvariablesmember != NULL; temp_customvariablesmember = temp_customvariablesmember->next) { if(temp_customvariablesmember->variable_name) fprintf(fp, "_%s=%d;%s\n", temp_customvariablesmember->variable_name, temp_customvariablesmember->has_been_modified, (temp_customvariablesmember->variable_value == NULL) ? "" : temp_customvariablesmember->variable_value); } fprintf(fp, "}\n"); } /* save all comments */ for(temp_comment = comment_list; temp_comment != NULL; temp_comment = temp_comment->next) { if(temp_comment->comment_type == HOST_COMMENT) fprintf(fp, "hostcomment {\n"); else fprintf(fp, "servicecomment {\n"); fprintf(fp, "host_name=%s\n", temp_comment->host_name); if(temp_comment->comment_type == SERVICE_COMMENT) fprintf(fp, "service_description=%s\n", temp_comment->service_description); fprintf(fp, "entry_type=%d\n", temp_comment->entry_type); fprintf(fp, "comment_id=%lu\n", temp_comment->comment_id); fprintf(fp, "source=%d\n", temp_comment->source); fprintf(fp, "persistent=%d\n", temp_comment->persistent); fprintf(fp, "entry_time=%llu\n", (unsigned long long)temp_comment->entry_time); fprintf(fp, "expires=%d\n", temp_comment->expires); fprintf(fp, "expire_time=%llu\n", (unsigned long long)temp_comment->expire_time); fprintf(fp, "author=%s\n", temp_comment->author); fprintf(fp, "comment_data=%s\n", temp_comment->comment_data); fprintf(fp, "}\n"); } /* save all downtime */ for(temp_downtime = scheduled_downtime_list; temp_downtime != NULL; temp_downtime = temp_downtime->next) { if(temp_downtime->type == HOST_DOWNTIME) fprintf(fp, "hostdowntime {\n"); else fprintf(fp, "servicedowntime {\n"); fprintf(fp, "host_name=%s\n", temp_downtime->host_name); if(temp_downtime->type == SERVICE_DOWNTIME) fprintf(fp, "service_description=%s\n", temp_downtime->service_description); fprintf(fp, "comment_id=%lu\n", temp_downtime->comment_id); fprintf(fp, "downtime_id=%lu\n", temp_downtime->downtime_id); fprintf(fp, "entry_time=%llu\n", (unsigned long long)temp_downtime->entry_time); fprintf(fp, "start_time=%llu\n", (unsigned long long)temp_downtime->start_time); fprintf(fp, "flex_downtime_start=%llu\n", (unsigned long long)temp_downtime->flex_downtime_start); fprintf(fp, "end_time=%llu\n", (unsigned long long)temp_downtime->end_time); fprintf(fp, "triggered_by=%lu\n", temp_downtime->triggered_by); fprintf(fp, "fixed=%d\n", temp_downtime->fixed); fprintf(fp, "duration=%lu\n", temp_downtime->duration); fprintf(fp, "is_in_effect=%d\n", temp_downtime->is_in_effect); fprintf(fp, "start_notification_sent=%d\n", temp_downtime->start_notification_sent); fprintf(fp, "author=%s\n", temp_downtime->author); fprintf(fp, "comment=%s\n", temp_downtime->comment); fprintf(fp, "}\n"); } fflush(fp); fsync(fd); result = fclose(fp); /* save/close was successful */ if(result == 0) { result = OK; /* move the temp file to the retention file (overwrite the old retention file) */ if(my_rename(tmp_file, retention_file)) { unlink(tmp_file); logit(NSLOG_RUNTIME_ERROR, TRUE, "Error: Unable to update retention file '%s': %s", retention_file, strerror(errno)); result = ERROR; } } /* a problem occurred saving the file */ else { result = ERROR; /* remove temp file and log an error */ unlink(tmp_file); logit(NSLOG_RUNTIME_ERROR, TRUE, "Error: Unable to save retention file: %s", strerror(errno)); } /* free memory */ my_free(tmp_file); return result; } /******************************************************************/ /***************** DEFAULT STATE INPUT FUNCTION *******************/ /******************************************************************/ int xrddefault_read_state_information(void) { char *input = NULL; char *inputbuf = NULL; char *temp_ptr = NULL; mmapfile *thefile; char *host_name = NULL; char *service_description = NULL; char *contact_name = NULL; char *author = NULL; char *comment_data = NULL; int data_type = XRDDEFAULT_NO_DATA; int x = 0; host *temp_host = NULL; service *temp_service = NULL; contact *temp_contact = NULL; command *temp_command = NULL; timeperiod *temp_timeperiod = NULL; customvariablesmember *temp_customvariablesmember = NULL; char *customvarname = NULL; char *var = NULL; char *val = NULL; char *tempval = NULL; char *ch = NULL; unsigned long comment_id = 0; int persistent = FALSE; int expires = FALSE; time_t expire_time = 0L; int entry_type = USER_COMMENT; int source = COMMENTSOURCE_INTERNAL; time_t entry_time = 0L; time_t creation_time; time_t current_time; int scheduling_info_is_ok = FALSE; unsigned long downtime_id = 0; time_t start_time = 0L; time_t flex_downtime_start = ( time_t)0; time_t end_time = 0L; int fixed = FALSE; unsigned long triggered_by = 0; unsigned long duration = 0L; unsigned long host_attribute_mask = 0L; unsigned long service_attribute_mask = 0L; unsigned long contact_attribute_mask = 0L; unsigned long contact_host_attribute_mask = 0L; unsigned long contact_service_attribute_mask = 0L; unsigned long process_host_attribute_mask = 0L; unsigned long process_service_attribute_mask = 0L; int remove_comment = FALSE; int ack = FALSE; int was_flapping = FALSE; int allow_flapstart_notification = TRUE; struct timeval tv[2]; double runtime[2]; int found_directive = FALSE; int is_in_effect = FALSE; int start_notification_sent = FALSE; log_debug_info(DEBUGL_FUNCTIONS, 0, "xrddefault_read_state_information() start\n"); /* make sure we have what we need */ if(retention_file == NULL) { logit(NSLOG_RUNTIME_ERROR, TRUE, "Error: We don't have a filename for retention data!\n"); return ERROR; } if(test_scheduling == TRUE) gettimeofday(&tv[0], NULL); /* open the retention file for reading */ if((thefile = mmap_fopen(retention_file)) == NULL) return ERROR; /* what attributes should be masked out? */ /* NOTE: host/service/contact-specific values may be added in the future, but for now we only have global masks */ process_host_attribute_mask = retained_process_host_attribute_mask; process_service_attribute_mask = retained_process_host_attribute_mask; host_attribute_mask = retained_host_attribute_mask; service_attribute_mask = retained_host_attribute_mask; contact_host_attribute_mask = retained_contact_host_attribute_mask; contact_service_attribute_mask = retained_contact_service_attribute_mask; /* Big speedup when reading retention.dat in bulk */ defer_downtime_sorting = 1; defer_comment_sorting = 1; /* read all lines in the retention file */ while(1) { /* free memory */ my_free(inputbuf); /* read the next line */ if((inputbuf = mmap_fgets(thefile)) == NULL) break; input = inputbuf; /* far better than strip()ing */ if(input[0] == '\t') input++; strip(input); if(!strcmp(input, "service {")) data_type = XRDDEFAULT_SERVICESTATUS_DATA; else if(!strcmp(input, "host {")) data_type = XRDDEFAULT_HOSTSTATUS_DATA; else if(!strcmp(input, "contact {")) data_type = XRDDEFAULT_CONTACTSTATUS_DATA; else if(!strcmp(input, "hostcomment {")) data_type = XRDDEFAULT_HOSTCOMMENT_DATA; else if(!strcmp(input, "servicecomment {")) data_type = XRDDEFAULT_SERVICECOMMENT_DATA; else if(!strcmp(input, "hostdowntime {")) data_type = XRDDEFAULT_HOSTDOWNTIME_DATA; else if(!strcmp(input, "servicedowntime {")) data_type = XRDDEFAULT_SERVICEDOWNTIME_DATA; else if(!strcmp(input, "info {")) data_type = XRDDEFAULT_INFO_DATA; else if(!strcmp(input, "program {")) data_type = XRDDEFAULT_PROGRAMSTATUS_DATA; else if(!strcmp(input, "}")) { switch(data_type) { case XRDDEFAULT_INFO_DATA: break; case XRDDEFAULT_PROGRAMSTATUS_DATA: /* adjust modified attributes if necessary */ if(use_retained_program_state == FALSE) { modified_host_process_attributes = MODATTR_NONE; modified_service_process_attributes = MODATTR_NONE; } break; case XRDDEFAULT_HOSTSTATUS_DATA: if(temp_host != NULL) { /* adjust modified attributes if necessary */ if(temp_host->retain_nonstatus_information == FALSE) temp_host->modified_attributes = MODATTR_NONE; /* adjust modified attributes if no custom variables have been changed */ if(temp_host->modified_attributes & MODATTR_CUSTOM_VARIABLE) { for(temp_customvariablesmember = temp_host->custom_variables; temp_customvariablesmember != NULL; temp_customvariablesmember = temp_customvariablesmember->next) { if(temp_customvariablesmember->has_been_modified == TRUE) break; } if(temp_customvariablesmember == NULL) temp_host->modified_attributes -= MODATTR_CUSTOM_VARIABLE; } /* calculate next possible notification time */ if(temp_host->current_state != HOST_UP && temp_host->last_notification != (time_t)0) temp_host->next_notification = get_next_host_notification_time(temp_host, temp_host->last_notification); /* ADDED 01/23/2009 adjust current check attempts if host in hard problem state (max attempts may have changed in config since restart) */ if(temp_host->current_state != HOST_UP && temp_host->state_type == HARD_STATE) temp_host->current_attempt = temp_host->max_attempts; /* ADDED 02/20/08 assume same flapping state if large install tweaks enabled */ if(use_large_installation_tweaks == TRUE) { temp_host->is_flapping = was_flapping; } /* else use normal startup flap detection logic */ else { /* host was flapping before program started */ /* 11/10/07 don't allow flapping notifications to go out */ if(was_flapping == TRUE) allow_flapstart_notification = FALSE; else /* flapstart notifications are okay */ allow_flapstart_notification = TRUE; /* check for flapping */ check_for_host_flapping(temp_host, FALSE, FALSE, allow_flapstart_notification); /* host was flapping before and isn't now, so clear recovery check variable if host isn't flapping now */ if(was_flapping == TRUE && temp_host->is_flapping == FALSE) temp_host->check_flapping_recovery_notification = FALSE; } /* handle new vars added in 2.x */ if(temp_host->last_hard_state_change == (time_t)0) temp_host->last_hard_state_change = temp_host->last_state_change; /* update host status */ update_host_status(temp_host, FALSE); } /* reset vars */ was_flapping = FALSE; allow_flapstart_notification = TRUE; my_free(host_name); host_name = NULL; temp_host = NULL; break; case XRDDEFAULT_SERVICESTATUS_DATA: if(temp_service != NULL) { /* adjust modified attributes if necessary */ if(temp_service->retain_nonstatus_information == FALSE) temp_service->modified_attributes = MODATTR_NONE; /* adjust modified attributes if no custom variables have been changed */ if(temp_service->modified_attributes & MODATTR_CUSTOM_VARIABLE) { for(temp_customvariablesmember = temp_service->custom_variables; temp_customvariablesmember != NULL; temp_customvariablesmember = temp_customvariablesmember->next) { if(temp_customvariablesmember->has_been_modified == TRUE) break; } if(temp_customvariablesmember == NULL) temp_service->modified_attributes -= MODATTR_CUSTOM_VARIABLE; } /* calculate next possible notification time */ if(temp_service->current_state != STATE_OK && temp_service->last_notification != (time_t)0) temp_service->next_notification = get_next_service_notification_time(temp_service, temp_service->last_notification); /* fix old vars */ if(temp_service->has_been_checked == FALSE && temp_service->state_type == SOFT_STATE) temp_service->state_type = HARD_STATE; /* ADDED 01/23/2009 adjust current check attempt if service is in hard problem state (max attempts may have changed in config since restart) */ if(temp_service->current_state != STATE_OK && temp_service->state_type == HARD_STATE) temp_service->current_attempt = temp_service->max_attempts; /* ADDED 02/20/08 assume same flapping state if large install tweaks enabled */ if(use_large_installation_tweaks == TRUE) { temp_service->is_flapping = was_flapping; } /* else use normal startup flap detection logic */ else { /* service was flapping before program started */ /* 11/10/07 don't allow flapping notifications to go out */ if(was_flapping == TRUE) allow_flapstart_notification = FALSE; else /* flapstart notifications are okay */ allow_flapstart_notification = TRUE; /* check for flapping */ check_for_service_flapping(temp_service, FALSE, allow_flapstart_notification); /* service was flapping before and isn't now, so clear recovery check variable if service isn't flapping now */ if(was_flapping == TRUE && temp_service->is_flapping == FALSE) temp_service->check_flapping_recovery_notification = FALSE; } /* handle new vars added in 2.x */ if(temp_service->last_hard_state_change == (time_t)0) temp_service->last_hard_state_change = temp_service->last_state_change; /* update service status */ update_service_status(temp_service, FALSE); } /* reset vars */ was_flapping = FALSE; allow_flapstart_notification = TRUE; my_free(host_name); my_free(service_description); temp_service = NULL; break; case XRDDEFAULT_CONTACTSTATUS_DATA: if(temp_contact != NULL) { /* adjust modified attributes if necessary */ if(temp_contact->retain_nonstatus_information == FALSE) temp_contact->modified_attributes = MODATTR_NONE; /* adjust modified attributes if no custom variables have been changed */ if(temp_contact->modified_attributes & MODATTR_CUSTOM_VARIABLE) { for(temp_customvariablesmember = temp_contact->custom_variables; temp_customvariablesmember != NULL; temp_customvariablesmember = temp_customvariablesmember->next) { if(temp_customvariablesmember->has_been_modified == TRUE) break; } if(temp_customvariablesmember == NULL) temp_contact->modified_attributes -= MODATTR_CUSTOM_VARIABLE; } /* update contact status */ update_contact_status(temp_contact, FALSE); } my_free(contact_name); temp_contact = NULL; break; case XRDDEFAULT_HOSTCOMMENT_DATA: case XRDDEFAULT_SERVICECOMMENT_DATA: /* add the comment */ add_comment((data_type == XRDDEFAULT_HOSTCOMMENT_DATA) ? HOST_COMMENT : SERVICE_COMMENT, entry_type, host_name, service_description, entry_time, author, comment_data, comment_id, persistent, expires, expire_time, source); /* delete the comment if necessary */ /* it seems a bit backwards to add and then immediately delete the comment, but its necessary to track comment deletions in the event broker */ remove_comment = FALSE; /* host no longer exists */ if((temp_host = find_host(host_name)) == NULL) remove_comment = TRUE; /* service no longer exists */ else if(data_type == XRDDEFAULT_SERVICECOMMENT_DATA && (temp_service = find_service(host_name, service_description)) == NULL) remove_comment = TRUE; /* acknowledgement comments get deleted if they're not persistent and the original problem is no longer acknowledged */ else if(entry_type == ACKNOWLEDGEMENT_COMMENT) { ack = FALSE; if(data_type == XRDDEFAULT_HOSTCOMMENT_DATA) ack = temp_host->problem_has_been_acknowledged; else ack = temp_service->problem_has_been_acknowledged; if(ack == FALSE && persistent == FALSE) remove_comment = TRUE; } /* non-persistent comments don't last past restarts UNLESS they're acks (see above) */ else if(persistent == FALSE && (sigrestart == FALSE || entry_type == DOWNTIME_COMMENT)) remove_comment = TRUE; if(remove_comment == TRUE) delete_comment((data_type == XRDDEFAULT_HOSTCOMMENT_DATA) ? HOST_COMMENT : SERVICE_COMMENT, comment_id); /* free temp memory */ my_free(host_name); my_free(service_description); my_free(author); my_free(comment_data); /* reset defaults */ entry_type = USER_COMMENT; comment_id = 0; source = COMMENTSOURCE_INTERNAL; persistent = FALSE; entry_time = 0L; expires = FALSE; expire_time = 0L; break; case XRDDEFAULT_HOSTDOWNTIME_DATA: case XRDDEFAULT_SERVICEDOWNTIME_DATA: /* add the downtime */ if(data_type == XRDDEFAULT_HOSTDOWNTIME_DATA) add_host_downtime(host_name, entry_time, author, comment_data, start_time, flex_downtime_start, end_time, fixed, triggered_by, duration, downtime_id, is_in_effect, start_notification_sent); else add_service_downtime(host_name, service_description, entry_time, author, comment_data, start_time, flex_downtime_start, end_time, fixed, triggered_by, duration, downtime_id, is_in_effect, start_notification_sent); /* must register the downtime with Nagios so it can schedule it, add comments, etc. */ register_downtime((data_type == XRDDEFAULT_HOSTDOWNTIME_DATA) ? HOST_DOWNTIME : SERVICE_DOWNTIME, downtime_id); /* free temp memory */ my_free(host_name); my_free(service_description); my_free(author); my_free(comment_data); /* reset defaults */ downtime_id = 0; entry_time = 0L; start_time = 0L; flex_downtime_start = ( time_t)0; end_time = 0L; fixed = FALSE; triggered_by = 0; duration = 0L; break; default: break; } data_type = XRDDEFAULT_NO_DATA; } else if(data_type != XRDDEFAULT_NO_DATA) { /* slightly faster than strtok () */ var = input; if((val = strchr(input, '=')) == NULL) continue; val[0] = '\x0'; val++; found_directive = TRUE; switch(data_type) { case XRDDEFAULT_INFO_DATA: if(!strcmp(var, "created")) { creation_time = strtoul(val, NULL, 10); time(¤t_time); if(current_time - creation_time < retention_scheduling_horizon) scheduling_info_is_ok = TRUE; else scheduling_info_is_ok = FALSE; last_program_stop = creation_time; } else if(!strcmp(var, "version")) { /* initialize last version in case we're reading a pre-3.1.0 retention file */ if(last_program_version == NULL) last_program_version = (char *)strdup(val); } else if(!strcmp(var, "last_update_check")) last_update_check = strtoul(val, NULL, 10); else if(!strcmp(var, "update_available")) update_available = atoi(val); else if(!strcmp(var, "update_uid")) update_uid = strtoul(val, NULL, 10); else if(!strcmp(var, "last_version")) { if(last_program_version) my_free(last_program_version); last_program_version = (char *)strdup(val); } else if(!strcmp(var, "new_version")) new_program_version = (char *)strdup(val); break; case XRDDEFAULT_PROGRAMSTATUS_DATA: if(!strcmp(var, "modified_host_attributes")) { modified_host_process_attributes = strtoul(val, NULL, 10); /* mask out attributes we don't want to retain */ modified_host_process_attributes &= ~process_host_attribute_mask; } else if(!strcmp(var, "modified_service_attributes")) { modified_service_process_attributes = strtoul(val, NULL, 10); /* mask out attributes we don't want to retain */ modified_service_process_attributes &= ~process_service_attribute_mask; } if(use_retained_program_state == TRUE) { if(!strcmp(var, "enable_notifications")) { if(modified_host_process_attributes & MODATTR_NOTIFICATIONS_ENABLED) enable_notifications = (atoi(val) > 0) ? TRUE : FALSE; } else if(!strcmp(var, "active_service_checks_enabled")) { if(modified_service_process_attributes & MODATTR_ACTIVE_CHECKS_ENABLED) execute_service_checks = (atoi(val) > 0) ? TRUE : FALSE; } else if(!strcmp(var, "passive_service_checks_enabled")) { if(modified_service_process_attributes & MODATTR_PASSIVE_CHECKS_ENABLED) accept_passive_service_checks = (atoi(val) > 0) ? TRUE : FALSE; } else if(!strcmp(var, "active_host_checks_enabled")) { if(modified_host_process_attributes & MODATTR_ACTIVE_CHECKS_ENABLED) execute_host_checks = (atoi(val) > 0) ? TRUE : FALSE; } else if(!strcmp(var, "passive_host_checks_enabled")) { if(modified_host_process_attributes & MODATTR_PASSIVE_CHECKS_ENABLED) accept_passive_host_checks = (atoi(val) > 0) ? TRUE : FALSE; } else if(!strcmp(var, "enable_event_handlers")) { if(modified_host_process_attributes & MODATTR_EVENT_HANDLER_ENABLED) enable_event_handlers = (atoi(val) > 0) ? TRUE : FALSE; } else if(!strcmp(var, "obsess_over_services")) { if(modified_service_process_attributes & MODATTR_OBSESSIVE_HANDLER_ENABLED) obsess_over_services = (atoi(val) > 0) ? TRUE : FALSE; } else if(!strcmp(var, "obsess_over_hosts")) { if(modified_host_process_attributes & MODATTR_OBSESSIVE_HANDLER_ENABLED) obsess_over_hosts = (atoi(val) > 0) ? TRUE : FALSE; } else if(!strcmp(var, "check_service_freshness")) { if(modified_service_process_attributes & MODATTR_FRESHNESS_CHECKS_ENABLED) check_service_freshness = (atoi(val) > 0) ? TRUE : FALSE; } else if(!strcmp(var, "check_host_freshness")) { if(modified_host_process_attributes & MODATTR_FRESHNESS_CHECKS_ENABLED) check_host_freshness = (atoi(val) > 0) ? TRUE : FALSE; } else if(!strcmp(var, "enable_flap_detection")) { if(modified_host_process_attributes & MODATTR_FLAP_DETECTION_ENABLED) enable_flap_detection = (atoi(val) > 0) ? TRUE : FALSE; } else if(!strcmp(var, "process_performance_data")) { if(modified_host_process_attributes & MODATTR_PERFORMANCE_DATA_ENABLED) process_performance_data = (atoi(val) > 0) ? TRUE : FALSE; } else if(!strcmp(var, "global_host_event_handler")) { if(modified_host_process_attributes & MODATTR_EVENT_HANDLER_COMMAND) { /* make sure the check command still exists... */ tempval = (char *)strdup(val); temp_ptr = my_strtok(tempval, "!"); temp_command = find_command(temp_ptr); temp_ptr = (char *)strdup(val); my_free(tempval); if(temp_command != NULL && temp_ptr != NULL) { my_free(global_host_event_handler); global_host_event_handler = temp_ptr; } } } else if(!strcmp(var, "global_service_event_handler")) { if(modified_service_process_attributes & MODATTR_EVENT_HANDLER_COMMAND) { /* make sure the check command still exists... */ tempval = (char *)strdup(val); temp_ptr = my_strtok(tempval, "!"); temp_command = find_command(temp_ptr); temp_ptr = (char *)strdup(val); my_free(tempval); if(temp_command != NULL && temp_ptr != NULL) { my_free(global_service_event_handler); global_service_event_handler = temp_ptr; } } } else if(!strcmp(var, "next_comment_id")) next_comment_id = strtoul(val, NULL, 10); else if(!strcmp(var, "next_downtime_id")) next_downtime_id = strtoul(val, NULL, 10); else if(!strcmp(var, "next_event_id")) next_event_id = strtoul(val, NULL, 10); else if(!strcmp(var, "next_problem_id")) next_problem_id = strtoul(val, NULL, 10); else if(!strcmp(var, "next_notification_id")) next_notification_id = strtoul(val, NULL, 10); } break; case XRDDEFAULT_HOSTSTATUS_DATA: if(temp_host == NULL) { if(!strcmp(var, "host_name")) { host_name = (char *)strdup(val); temp_host = find_host(host_name); } } else { if(!strcmp(var, "modified_attributes")) { temp_host->modified_attributes = strtoul(val, NULL, 10); /* mask out attributes we don't want to retain */ temp_host->modified_attributes &= ~host_attribute_mask; /* break out */ break; } if(temp_host->retain_status_information == TRUE) { if(!strcmp(var, "has_been_checked")) temp_host->has_been_checked = (atoi(val) > 0) ? TRUE : FALSE; else if(!strcmp(var, "check_execution_time")) temp_host->execution_time = strtod(val, NULL); else if(!strcmp(var, "check_latency")) temp_host->latency = strtod(val, NULL); else if(!strcmp(var, "check_type")) temp_host->check_type = atoi(val); else if(!strcmp(var, "current_state")) temp_host->current_state = atoi(val); else if(!strcmp(var, "last_state")) temp_host->last_state = atoi(val); else if(!strcmp(var, "last_hard_state")) temp_host->last_hard_state = atoi(val); else if(!strcmp(var, "plugin_output")) { my_free(temp_host->plugin_output); temp_host->plugin_output = (char *)strdup(val); } else if(!strcmp(var, "long_plugin_output")) { my_free(temp_host->long_plugin_output); temp_host->long_plugin_output = (char *)strdup(val); } else if(!strcmp(var, "performance_data")) { my_free(temp_host->perf_data); temp_host->perf_data = (char *)strdup(val); } else if(!strcmp(var, "last_check")) temp_host->last_check = strtoul(val, NULL, 10); else if(!strcmp(var, "next_check")) { if(use_retained_scheduling_info == TRUE && scheduling_info_is_ok == TRUE) temp_host->next_check = strtoul(val, NULL, 10); } else if(!strcmp(var, "check_options")) { if(use_retained_scheduling_info == TRUE && scheduling_info_is_ok == TRUE) temp_host->check_options = atoi(val); } else if(!strcmp(var, "current_attempt")) temp_host->current_attempt = atoi(val); else if(!strcmp(var, "current_event_id")) temp_host->current_event_id = strtoul(val, NULL, 10); else if(!strcmp(var, "last_event_id")) temp_host->last_event_id = strtoul(val, NULL, 10); else if(!strcmp(var, "current_problem_id")) temp_host->current_problem_id = strtoul(val, NULL, 10); else if(!strcmp(var, "last_problem_id")) temp_host->last_problem_id = strtoul(val, NULL, 10); else if(!strcmp(var, "state_type")) temp_host->state_type = atoi(val); else if(!strcmp(var, "last_state_change")) temp_host->last_state_change = strtoul(val, NULL, 10); else if(!strcmp(var, "last_hard_state_change")) temp_host->last_hard_state_change = strtoul(val, NULL, 10); else if(!strcmp(var, "last_time_up")) temp_host->last_time_up = strtoul(val, NULL, 10); else if(!strcmp(var, "last_time_down")) temp_host->last_time_down = strtoul(val, NULL, 10); else if(!strcmp(var, "last_time_unreachable")) temp_host->last_time_unreachable = strtoul(val, NULL, 10); else if(!strcmp(var, "notified_on_down")) temp_host->notified_on |= (atoi(val) > 0 ? OPT_DOWN : 0); else if(!strcmp(var, "notified_on_unreachable")) temp_host->notified_on |= (atoi(val) > 0 ? OPT_UNREACHABLE : 0); else if(!strcmp(var, "last_notification")) temp_host->last_notification = strtoul(val, NULL, 10); else if(!strcmp(var, "current_notification_number")) temp_host->current_notification_number = atoi(val); else if(!strcmp(var, "current_notification_id")) temp_host->current_notification_id = strtoul(val, NULL, 10); else if(!strcmp(var, "is_flapping")) was_flapping = atoi(val); else if(!strcmp(var, "percent_state_change")) temp_host->percent_state_change = strtod(val, NULL); else if(!strcmp(var, "check_flapping_recovery_notification")) temp_host->check_flapping_recovery_notification = atoi(val); else if(!strcmp(var, "state_history")) { temp_ptr = val; for(x = 0; x < MAX_STATE_HISTORY_ENTRIES; x++) { if((ch = my_strsep(&temp_ptr, ",")) != NULL) temp_host->state_history[x] = atoi(ch); else break; } temp_host->state_history_index = 0; } else found_directive = FALSE; } if(temp_host->retain_nonstatus_information == TRUE) { /* null-op speeds up logic */ if(found_directive == TRUE); else if(!strcmp(var, "problem_has_been_acknowledged")) temp_host->problem_has_been_acknowledged = (atoi(val) > 0) ? TRUE : FALSE; else if(!strcmp(var, "acknowledgement_type")) temp_host->acknowledgement_type = atoi(val); else if(!strcmp(var, "notifications_enabled")) { if(temp_host->modified_attributes & MODATTR_NOTIFICATIONS_ENABLED) temp_host->notifications_enabled = (atoi(val) > 0) ? TRUE : FALSE; } else if(!strcmp(var, "active_checks_enabled")) { if(temp_host->modified_attributes & MODATTR_ACTIVE_CHECKS_ENABLED) temp_host->checks_enabled = (atoi(val) > 0) ? TRUE : FALSE; } else if(!strcmp(var, "passive_checks_enabled")) { if(temp_host->modified_attributes & MODATTR_PASSIVE_CHECKS_ENABLED) temp_host->accept_passive_checks = (atoi(val) > 0) ? TRUE : FALSE; } else if(!strcmp(var, "event_handler_enabled")) { if(temp_host->modified_attributes & MODATTR_EVENT_HANDLER_ENABLED) temp_host->event_handler_enabled = (atoi(val) > 0) ? TRUE : FALSE; } else if(!strcmp(var, "flap_detection_enabled")) { if(temp_host->modified_attributes & MODATTR_FLAP_DETECTION_ENABLED) temp_host->flap_detection_enabled = (atoi(val) > 0) ? TRUE : FALSE; } else if(!strcmp(var, "process_performance_data")) { if(temp_host->modified_attributes & MODATTR_PERFORMANCE_DATA_ENABLED) temp_host->process_performance_data = (atoi(val) > 0) ? TRUE : FALSE; } else if(!strcmp(var, "obsess_over_host") || !strcmp(var, "obsess")) { if(temp_host->modified_attributes & MODATTR_OBSESSIVE_HANDLER_ENABLED) temp_host->obsess = (atoi(val) > 0) ? TRUE : FALSE; } else if(!strcmp(var, "check_command")) { if(temp_host->modified_attributes & MODATTR_CHECK_COMMAND) { /* make sure the check command still exists... */ tempval = (char *)strdup(val); temp_ptr = my_strtok(tempval, "!"); temp_command = find_command(temp_ptr); temp_ptr = (char *)strdup(val); my_free(tempval); if(temp_command != NULL && temp_ptr != NULL) { my_free(temp_host->check_command); temp_host->check_command = temp_ptr; } else temp_host->modified_attributes -= MODATTR_CHECK_COMMAND; } } else if(!strcmp(var, "check_period")) { if(temp_host->modified_attributes & MODATTR_CHECK_TIMEPERIOD) { /* make sure the timeperiod still exists... */ temp_timeperiod = find_timeperiod(val); temp_ptr = (char *)strdup(val); if(temp_timeperiod != NULL && temp_ptr != NULL) { my_free(temp_host->check_period); temp_host->check_period = temp_ptr; } else temp_host->modified_attributes -= MODATTR_CHECK_TIMEPERIOD; } } else if(!strcmp(var, "notification_period")) { if(temp_host->modified_attributes & MODATTR_NOTIFICATION_TIMEPERIOD) { /* make sure the timeperiod still exists... */ temp_timeperiod = find_timeperiod(val); temp_ptr = (char *)strdup(val); if(temp_timeperiod != NULL && temp_ptr != NULL) { my_free(temp_host->notification_period); temp_host->notification_period = temp_ptr; } else temp_host->modified_attributes -= MODATTR_NOTIFICATION_TIMEPERIOD; } } else if(!strcmp(var, "event_handler")) { if(temp_host->modified_attributes & MODATTR_EVENT_HANDLER_COMMAND) { /* make sure the check command still exists... */ tempval = (char *)strdup(val); temp_ptr = my_strtok(tempval, "!"); temp_command = find_command(temp_ptr); temp_ptr = (char *)strdup(val); my_free(tempval); if(temp_command != NULL && temp_ptr != NULL) { my_free(temp_host->event_handler); temp_host->event_handler = temp_ptr; } else temp_host->modified_attributes -= MODATTR_EVENT_HANDLER_COMMAND; } } else if(!strcmp(var, "check_interval")) { if(temp_host->modified_attributes & MODATTR_NORMAL_CHECK_INTERVAL && strtod(val, NULL) >= 0) temp_host->check_interval = strtod(val, NULL); } else if(!strcmp(var, "retry_interval")) { if(temp_host->modified_attributes & MODATTR_RETRY_CHECK_INTERVAL && strtod(val, NULL) >= 0) temp_host->retry_interval = strtod(val, NULL); } else if(!strcmp(var, "max_attempts")) { if(temp_host->modified_attributes & MODATTR_MAX_CHECK_ATTEMPTS && atoi(val) >= 1) { temp_host->max_attempts = atoi(val); /* adjust current attempt number if in a hard state */ if(temp_host->state_type == HARD_STATE && temp_host->current_state != HOST_UP && temp_host->current_attempt > 1) temp_host->current_attempt = temp_host->max_attempts; } } /* custom variables */ else if(var[0] == '_') { if(temp_host->modified_attributes & MODATTR_CUSTOM_VARIABLE) { /* get the variable name */ if((customvarname = (char *)strdup(var + 1))) { for(temp_customvariablesmember = temp_host->custom_variables; temp_customvariablesmember != NULL; temp_customvariablesmember = temp_customvariablesmember->next) { if(!strcmp(customvarname, temp_customvariablesmember->variable_name)) { if((x = atoi(val)) > 0 && strlen(val) > 3) { my_free(temp_customvariablesmember->variable_value); temp_customvariablesmember->variable_value = (char *)strdup(val + 2); temp_customvariablesmember->has_been_modified = (x > 0) ? TRUE : FALSE; } break; } } /* free memory */ my_free(customvarname); } } } } } break; case XRDDEFAULT_SERVICESTATUS_DATA: if(temp_service == NULL) { if(!strcmp(var, "host_name")) { host_name = (char *)strdup(val); /*temp_service=find_service(host_name,service_description);*/ /* break out */ break; } else if(!strcmp(var, "service_description")) { service_description = (char *)strdup(val); temp_service = find_service(host_name, service_description); /* break out */ break; } } else { if(!strcmp(var, "modified_attributes")) { temp_service->modified_attributes = strtoul(val, NULL, 10); /* mask out attributes we don't want to retain */ temp_service->modified_attributes &= ~service_attribute_mask; } if(temp_service->retain_status_information == TRUE) { if(!strcmp(var, "has_been_checked")) temp_service->has_been_checked = (atoi(val) > 0) ? TRUE : FALSE; else if(!strcmp(var, "check_execution_time")) temp_service->execution_time = strtod(val, NULL); else if(!strcmp(var, "check_latency")) temp_service->latency = strtod(val, NULL); else if(!strcmp(var, "check_type")) temp_service->check_type = atoi(val); else if(!strcmp(var, "current_state")) temp_service->current_state = atoi(val); else if(!strcmp(var, "last_state")) temp_service->last_state = atoi(val); else if(!strcmp(var, "last_hard_state")) temp_service->last_hard_state = atoi(val); else if(!strcmp(var, "current_attempt")) temp_service->current_attempt = atoi(val); else if(!strcmp(var, "current_event_id")) temp_service->current_event_id = strtoul(val, NULL, 10); else if(!strcmp(var, "last_event_id")) temp_service->last_event_id = strtoul(val, NULL, 10); else if(!strcmp(var, "current_problem_id")) temp_service->current_problem_id = strtoul(val, NULL, 10); else if(!strcmp(var, "last_problem_id")) temp_service->last_problem_id = strtoul(val, NULL, 10); else if(!strcmp(var, "state_type")) temp_service->state_type = atoi(val); else if(!strcmp(var, "last_state_change")) temp_service->last_state_change = strtoul(val, NULL, 10); else if(!strcmp(var, "last_hard_state_change")) temp_service->last_hard_state_change = strtoul(val, NULL, 10); else if(!strcmp(var, "last_time_ok")) temp_service->last_time_ok = strtoul(val, NULL, 10); else if(!strcmp(var, "last_time_warning")) temp_service->last_time_warning = strtoul(val, NULL, 10); else if(!strcmp(var, "last_time_unknown")) temp_service->last_time_unknown = strtoul(val, NULL, 10); else if(!strcmp(var, "last_time_critical")) temp_service->last_time_critical = strtoul(val, NULL, 10); else if(!strcmp(var, "plugin_output")) { my_free(temp_service->plugin_output); temp_service->plugin_output = (char *)strdup(val); } else if(!strcmp(var, "long_plugin_output")) { my_free(temp_service->long_plugin_output); temp_service->long_plugin_output = (char *)strdup(val); } else if(!strcmp(var, "performance_data")) { my_free(temp_service->perf_data); temp_service->perf_data = (char *)strdup(val); } else if(!strcmp(var, "last_check")) temp_service->last_check = strtoul(val, NULL, 10); else if(!strcmp(var, "next_check")) { if(use_retained_scheduling_info == TRUE && scheduling_info_is_ok == TRUE) temp_service->next_check = strtoul(val, NULL, 10); } else if(!strcmp(var, "check_options")) { if(use_retained_scheduling_info == TRUE && scheduling_info_is_ok == TRUE) temp_service->check_options = atoi(val); } else if(!strcmp(var, "notified_on_unknown")) temp_service->notified_on |= ((atoi(val) > 0) ? OPT_UNKNOWN : 0); else if(!strcmp(var, "notified_on_warning")) temp_service->notified_on |= ((atoi(val) > 0) ? OPT_WARNING : 0); else if(!strcmp(var, "notified_on_critical")) temp_service->notified_on |= ((atoi(val) > 0) ? OPT_CRITICAL : 0); else if(!strcmp(var, "current_notification_number")) temp_service->current_notification_number = atoi(val); else if(!strcmp(var, "current_notification_id")) temp_service->current_notification_id = strtoul(val, NULL, 10); else if(!strcmp(var, "last_notification")) temp_service->last_notification = strtoul(val, NULL, 10); else if(!strcmp(var, "is_flapping")) was_flapping = atoi(val); else if(!strcmp(var, "percent_state_change")) temp_service->percent_state_change = strtod(val, NULL); else if(!strcmp(var, "check_flapping_recovery_notification")) temp_service->check_flapping_recovery_notification = atoi(val); else if(!strcmp(var, "state_history")) { temp_ptr = val; for(x = 0; x < MAX_STATE_HISTORY_ENTRIES; x++) { if((ch = my_strsep(&temp_ptr, ",")) != NULL) temp_service->state_history[x] = atoi(ch); else break; } temp_service->state_history_index = 0; } else found_directive = FALSE; } if(temp_service->retain_nonstatus_information == TRUE) { /* null-op speeds up logic */ if(found_directive == TRUE); else if(!strcmp(var, "problem_has_been_acknowledged")) temp_service->problem_has_been_acknowledged = (atoi(val) > 0) ? TRUE : FALSE; else if(!strcmp(var, "acknowledgement_type")) temp_service->acknowledgement_type = atoi(val); else if(!strcmp(var, "notifications_enabled")) { if(temp_service->modified_attributes & MODATTR_NOTIFICATIONS_ENABLED) temp_service->notifications_enabled = (atoi(val) > 0) ? TRUE : FALSE; } else if(!strcmp(var, "active_checks_enabled")) { if(temp_service->modified_attributes & MODATTR_ACTIVE_CHECKS_ENABLED) temp_service->checks_enabled = (atoi(val) > 0) ? TRUE : FALSE; } else if(!strcmp(var, "passive_checks_enabled")) { if(temp_service->modified_attributes & MODATTR_PASSIVE_CHECKS_ENABLED) temp_service->accept_passive_checks = (atoi(val) > 0) ? TRUE : FALSE; } else if(!strcmp(var, "event_handler_enabled")) { if(temp_service->modified_attributes & MODATTR_EVENT_HANDLER_ENABLED) temp_service->event_handler_enabled = (atoi(val) > 0) ? TRUE : FALSE; } else if(!strcmp(var, "flap_detection_enabled")) { if(temp_service->modified_attributes & MODATTR_FLAP_DETECTION_ENABLED) temp_service->flap_detection_enabled = (atoi(val) > 0) ? TRUE : FALSE; } else if(!strcmp(var, "process_performance_data")) { if(temp_service->modified_attributes & MODATTR_PERFORMANCE_DATA_ENABLED) temp_service->process_performance_data = (atoi(val) > 0) ? TRUE : FALSE; } else if(!strcmp(var, "obsess_over_service") || !strcmp(var, "obsess")) { if(temp_service->modified_attributes & MODATTR_OBSESSIVE_HANDLER_ENABLED) temp_service->obsess = (atoi(val) > 0) ? TRUE : FALSE; } else if(!strcmp(var, "check_command")) { if(temp_service->modified_attributes & MODATTR_CHECK_COMMAND) { /* make sure the check command still exists... */ tempval = (char *)strdup(val); temp_ptr = my_strtok(tempval, "!"); temp_command = find_command(temp_ptr); temp_ptr = (char *)strdup(val); my_free(tempval); if(temp_command != NULL && temp_ptr != NULL) { my_free(temp_service->check_command); temp_service->check_command = temp_ptr; } else temp_service->modified_attributes -= MODATTR_CHECK_COMMAND; } } else if(!strcmp(var, "check_period")) { if(temp_service->modified_attributes & MODATTR_CHECK_TIMEPERIOD) { /* make sure the timeperiod still exists... */ temp_timeperiod = find_timeperiod(val); temp_ptr = (char *)strdup(val); if(temp_timeperiod != NULL && temp_ptr != NULL) { my_free(temp_service->check_period); temp_service->check_period = temp_ptr; } else temp_service->modified_attributes -= MODATTR_CHECK_TIMEPERIOD; } } else if(!strcmp(var, "notification_period")) { if(temp_service->modified_attributes & MODATTR_NOTIFICATION_TIMEPERIOD) { /* make sure the timeperiod still exists... */ temp_timeperiod = find_timeperiod(val); temp_ptr = (char *)strdup(val); if(temp_timeperiod != NULL && temp_ptr != NULL) { my_free(temp_service->notification_period); temp_service->notification_period = temp_ptr; } else temp_service->modified_attributes -= MODATTR_NOTIFICATION_TIMEPERIOD; } } else if(!strcmp(var, "event_handler")) { if(temp_service->modified_attributes & MODATTR_EVENT_HANDLER_COMMAND) { /* make sure the check command still exists... */ tempval = (char *)strdup(val); temp_ptr = my_strtok(tempval, "!"); temp_command = find_command(temp_ptr); temp_ptr = (char *)strdup(val); my_free(tempval); if(temp_command != NULL && temp_ptr != NULL) { my_free(temp_service->event_handler); temp_service->event_handler = temp_ptr; } else temp_service->modified_attributes -= MODATTR_EVENT_HANDLER_COMMAND; } } else if(!strcmp(var, "check_interval")) { if(temp_service->modified_attributes & MODATTR_NORMAL_CHECK_INTERVAL && strtod(val, NULL) >= 0) temp_service->check_interval = strtod(val, NULL); } else if(!strcmp(var, "retry_interval")) { if(temp_service->modified_attributes & MODATTR_RETRY_CHECK_INTERVAL && strtod(val, NULL) >= 0) temp_service->retry_interval = strtod(val, NULL); } else if(!strcmp(var, "max_attempts")) { if(temp_service->modified_attributes & MODATTR_MAX_CHECK_ATTEMPTS && atoi(val) >= 1) { temp_service->max_attempts = atoi(val); /* adjust current attempt number if in a hard state */ if(temp_service->state_type == HARD_STATE && temp_service->current_state != STATE_OK && temp_service->current_attempt > 1) temp_service->current_attempt = temp_service->max_attempts; } } /* custom variables */ else if(var[0] == '_') { if(temp_service->modified_attributes & MODATTR_CUSTOM_VARIABLE) { /* get the variable name */ if((customvarname = (char *)strdup(var + 1))) { for(temp_customvariablesmember = temp_service->custom_variables; temp_customvariablesmember != NULL; temp_customvariablesmember = temp_customvariablesmember->next) { if(!strcmp(customvarname, temp_customvariablesmember->variable_name)) { if((x = atoi(val)) > 0 && strlen(val) > 3) { my_free(temp_customvariablesmember->variable_value); temp_customvariablesmember->variable_value = (char *)strdup(val + 2); temp_customvariablesmember->has_been_modified = (x > 0) ? TRUE : FALSE; } break; } } /* free memory */ my_free(customvarname); } } } } } break; case XRDDEFAULT_CONTACTSTATUS_DATA: if(temp_contact == NULL) { if(!strcmp(var, "contact_name")) { contact_name = (char *)strdup(val); temp_contact = find_contact(contact_name); } } else { if(!strcmp(var, "modified_attributes")) { temp_contact->modified_attributes = strtoul(val, NULL, 10); /* mask out attributes we don't want to retain */ temp_contact->modified_attributes &= ~contact_attribute_mask; } else if(!strcmp(var, "modified_host_attributes")) { temp_contact->modified_host_attributes = strtoul(val, NULL, 10); /* mask out attributes we don't want to retain */ temp_contact->modified_host_attributes &= ~contact_host_attribute_mask; } else if(!strcmp(var, "modified_service_attributes")) { temp_contact->modified_service_attributes = strtoul(val, NULL, 10); /* mask out attributes we don't want to retain */ temp_contact->modified_service_attributes &= ~contact_service_attribute_mask; } else if(temp_contact->retain_status_information == TRUE) { if(!strcmp(var, "last_host_notification")) temp_contact->last_host_notification = strtoul(val, NULL, 10); else if(!strcmp(var, "last_service_notification")) temp_contact->last_service_notification = strtoul(val, NULL, 10); else found_directive = FALSE; } if(temp_contact->retain_nonstatus_information == TRUE) { /* null-op speeds up logic */ if(found_directive == TRUE); else if(!strcmp(var, "host_notification_period")) { if(temp_contact->modified_host_attributes & MODATTR_NOTIFICATION_TIMEPERIOD) { /* make sure the timeperiod still exists... */ temp_timeperiod = find_timeperiod(val); temp_ptr = (char *)strdup(val); if(temp_timeperiod != NULL && temp_ptr != NULL) { my_free(temp_contact->host_notification_period); temp_contact->host_notification_period = temp_ptr; } else temp_contact->modified_host_attributes -= MODATTR_NOTIFICATION_TIMEPERIOD; } } else if(!strcmp(var, "service_notification_period")) { if(temp_contact->modified_service_attributes & MODATTR_NOTIFICATION_TIMEPERIOD) { /* make sure the timeperiod still exists... */ temp_timeperiod = find_timeperiod(val); temp_ptr = (char *)strdup(val); if(temp_timeperiod != NULL && temp_ptr != NULL) { my_free(temp_contact->service_notification_period); temp_contact->service_notification_period = temp_ptr; } else temp_contact->modified_service_attributes -= MODATTR_NOTIFICATION_TIMEPERIOD; } } else if(!strcmp(var, "host_notifications_enabled")) { if(temp_contact->modified_host_attributes & MODATTR_NOTIFICATIONS_ENABLED) temp_contact->host_notifications_enabled = (atoi(val) > 0) ? TRUE : FALSE; } else if(!strcmp(var, "service_notifications_enabled")) { if(temp_contact->modified_service_attributes & MODATTR_NOTIFICATIONS_ENABLED) temp_contact->service_notifications_enabled = (atoi(val) > 0) ? TRUE : FALSE; } /* custom variables */ else if(var[0] == '_') { if(temp_contact->modified_attributes & MODATTR_CUSTOM_VARIABLE) { /* get the variable name */ if((customvarname = (char *)strdup(var + 1))) { for(temp_customvariablesmember = temp_contact->custom_variables; temp_customvariablesmember != NULL; temp_customvariablesmember = temp_customvariablesmember->next) { if(!strcmp(customvarname, temp_customvariablesmember->variable_name)) { if((x = atoi(val)) > 0 && strlen(val) > 3) { my_free(temp_customvariablesmember->variable_value); temp_customvariablesmember->variable_value = (char *)strdup(val + 2); temp_customvariablesmember->has_been_modified = (x > 0) ? TRUE : FALSE; } break; } } /* free memory */ my_free(customvarname); } } } } } break; case XRDDEFAULT_HOSTCOMMENT_DATA: case XRDDEFAULT_SERVICECOMMENT_DATA: if(!strcmp(var, "host_name")) host_name = (char *)strdup(val); else if(!strcmp(var, "service_description")) service_description = (char *)strdup(val); else if(!strcmp(var, "entry_type")) entry_type = atoi(val); else if(!strcmp(var, "comment_id")) comment_id = strtoul(val, NULL, 10); else if(!strcmp(var, "source")) source = atoi(val); else if(!strcmp(var, "persistent")) persistent = (atoi(val) > 0) ? TRUE : FALSE; else if(!strcmp(var, "entry_time")) entry_time = strtoul(val, NULL, 10); else if(!strcmp(var, "expires")) expires = (atoi(val) > 0) ? TRUE : FALSE; else if(!strcmp(var, "expire_time")) expire_time = strtoul(val, NULL, 10); else if(!strcmp(var, "author")) author = (char *)strdup(val); else if(!strcmp(var, "comment_data")) comment_data = (char *)strdup(val); break; case XRDDEFAULT_HOSTDOWNTIME_DATA: case XRDDEFAULT_SERVICEDOWNTIME_DATA: if(!strcmp(var, "host_name")) host_name = (char *)strdup(val); else if(!strcmp(var, "service_description")) service_description = (char *)strdup(val); else if(!strcmp(var, "downtime_id")) downtime_id = strtoul(val, NULL, 10); else if(!strcmp(var, "comment_id")) comment_id = strtoul(val, NULL, 10); else if(!strcmp(var, "entry_time")) entry_time = strtoul(val, NULL, 10); else if(!strcmp(var, "start_time")) start_time = strtoul(val, NULL, 10); else if(!strcmp(var, "flex_downtime_start")) flex_downtime_start = strtoul(val, NULL, 10); else if(!strcmp(var, "end_time")) end_time = strtoul(val, NULL, 10); else if(!strcmp(var, "fixed")) fixed = (atoi(val) > 0) ? TRUE : FALSE; else if(!strcmp(var, "triggered_by")) triggered_by = strtoul(val, NULL, 10); else if(!strcmp(var, "is_in_effect")) is_in_effect = (atoi(val) > 0) ? TRUE : FALSE; else if(!strcmp(var, "start_notification_sent")) start_notification_sent = (atoi(val) > 0) ? TRUE : FALSE; else if(!strcmp(var, "duration")) duration = strtoul(val, NULL, 10); else if(!strcmp(var, "author")) author = (char *)strdup(val); else if(!strcmp(var, "comment")) comment_data = (char *)strdup(val); break; default: break; } } } /* free memory and close the file */ my_free(inputbuf); mmap_fclose(thefile); if(sort_downtime() != OK) return ERROR; if(sort_comments() != OK) return ERROR; if(test_scheduling == TRUE) gettimeofday(&tv[1], NULL); if(test_scheduling == TRUE) { runtime[0] = (double)((double)(tv[1].tv_sec - tv[0].tv_sec) + (double)((tv[1].tv_usec - tv[0].tv_usec) / 1000.0) / 1000.0); runtime[1] = (double)((double)(tv[1].tv_sec - tv[0].tv_sec) + (double)((tv[1].tv_usec - tv[0].tv_usec) / 1000.0) / 1000.0); printf("RETENTION DATA TIMES\n"); printf("----------------------------------\n"); printf("Read and Process: %.6lf sec\n", runtime[0]); printf(" ============\n"); printf("TOTAL: %.6lf sec\n", runtime[1]); printf("\n\n"); } return OK; }