/*****************************************************************************
 *
 * XSDDEFAULT.C - Default external status data input routines for Icinga
 *
 * Copyright (c) 1999-2009 Ethan Galstad (egalstad@nagios.org)
 * Copyright (c) 2009-2013 Nagios Core Development Team and Community Contributors
 * Copyright (c) 2009-2015 Icinga Development Team (http://www.icinga.org)
 *
 * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 *****************************************************************************/


/*********** COMMON HEADER FILES ***********/

#include "../include/config.h"
#include "../include/common.h"
#include "../include/locations.h"
#include "../include/statusdata.h"
#include "../include/comments.h"
#include "../include/downtime.h"
#include "../include/macros.h"
#include "../include/skiplist.h"

#ifdef NSCORE
#include "../include/icinga.h"
#endif

#ifdef NSCGI
#include "../include/cgiutils.h"
#endif


/**** IMPLEMENTATION SPECIFIC HEADER FILES ****/
#include "xsddefault.h"



#ifdef NSCGI
time_t program_start;
int daemon_mode;
time_t last_command_check;
time_t last_log_rotation;
time_t status_file_creation_time;
char *status_file_icinga_version;
int enable_notifications;
time_t disable_notifications_expire_time;
int execute_service_checks;
int accept_passive_service_checks;
int execute_host_checks;
int accept_passive_host_checks;
int enable_event_handlers;
int obsess_over_services;
int obsess_over_hosts;
int check_service_freshness;
int check_host_freshness;
int enable_flap_detection;
int enable_failure_prediction;
int process_performance_data;
int nagios_pid;
int buffer_stats[1][3];
int program_stats[MAX_CHECK_STATS_TYPES][3];
#endif

#ifdef NSCORE
extern time_t program_start;
extern int nagios_pid;
extern int daemon_mode;
extern time_t last_command_check;
extern time_t last_log_rotation;
extern int enable_notifications;
extern time_t disable_notifications_expire_time;
extern int execute_service_checks;
extern int accept_passive_service_checks;
extern int execute_host_checks;
extern int accept_passive_host_checks;
extern int enable_event_handlers;
extern int obsess_over_services;
extern int obsess_over_hosts;
extern int check_service_freshness;
extern int check_host_freshness;
extern int enable_flap_detection;
extern int enable_failure_prediction;
extern int process_performance_data;
extern int aggregate_status_updates;
extern int check_external_commands;

extern int external_command_buffer_slots;
extern circular_buffer external_command_buffer;

extern host *host_list;
extern service *service_list;
extern contact *contact_list;
extern comment *comment_list;
extern scheduled_downtime *scheduled_downtime_list;

extern skiplist *object_skiplists[NUM_OBJECT_SKIPLISTS];

extern unsigned long  next_comment_id;
extern unsigned long  next_downtime_id;
extern unsigned long  next_event_id;
extern unsigned long  next_problem_id;
extern unsigned long  next_notification_id;

extern unsigned long  modified_host_process_attributes;
extern unsigned long  modified_service_process_attributes;
extern char           *global_host_event_handler;
extern char           *global_service_event_handler;

extern check_stats    check_statistics[MAX_CHECK_STATS_TYPES];
#endif


char *xsddefault_status_log = NULL;
char *xsddefault_temp_file = NULL;



/******************************************************************/
/***************** COMMON CONFIG INITIALIZATION  ******************/
/******************************************************************/

/* grab configuration information */
int xsddefault_grab_config_info(char *config_file) {
	char *input = NULL;
	mmapfile *thefile;
#ifdef NSCORE
	icinga_macros *mac;
#endif


	/*** CORE PASSES IN MAIN CONFIG FILE, CGIS PASS IN CGI CONFIG FILE! ***/

	/* open the config file for reading */
	if ((thefile = mmap_fopen(config_file)) == NULL)
		return ERROR;

	/* read in all lines from the main config file */
	while (1) {

		/* free memory */
		my_free(input);

		/* read the next line */
		if ((input = mmap_fgets_multiline(thefile)) == NULL)
			break;

		strip(input);

		/* skip blank lines and comments */
		if (input[0] == '#' || input[0] == '\x0')
			continue;

		/* core reads variables directly from the main config file */
		xsddefault_grab_config_directives(input);
	}

	/* free memory and close the file */
	my_free(input);
	mmap_fclose(thefile);

	/* initialize locations if necessary */
	if (xsddefault_status_log == NULL)
		xsddefault_status_log = (char *)strdup(DEFAULT_STATUS_FILE);
	if (xsddefault_temp_file == NULL)
		xsddefault_temp_file = (char *)strdup(DEFAULT_TEMP_FILE);

	/* make sure we have what we need */
	if (xsddefault_status_log == NULL)
		return ERROR;
	if (xsddefault_temp_file == NULL)
		return ERROR;

#ifdef NSCORE
	mac = get_global_macros();

	/* save the status file macro */
	my_free(mac->x[MACRO_STATUSDATAFILE]);
	if ((mac->x[MACRO_STATUSDATAFILE] = (char *)strdup(xsddefault_status_log)))
		strip(mac->x[MACRO_STATUSDATAFILE]);
#endif

	return OK;
}


/* processes a single directive */
int xsddefault_grab_config_directives(char *input) {
	char *temp_ptr = NULL;
	char *varname = NULL;
	char *varvalue = NULL;

	/* get the variable name */
	if ((temp_ptr = my_strtok(input, "=")) == NULL)
		return ERROR;
	if ((varname = (char *)strdup(temp_ptr)) == NULL)
		return ERROR;

	/* get the variable value */
	if ((temp_ptr = my_strtok(NULL, "\n")) == NULL) {
		my_free(varname);
		return ERROR;
	}
	if ((varvalue = (char *)strdup(temp_ptr)) == NULL) {
		my_free(varname);
		return ERROR;
	}

	/* status log definition */
	if (!strcmp(varname, "status_file") || !strcmp(varname, "xsddefault_status_log"))
		xsddefault_status_log = (char *)strdup(temp_ptr);

	/* temp file definition */
	else if (!strcmp(varname, "temp_file"))
		xsddefault_temp_file = (char *)strdup(temp_ptr);

	/* free memory */
	my_free(varname);
	my_free(varvalue);

	return OK;
}



#ifdef NSCORE

/******************************************************************/
/********************* INIT/CLEANUP FUNCTIONS *********************/
/******************************************************************/


/* initialize status data */
int xsddefault_initialize_status_data(char *config_file) {
	int result;

	/* grab configuration data */
	result = xsddefault_grab_config_info(config_file);
	if (result == ERROR)
		return ERROR;

	/* delete the old status log (it might not exist) */
	if (xsddefault_status_log)
		unlink(xsddefault_status_log);

	return OK;
}


/* cleanup status data before terminating */
int xsddefault_cleanup_status_data(char *config_file, int delete_status_data) {

	/* delete the status log */
	if (delete_status_data == TRUE && xsddefault_status_log) {
		if (unlink(xsddefault_status_log))
			return ERROR;
	}

	/* free memory */
	my_free(xsddefault_status_log);
	my_free(xsddefault_temp_file);

	return OK;
}


/******************************************************************/
/****************** STATUS DATA OUTPUT FUNCTIONS ******************/
/******************************************************************/

/* write all status data to file */
int xsddefault_save_status_data(void) {
	char *temp_file = NULL;
	customvariablesmember *temp_customvariablesmember = NULL;
	host *temp_host = NULL;
	service *temp_service = NULL;
	contact *temp_contact = NULL;
	comment *temp_comment = NULL;
	scheduled_downtime *temp_downtime = NULL;
	time_t current_time;
	int fd = 0;
	FILE *fp = NULL;
	int used_external_command_buffer_slots = 0;
	int high_external_command_buffer_slots = 0;
	int result = OK;

	log_debug_info(DEBUGL_FUNCTIONS, 0, "save_status_data()\n");

	/* if this is set to /dev/null, skip it */
	if (!xsddefault_status_log || !strcmp(xsddefault_status_log, "/dev/null"))
		return OK;

	/* open a safe temp file for output */
	if (xsddefault_temp_file == NULL)
		return ERROR;
	asprintf(&temp_file, "%sXXXXXX", xsddefault_temp_file);
	if (temp_file == NULL)
		return ERROR;

	log_debug_info(DEBUGL_STATUSDATA, 2, "Writing status data to temp file '%s'\n", temp_file);

	if ((fd = mkstemp(temp_file)) == -1) {

		/* log an error */
		logit(NSLOG_RUNTIME_ERROR, TRUE, "Error: Unable to create temp file '%s' for writing status data: %s\n", temp_file, strerror(errno));

		/* free memory */
		my_free(temp_file);

		return ERROR;
	}
	fp = (FILE *)fdopen(fd, "w");
	if (fp == NULL) {

		close(fd);
		unlink(temp_file);

		/* log an error */
		logit(NSLOG_RUNTIME_ERROR, TRUE, "Error: Unable to open temp file '%s' for writing status data: %s\n", temp_file, strerror(errno));

		/* free memory */
		my_free(temp_file);

		return ERROR;
	}

	/* get number of items in the command buffer */
	if (check_external_commands == TRUE) {
		pthread_mutex_lock(&external_command_buffer.buffer_lock);
		used_external_command_buffer_slots = external_command_buffer.items;
		high_external_command_buffer_slots = external_command_buffer.high;
		pthread_mutex_unlock(&external_command_buffer.buffer_lock);
	} else {
		used_external_command_buffer_slots = 0;
		high_external_command_buffer_slots = 0;
	}

	/* generate check statistics */
	generate_check_stats();

	/* write version info to status file */
	fprintf(fp, "########################################\n");
	fprintf(fp, "#          %s STATUS FILE\n", PROGRAM_NAME_UC);
	fprintf(fp, "#\n");
	fprintf(fp, "# THIS FILE IS AUTOMATICALLY GENERATED\n");
	fprintf(fp, "# BY %s.  DO NOT MODIFY THIS FILE!\n", PROGRAM_NAME_UC);
	fprintf(fp, "########################################\n\n");

	time(&current_time);

	/* write file info */
	fprintf(fp, "info {\n");
	fprintf(fp, "\tcreated=%lu\n", current_time);
	fprintf(fp, "\tversion=%s\n", PROGRAM_VERSION);
	fprintf(fp, "\t}\n\n");

	/* save program status data */
	fprintf(fp, "programstatus {\n");
	fprintf(fp, "\tmodified_host_attributes=%lu\n", modified_host_process_attributes);
	fprintf(fp, "\tmodified_service_attributes=%lu\n", modified_service_process_attributes);
	fprintf(fp, "\ticinga_pid=%d\n", nagios_pid);
	fprintf(fp, "\tdaemon_mode=%d\n", daemon_mode);
	fprintf(fp, "\tprogram_start=%lu\n", program_start);
	fprintf(fp, "\tlast_command_check=%lu\n", last_command_check);
	fprintf(fp, "\tlast_log_rotation=%lu\n", last_log_rotation);
	fprintf(fp, "\tenable_notifications=%d\n", enable_notifications);
	fprintf(fp, "\tdisable_notifications_expire_time=%lu\n", disable_notifications_expire_time);
	fprintf(fp, "\tactive_service_checks_enabled=%d\n", execute_service_checks);
	fprintf(fp, "\tpassive_service_checks_enabled=%d\n", accept_passive_service_checks);
	fprintf(fp, "\tactive_host_checks_enabled=%d\n", execute_host_checks);
	fprintf(fp, "\tpassive_host_checks_enabled=%d\n", accept_passive_host_checks);
	fprintf(fp, "\tenable_event_handlers=%d\n", enable_event_handlers);
	fprintf(fp, "\tobsess_over_services=%d\n", obsess_over_services);
	fprintf(fp, "\tobsess_over_hosts=%d\n", obsess_over_hosts);
	fprintf(fp, "\tcheck_service_freshness=%d\n", check_service_freshness);
	fprintf(fp, "\tcheck_host_freshness=%d\n", check_host_freshness);
	fprintf(fp, "\tenable_flap_detection=%d\n", enable_flap_detection);
	fprintf(fp, "\tenable_failure_prediction=%d\n", enable_failure_prediction);
	fprintf(fp, "\tprocess_performance_data=%d\n", process_performance_data);
	fprintf(fp, "\tglobal_host_event_handler=%s\n", (global_host_event_handler == NULL) ? "" : global_host_event_handler);
	fprintf(fp, "\tglobal_service_event_handler=%s\n", (global_service_event_handler == NULL) ? "" : global_service_event_handler);
	fprintf(fp, "\tnext_comment_id=%lu\n", next_comment_id);
	fprintf(fp, "\tnext_downtime_id=%lu\n", next_downtime_id);
	fprintf(fp, "\tnext_event_id=%lu\n", next_event_id);
	fprintf(fp, "\tnext_problem_id=%lu\n", next_problem_id);
	fprintf(fp, "\tnext_notification_id=%lu\n", next_notification_id);
	fprintf(fp, "\ttotal_external_command_buffer_slots=%d\n", external_command_buffer_slots);
	fprintf(fp, "\tused_external_command_buffer_slots=%d\n", used_external_command_buffer_slots);
	fprintf(fp, "\thigh_external_command_buffer_slots=%d\n", high_external_command_buffer_slots);
	fprintf(fp, "\tactive_scheduled_host_check_stats=%d,%d,%d\n", check_statistics[ACTIVE_SCHEDULED_HOST_CHECK_STATS].minute_stats[0], check_statistics[ACTIVE_SCHEDULED_HOST_CHECK_STATS].minute_stats[1], check_statistics[ACTIVE_SCHEDULED_HOST_CHECK_STATS].minute_stats[2]);
	fprintf(fp, "\tactive_ondemand_host_check_stats=%d,%d,%d\n", check_statistics[ACTIVE_ONDEMAND_HOST_CHECK_STATS].minute_stats[0], check_statistics[ACTIVE_ONDEMAND_HOST_CHECK_STATS].minute_stats[1], check_statistics[ACTIVE_ONDEMAND_HOST_CHECK_STATS].minute_stats[2]);
	fprintf(fp, "\tpassive_host_check_stats=%d,%d,%d\n", check_statistics[PASSIVE_HOST_CHECK_STATS].minute_stats[0], check_statistics[PASSIVE_HOST_CHECK_STATS].minute_stats[1], check_statistics[PASSIVE_HOST_CHECK_STATS].minute_stats[2]);
	fprintf(fp, "\tactive_scheduled_service_check_stats=%d,%d,%d\n", check_statistics[ACTIVE_SCHEDULED_SERVICE_CHECK_STATS].minute_stats[0], check_statistics[ACTIVE_SCHEDULED_SERVICE_CHECK_STATS].minute_stats[1], check_statistics[ACTIVE_SCHEDULED_SERVICE_CHECK_STATS].minute_stats[2]);
	fprintf(fp, "\tactive_ondemand_service_check_stats=%d,%d,%d\n", check_statistics[ACTIVE_ONDEMAND_SERVICE_CHECK_STATS].minute_stats[0], check_statistics[ACTIVE_ONDEMAND_SERVICE_CHECK_STATS].minute_stats[1], check_statistics[ACTIVE_ONDEMAND_SERVICE_CHECK_STATS].minute_stats[2]);
	fprintf(fp, "\tpassive_service_check_stats=%d,%d,%d\n", check_statistics[PASSIVE_SERVICE_CHECK_STATS].minute_stats[0], check_statistics[PASSIVE_SERVICE_CHECK_STATS].minute_stats[1], check_statistics[PASSIVE_SERVICE_CHECK_STATS].minute_stats[2]);
	fprintf(fp, "\tcached_host_check_stats=%d,%d,%d\n", check_statistics[ACTIVE_CACHED_HOST_CHECK_STATS].minute_stats[0], check_statistics[ACTIVE_CACHED_HOST_CHECK_STATS].minute_stats[1], check_statistics[ACTIVE_CACHED_HOST_CHECK_STATS].minute_stats[2]);
	fprintf(fp, "\tcached_service_check_stats=%d,%d,%d\n", check_statistics[ACTIVE_CACHED_SERVICE_CHECK_STATS].minute_stats[0], check_statistics[ACTIVE_CACHED_SERVICE_CHECK_STATS].minute_stats[1], check_statistics[ACTIVE_CACHED_SERVICE_CHECK_STATS].minute_stats[2]);
	fprintf(fp, "\texternal_command_stats=%d,%d,%d\n", check_statistics[EXTERNAL_COMMAND_STATS].minute_stats[0], check_statistics[EXTERNAL_COMMAND_STATS].minute_stats[1], check_statistics[EXTERNAL_COMMAND_STATS].minute_stats[2]);

	fprintf(fp, "\tparallel_host_check_stats=%d,%d,%d\n", check_statistics[PARALLEL_HOST_CHECK_STATS].minute_stats[0], check_statistics[PARALLEL_HOST_CHECK_STATS].minute_stats[1], check_statistics[PARALLEL_HOST_CHECK_STATS].minute_stats[2]);
	fprintf(fp, "\tserial_host_check_stats=%d,%d,%d\n", check_statistics[SERIAL_HOST_CHECK_STATS].minute_stats[0], check_statistics[SERIAL_HOST_CHECK_STATS].minute_stats[1], check_statistics[SERIAL_HOST_CHECK_STATS].minute_stats[2]);

	fprintf(fp, "\t}\n\n");


	/* save host status data */
	for (temp_host = host_list; temp_host != NULL; temp_host = temp_host->next) {

		fprintf(fp, "hoststatus {\n");
		fprintf(fp, "\thost_name=%s\n", temp_host->name);

		fprintf(fp, "\tmodified_attributes=%lu\n", temp_host->modified_attributes);
		fprintf(fp, "\tcheck_command=%s\n", (temp_host->host_check_command == NULL) ? "" : temp_host->host_check_command);
		fprintf(fp, "\tcheck_period=%s\n", (temp_host->check_period == NULL) ? "" : temp_host->check_period);
		fprintf(fp, "\tnotification_period=%s\n", (temp_host->notification_period == NULL) ? "" : temp_host->notification_period);
		fprintf(fp, "\tcheck_interval=%f\n", temp_host->check_interval);
		fprintf(fp, "\tretry_interval=%f\n", temp_host->retry_interval);
		fprintf(fp, "\tevent_handler=%s\n", (temp_host->event_handler == NULL) ? "" : temp_host->event_handler);

		fprintf(fp, "\thas_been_checked=%d\n", temp_host->has_been_checked);
		fprintf(fp, "\tshould_be_scheduled=%d\n", temp_host->should_be_scheduled);
		fprintf(fp, "\tcheck_execution_time=%.3f\n", temp_host->execution_time);
		fprintf(fp, "\tcheck_latency=%.3f\n", temp_host->latency);
		fprintf(fp, "\tcheck_type=%d\n", temp_host->check_type);
		fprintf(fp, "\tcurrent_state=%d\n", temp_host->current_state);
		fprintf(fp, "\tlast_hard_state=%d\n", temp_host->last_hard_state);
		fprintf(fp, "\tlast_event_id=%lu\n", temp_host->last_event_id);
		fprintf(fp, "\tcurrent_event_id=%lu\n", temp_host->current_event_id);
		fprintf(fp, "\tcurrent_problem_id=%lu\n", temp_host->current_problem_id);
		fprintf(fp, "\tlast_problem_id=%lu\n", temp_host->last_problem_id);
		fprintf(fp, "\tplugin_output=%s\n", (temp_host->plugin_output == NULL) ? "" : temp_host->plugin_output);
		fprintf(fp, "\tlong_plugin_output=%s\n", (temp_host->long_plugin_output == NULL) ? "" : temp_host->long_plugin_output);
		fprintf(fp, "\tperformance_data=%s\n", (temp_host->perf_data == NULL) ? "" : temp_host->perf_data);
		fprintf(fp, "\tlast_check=%lu\n", temp_host->last_check);
		fprintf(fp, "\tnext_check=%lu\n", temp_host->next_check);
		fprintf(fp, "\tcheck_options=%d\n", temp_host->check_options);
		fprintf(fp, "\tcurrent_attempt=%d\n", temp_host->current_attempt);
		fprintf(fp, "\tmax_attempts=%d\n", temp_host->max_attempts);
		fprintf(fp, "\tstate_type=%d\n", temp_host->state_type);
		fprintf(fp, "\tlast_state_change=%lu\n", temp_host->last_state_change);
		fprintf(fp, "\tlast_hard_state_change=%lu\n", temp_host->last_hard_state_change);
		fprintf(fp, "\tlast_time_up=%lu\n", temp_host->last_time_up);
		fprintf(fp, "\tlast_time_down=%lu\n", temp_host->last_time_down);
		fprintf(fp, "\tlast_time_unreachable=%lu\n", temp_host->last_time_unreachable);
		fprintf(fp, "\tlast_notification=%lu\n", temp_host->last_host_notification);
		fprintf(fp, "\tnext_notification=%lu\n", temp_host->next_host_notification);
		fprintf(fp, "\tno_more_notifications=%d\n", temp_host->no_more_notifications);
		fprintf(fp, "\tcurrent_notification_number=%d\n", temp_host->current_notification_number);
		/* state based escalation ranges */
		fprintf(fp, "\tcurrent_down_notification_number=%d\n", temp_host->current_down_notification_number);
		fprintf(fp, "\tcurrent_unreachable_notification_number=%d\n", temp_host->current_unreachable_notification_number);

		fprintf(fp, "\tcurrent_notification_id=%lu\n", temp_host->current_notification_id);
		fprintf(fp, "\tnotifications_enabled=%d\n", temp_host->notifications_enabled);
		fprintf(fp, "\tproblem_has_been_acknowledged=%d\n", temp_host->problem_has_been_acknowledged);
		fprintf(fp, "\tacknowledgement_type=%d\n", temp_host->acknowledgement_type);
		fprintf(fp, "\tacknowledgement_end_time=%lu\n", temp_host->acknowledgement_end_time);
		fprintf(fp, "\tactive_checks_enabled=%d\n", temp_host->checks_enabled);
		fprintf(fp, "\tpassive_checks_enabled=%d\n", temp_host->accept_passive_host_checks);
		fprintf(fp, "\tevent_handler_enabled=%d\n", temp_host->event_handler_enabled);
		fprintf(fp, "\tflap_detection_enabled=%d\n", temp_host->flap_detection_enabled);
		fprintf(fp, "\tfailure_prediction_enabled=%d\n", temp_host->failure_prediction_enabled);
		fprintf(fp, "\tprocess_performance_data=%d\n", temp_host->process_performance_data);
		fprintf(fp, "\tobsess_over_host=%d\n", temp_host->obsess_over_host);
		fprintf(fp, "\tlast_update=%lu\n", current_time);
		fprintf(fp, "\tis_flapping=%d\n", temp_host->is_flapping);
		fprintf(fp, "\tpercent_state_change=%.2f\n", temp_host->percent_state_change);
		fprintf(fp, "\tscheduled_downtime_depth=%d\n", temp_host->scheduled_downtime_depth);
		/*
		fprintf(fp,"\tstate_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, "\t_%s=%d;%s\n", temp_customvariablesmember->variable_name, temp_customvariablesmember->has_been_modified, (temp_customvariablesmember->variable_value == NULL) ? "" : temp_customvariablesmember->variable_value);
		}
		fprintf(fp, "\t}\n\n");
	}

	/* save service status data */
	for (temp_service = service_list; temp_service != NULL; temp_service = temp_service->next) {

		fprintf(fp, "servicestatus {\n");
		fprintf(fp, "\thost_name=%s\n", temp_service->host_name);

		fprintf(fp, "\tservice_description=%s\n", temp_service->description);
		fprintf(fp, "\tmodified_attributes=%lu\n", temp_service->modified_attributes);
		fprintf(fp, "\tcheck_command=%s\n", (temp_service->service_check_command == NULL) ? "" : temp_service->service_check_command);
		fprintf(fp, "\tcheck_period=%s\n", (temp_service->check_period == NULL) ? "" : temp_service->check_period);
		fprintf(fp, "\tnotification_period=%s\n", (temp_service->notification_period == NULL) ? "" : temp_service->notification_period);
		fprintf(fp, "\tcheck_interval=%f\n", temp_service->check_interval);
		fprintf(fp, "\tretry_interval=%f\n", temp_service->retry_interval);
		fprintf(fp, "\tevent_handler=%s\n", (temp_service->event_handler == NULL) ? "" : temp_service->event_handler);

		fprintf(fp, "\thas_been_checked=%d\n", temp_service->has_been_checked);
		fprintf(fp, "\tshould_be_scheduled=%d\n", temp_service->should_be_scheduled);
		fprintf(fp, "\tcheck_execution_time=%.3f\n", temp_service->execution_time);
		fprintf(fp, "\tcheck_latency=%.3f\n", temp_service->latency);
		fprintf(fp, "\tcheck_type=%d\n", temp_service->check_type);
		fprintf(fp, "\tcurrent_state=%d\n", temp_service->current_state);
		fprintf(fp, "\tlast_hard_state=%d\n", temp_service->last_hard_state);
		fprintf(fp, "\tlast_event_id=%lu\n", temp_service->last_event_id);
		fprintf(fp, "\tcurrent_event_id=%lu\n", temp_service->current_event_id);
		fprintf(fp, "\tcurrent_problem_id=%lu\n", temp_service->current_problem_id);
		fprintf(fp, "\tlast_problem_id=%lu\n", temp_service->last_problem_id);
		fprintf(fp, "\tcurrent_attempt=%d\n", temp_service->current_attempt);
		fprintf(fp, "\tmax_attempts=%d\n", temp_service->max_attempts);
		fprintf(fp, "\tstate_type=%d\n", temp_service->state_type);
		fprintf(fp, "\tlast_state_change=%lu\n", temp_service->last_state_change);
		fprintf(fp, "\tlast_hard_state_change=%lu\n", temp_service->last_hard_state_change);
		fprintf(fp, "\tlast_time_ok=%lu\n", temp_service->last_time_ok);
		fprintf(fp, "\tlast_time_warning=%lu\n", temp_service->last_time_warning);
		fprintf(fp, "\tlast_time_unknown=%lu\n", temp_service->last_time_unknown);
		fprintf(fp, "\tlast_time_critical=%lu\n", temp_service->last_time_critical);
		fprintf(fp, "\tplugin_output=%s\n", (temp_service->plugin_output == NULL) ? "" : temp_service->plugin_output);
		fprintf(fp, "\tlong_plugin_output=%s\n", (temp_service->long_plugin_output == NULL) ? "" : temp_service->long_plugin_output);
		fprintf(fp, "\tperformance_data=%s\n", (temp_service->perf_data == NULL) ? "" : temp_service->perf_data);
		fprintf(fp, "\tlast_check=%lu\n", temp_service->last_check);
		fprintf(fp, "\tnext_check=%lu\n", temp_service->next_check);
		fprintf(fp, "\tcheck_options=%d\n", temp_service->check_options);
		fprintf(fp, "\tcurrent_notification_number=%d\n", temp_service->current_notification_number);
		/* state based escalation ranges */
		fprintf(fp, "\tcurrent_warning_notification_number=%d\n", temp_service->current_warning_notification_number);
		fprintf(fp, "\tcurrent_critical_notification_number=%d\n", temp_service->current_critical_notification_number);
		fprintf(fp, "\tcurrent_unknown_notification_number=%d\n", temp_service->current_unknown_notification_number);

		fprintf(fp, "\tcurrent_notification_id=%lu\n", temp_service->current_notification_id);
		fprintf(fp, "\tlast_notification=%lu\n", temp_service->last_notification);
		fprintf(fp, "\tnext_notification=%lu\n", temp_service->next_notification);
		fprintf(fp, "\tno_more_notifications=%d\n", temp_service->no_more_notifications);
		fprintf(fp, "\tnotifications_enabled=%d\n", temp_service->notifications_enabled);
		fprintf(fp, "\tactive_checks_enabled=%d\n", temp_service->checks_enabled);
		fprintf(fp, "\tpassive_checks_enabled=%d\n", temp_service->accept_passive_service_checks);
		fprintf(fp, "\tevent_handler_enabled=%d\n", temp_service->event_handler_enabled);
		fprintf(fp, "\tproblem_has_been_acknowledged=%d\n", temp_service->problem_has_been_acknowledged);
		fprintf(fp, "\tacknowledgement_type=%d\n", temp_service->acknowledgement_type);
		fprintf(fp, "\tacknowledgement_end_time=%lu\n", temp_service->acknowledgement_end_time);
		fprintf(fp, "\tflap_detection_enabled=%d\n", temp_service->flap_detection_enabled);
		fprintf(fp, "\tfailure_prediction_enabled=%d\n", temp_service->failure_prediction_enabled);
		fprintf(fp, "\tprocess_performance_data=%d\n", temp_service->process_performance_data);
		fprintf(fp, "\tobsess_over_service=%d\n", temp_service->obsess_over_service);
		fprintf(fp, "\tlast_update=%lu\n", current_time);
		fprintf(fp, "\tis_flapping=%d\n", temp_service->is_flapping);
		fprintf(fp, "\tpercent_state_change=%.2f\n", temp_service->percent_state_change);
		fprintf(fp, "\tscheduled_downtime_depth=%d\n", temp_service->scheduled_downtime_depth);
		/*
		fprintf(fp,"\tstate_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, "\t_%s=%d;%s\n", temp_customvariablesmember->variable_name, temp_customvariablesmember->has_been_modified, (temp_customvariablesmember->variable_value == NULL) ? "" : temp_customvariablesmember->variable_value);
		}
		fprintf(fp, "\t}\n\n");
	}

	/* save contact status data */
	for (temp_contact = contact_list; temp_contact != NULL; temp_contact = temp_contact->next) {

		fprintf(fp, "contactstatus {\n");
		fprintf(fp, "\tcontact_name=%s\n", temp_contact->name);

		fprintf(fp, "\tmodified_attributes=%lu\n", temp_contact->modified_attributes);
		fprintf(fp, "\tmodified_host_attributes=%lu\n", temp_contact->modified_host_attributes);
		fprintf(fp, "\tmodified_service_attributes=%lu\n", temp_contact->modified_service_attributes);
		fprintf(fp, "\thost_notification_period=%s\n", (temp_contact->host_notification_period == NULL) ? "" : temp_contact->host_notification_period);
		fprintf(fp, "\tservice_notification_period=%s\n", (temp_contact->service_notification_period == NULL) ? "" : temp_contact->service_notification_period);

		fprintf(fp, "\tlast_host_notification=%lu\n", temp_contact->last_host_notification);
		fprintf(fp, "\tlast_service_notification=%lu\n", temp_contact->last_service_notification);
		fprintf(fp, "\thost_notifications_enabled=%d\n", temp_contact->host_notifications_enabled);
		fprintf(fp, "\tservice_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, "\t_%s=%d;%s\n", temp_customvariablesmember->variable_name, temp_customvariablesmember->has_been_modified, (temp_customvariablesmember->variable_value == NULL) ? "" : temp_customvariablesmember->variable_value);
		}
		fprintf(fp, "\t}\n\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, "\thost_name=%s\n", temp_comment->host_name);
		if (temp_comment->comment_type == SERVICE_COMMENT)
			fprintf(fp, "\tservice_description=%s\n", temp_comment->service_description);
		fprintf(fp, "\tentry_type=%d\n", temp_comment->entry_type);
		fprintf(fp, "\tcomment_id=%lu\n", temp_comment->comment_id);
		fprintf(fp, "\tsource=%d\n", temp_comment->source);
		fprintf(fp, "\tpersistent=%d\n", temp_comment->persistent);
		fprintf(fp, "\tentry_time=%lu\n", temp_comment->entry_time);
		fprintf(fp, "\texpires=%d\n", temp_comment->expires);
		fprintf(fp, "\texpire_time=%lu\n", temp_comment->expire_time);
		fprintf(fp, "\tauthor=%s\n", temp_comment->author);
		fprintf(fp, "\tcomment_data=%s\n", temp_comment->comment_data);
		fprintf(fp, "\t}\n\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, "\thost_name=%s\n", temp_downtime->host_name);
		if (temp_downtime->type == SERVICE_DOWNTIME)
			fprintf(fp, "\tservice_description=%s\n", temp_downtime->service_description);
		fprintf(fp, "\tdowntime_id=%lu\n", temp_downtime->downtime_id);
		fprintf(fp, "\tentry_time=%lu\n", temp_downtime->entry_time);
		fprintf(fp, "\tstart_time=%lu\n", temp_downtime->start_time);
		fprintf(fp, "\tend_time=%lu\n", temp_downtime->end_time);
		fprintf(fp, "\ttriggered_by=%lu\n", temp_downtime->triggered_by);
		fprintf(fp, "\tfixed=%d\n", temp_downtime->fixed);
		fprintf(fp, "\tduration=%lu\n", temp_downtime->duration);
		fprintf(fp, "\tis_in_effect=%d\n", temp_downtime->is_in_effect);
		fprintf(fp, "\tauthor=%s\n", temp_downtime->author);
		fprintf(fp, "\tcomment=%s\n", temp_downtime->comment);
		fprintf(fp, "\ttrigger_time=%lu\n", temp_downtime->trigger_time);
		fprintf(fp, "\t}\n\n");
	}


	/* reset file permissions */
	fchmod(fd, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH);

	/* flush the file to disk */
	fflush(fp);

	/* fsync the file so that it is completely written out before moving it */
	fsync(fd);

	/* close the temp file */
	result = fclose(fp);

	/* save/close was successful */
	if (result == 0) {

		result = OK;

		/* move the temp file to the status log (overwrite the old status log) */
		if (my_rename(temp_file, xsddefault_status_log)) {
			unlink(temp_file);
			logit(NSLOG_RUNTIME_ERROR, TRUE, "Error: Unable to update status data file '%s': %s", xsddefault_status_log, strerror(errno));
			result = ERROR;
		}
	}

	/* a problem occurred saving the file */
	else {

		result = ERROR;

		/* remove temp file and log an error */
		unlink(temp_file);
		logit(NSLOG_RUNTIME_ERROR, TRUE, "Error: Unable to save status file: %s", strerror(errno));
	}

	/* free memory */
	my_free(temp_file);

	return result;
}

#endif



#ifdef NSCGI

/******************************************************************/
/****************** DEFAULT DATA INPUT FUNCTIONS ******************/
/******************************************************************/

/* read all program, host, and service status information */
int xsddefault_read_status_data(char *config_file, int options) {
#ifdef NO_MMAP
	char input[MAX_PLUGIN_OUTPUT_LENGTH] = "";
	FILE *fp = NULL;
#else
	char *input = NULL;
	mmapfile *thefile = NULL;
#endif
	int data_type = XSDDEFAULT_NO_DATA;
	hoststatus *temp_hoststatus = NULL;
	servicestatus *temp_servicestatus = NULL;
	char *var = NULL;
	char *val = NULL;
	char *ptr = NULL;
	int result = 0;
	/* comment and downtime vars */
	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;
	char *host_name = NULL;
	char *service_description = NULL;
	char *author = NULL;
	char *comment_data = NULL;
	unsigned long downtime_id = 0;
	time_t start_time = 0L;
	time_t end_time = 0L;
	int fixed = FALSE;
	unsigned long triggered_by = 0;
	unsigned long duration = 0L;
	int x = 0;
	int is_in_effect = FALSE;
	time_t trigger_time = 0L;


	/* initialize some vars */
	for (x = 0; x < MAX_CHECK_STATS_TYPES; x++) {
		program_stats[x][0] = 0;
		program_stats[x][1] = 0;
		program_stats[x][2] = 0;
	}

	/* grab configuration data */
	if (xsddefault_grab_config_info(config_file) == ERROR) {
		logit(NSLOG_RUNTIME_ERROR, TRUE, "Error: Unable to read config file '%s': %s", config_file, strerror(errno));
		return ERROR;
	}

	/* open the status file for reading */
#ifdef NO_MMAP
	if ((fp = fopen(xsddefault_status_log, "r")) == NULL) {
		logit(NSLOG_RUNTIME_ERROR, TRUE, "Error: Unable to read status data file '%s': %s", xsddefault_status_log, strerror(errno));
		return ERROR;
	}
#else
	if ((thefile = mmap_fopen(xsddefault_status_log)) == NULL) {
		logit(NSLOG_RUNTIME_ERROR, TRUE, "Error: Unable to read status data file '%s': %s", xsddefault_status_log, strerror(errno));
		return ERROR;
	}
#endif

	/* Big speedup when reading status.dat in bulk */
	defer_downtime_sorting = 1;
	defer_comment_sorting = 1;

	/* read all lines in the status file */
	while (1) {

#ifdef NO_MMAP
		strcpy(input, "");
		if (fgets(input, sizeof(input), fp) == NULL)
			break;
#else
		/* free memory */
		my_free(input);

		/* read the next line */
		if ((input = mmap_fgets(thefile)) == NULL)
			break;
#endif

		strip(input);

		/* skip blank lines and comments */
		if (input[0] == '#' || input[0] == '\x0')
			continue;

		else if (!strcmp(input, "info {"))
			data_type = XSDDEFAULT_INFO_DATA;
		else if (!strcmp(input, "programstatus {"))
			data_type = XSDDEFAULT_PROGRAMSTATUS_DATA;
		else if (!strcmp(input, "hoststatus {")) {
			data_type = XSDDEFAULT_HOSTSTATUS_DATA;
			temp_hoststatus = (hoststatus *)calloc(1, sizeof(hoststatus));
		} else if (!strcmp(input, "servicestatus {")) {
			data_type = XSDDEFAULT_SERVICESTATUS_DATA;
			temp_servicestatus = (servicestatus *)calloc(1, sizeof(servicestatus));
		} else if (!strcmp(input, "contactstatus {")) {
			data_type = XSDDEFAULT_CONTACTSTATUS_DATA;
			/* unimplemented */
		} else if (!strcmp(input, "hostcomment {"))
			data_type = XSDDEFAULT_HOSTCOMMENT_DATA;
		else if (!strcmp(input, "servicecomment {"))
			data_type = XSDDEFAULT_SERVICECOMMENT_DATA;
		else if (!strcmp(input, "hostdowntime {"))
			data_type = XSDDEFAULT_HOSTDOWNTIME_DATA;
		else if (!strcmp(input, "servicedowntime {"))
			data_type = XSDDEFAULT_SERVICEDOWNTIME_DATA;

		else if (!strcmp(input, "}")) {

			switch (data_type) {

			case XSDDEFAULT_INFO_DATA:
				break;

			case XSDDEFAULT_PROGRAMSTATUS_DATA:
				break;

			case XSDDEFAULT_HOSTSTATUS_DATA:
				temp_hoststatus->added = 0;
				add_host_status(temp_hoststatus);
				temp_hoststatus = NULL;
				break;

			case XSDDEFAULT_SERVICESTATUS_DATA:
				temp_servicestatus->added = 0;
				add_service_status(temp_servicestatus);
				temp_servicestatus = NULL;
				break;

			case XSDDEFAULT_CONTACTSTATUS_DATA:
				/* unimplemented */
				break;

			case XSDDEFAULT_HOSTCOMMENT_DATA:
			case XSDDEFAULT_SERVICECOMMENT_DATA:

				/* add the comment */
				add_comment((data_type == XSDDEFAULT_HOSTCOMMENT_DATA) ? HOST_COMMENT : SERVICE_COMMENT, entry_type, host_name, service_description, entry_time, author, comment_data, comment_id, persistent, expires, expire_time, source);

				/* 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 XSDDEFAULT_HOSTDOWNTIME_DATA:
			case XSDDEFAULT_SERVICEDOWNTIME_DATA:

				/* add the downtime */
				if (data_type == XSDDEFAULT_HOSTDOWNTIME_DATA)
					add_host_downtime(host_name, entry_time, author, comment_data, start_time, end_time, fixed, triggered_by, duration, downtime_id, is_in_effect, trigger_time);
				else
					add_service_downtime(host_name, service_description, entry_time, author, comment_data, start_time, end_time, fixed, triggered_by, duration, downtime_id, is_in_effect, trigger_time);

				/* 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;
				end_time = 0L;
				fixed = FALSE;
				triggered_by = 0;
				duration = 0L;
				is_in_effect = FALSE;

				break;

			default:
				break;
			}

			data_type = XSDDEFAULT_NO_DATA;
		}

		else if (data_type != XSDDEFAULT_NO_DATA) {

			var = strtok(input, "=");
			val = strtok(NULL, "\n");
			if (val == NULL)
				continue;

			switch (data_type) {

			case XSDDEFAULT_INFO_DATA:
#ifdef NSCGI
				if (!strcmp(var, "created"))
					status_file_creation_time = strtoul(val, NULL, 10);
				else if (!strcmp(var, "version"))
					status_file_icinga_version = (char *)strdup(val);
#endif
				break;

			case XSDDEFAULT_PROGRAMSTATUS_DATA:
				/* NOTE: some vars are not read, as they are not used by the CGIs (modified attributes, event handler commands, etc.) */
				if (!strcmp(var, "icinga_pid"))
					nagios_pid = atoi(val);
				else if (!strcmp(var, "daemon_mode"))
					daemon_mode = (atoi(val) > 0) ? TRUE : FALSE;
				else if (!strcmp(var, "program_start"))
					program_start = strtoul(val, NULL, 10);
				else if (!strcmp(var, "last_command_check"))
					last_command_check = strtoul(val, NULL, 10);
				else if (!strcmp(var, "last_log_rotation"))
					last_log_rotation = strtoul(val, NULL, 10);
				else if (!strcmp(var, "enable_notifications"))
					enable_notifications = (atoi(val) > 0) ? TRUE : FALSE;
				else if (!strcmp(var, "disable_notifications_expire_time"))
					disable_notifications_expire_time = strtoul(val, NULL, 10);
				else if (!strcmp(var, "active_service_checks_enabled"))
					execute_service_checks = (atoi(val) > 0) ? TRUE : FALSE;
				else if (!strcmp(var, "passive_service_checks_enabled"))
					accept_passive_service_checks = (atoi(val) > 0) ? TRUE : FALSE;
				else if (!strcmp(var, "active_host_checks_enabled"))
					execute_host_checks = (atoi(val) > 0) ? TRUE : FALSE;
				else if (!strcmp(var, "passive_host_checks_enabled"))
					accept_passive_host_checks = (atoi(val) > 0) ? TRUE : FALSE;
				else if (!strcmp(var, "enable_event_handlers"))
					enable_event_handlers = (atoi(val) > 0) ? TRUE : FALSE;
				else if (!strcmp(var, "obsess_over_services"))
					obsess_over_services = (atoi(val) > 0) ? TRUE : FALSE;
				else if (!strcmp(var, "obsess_over_hosts"))
					obsess_over_hosts = (atoi(val) > 0) ? TRUE : FALSE;
				else if (!strcmp(var, "check_service_freshness"))
					check_service_freshness = (atoi(val) > 0) ? TRUE : FALSE;
				else if (!strcmp(var, "check_host_freshness"))
					check_host_freshness = (atoi(val) > 0) ? TRUE : FALSE;
				else if (!strcmp(var, "enable_flap_detection"))
					enable_flap_detection = (atoi(val) > 0) ? TRUE : FALSE;
				else if (!strcmp(var, "enable_failure_prediction"))
					enable_failure_prediction = (atoi(val) > 0) ? TRUE : FALSE;
				else if (!strcmp(var, "process_performance_data"))
					process_performance_data = (atoi(val) > 0) ? TRUE : FALSE;

				else if (!strcmp(var, "total_external_command_buffer_slots"))
					buffer_stats[0][0] = atoi(val);
				else if (!strcmp(var, "used_external_command_buffer_slots"))
					buffer_stats[0][1] = atoi(val);
				else if (!strcmp(var, "high_external_command_buffer_slots"))
					buffer_stats[0][2] = atoi(val);


				else if (strstr(var, "_stats")) {

					x = -1;
					if (!strcmp(var, "active_scheduled_host_check_stats"))
						x = ACTIVE_SCHEDULED_HOST_CHECK_STATS;
					if (!strcmp(var, "active_ondemand_host_check_stats"))
						x = ACTIVE_ONDEMAND_HOST_CHECK_STATS;
					if (!strcmp(var, "passive_host_check_stats"))
						x = PASSIVE_HOST_CHECK_STATS;
					if (!strcmp(var, "active_scheduled_service_check_stats"))
						x = ACTIVE_SCHEDULED_SERVICE_CHECK_STATS;
					if (!strcmp(var, "active_ondemand_service_check_stats"))
						x = ACTIVE_ONDEMAND_SERVICE_CHECK_STATS;
					if (!strcmp(var, "passive_service_check_stats"))
						x = PASSIVE_SERVICE_CHECK_STATS;
					if (!strcmp(var, "cached_host_check_stats"))
						x = ACTIVE_CACHED_HOST_CHECK_STATS;
					if (!strcmp(var, "cached_service_check_stats"))
						x = ACTIVE_CACHED_SERVICE_CHECK_STATS;
					if (!strcmp(var, "external_command_stats"))
						x = EXTERNAL_COMMAND_STATS;
					if (!strcmp(var, "parallel_host_check_stats"))
						x = PARALLEL_HOST_CHECK_STATS;
					if (!strcmp(var, "serial_host_check_stats"))
						x = SERIAL_HOST_CHECK_STATS;

					if (x >= 0) {
						if ((ptr = strtok(val, ","))) {
							program_stats[x][0] = atoi(ptr);
							if ((ptr = strtok(NULL, ","))) {
								program_stats[x][1] = atoi(ptr);
								if ((ptr = strtok(NULL, "\n")))
									program_stats[x][2] = atoi(ptr);
							}
						}
					}
				}
				break;

			case XSDDEFAULT_HOSTSTATUS_DATA:
				/* NOTE: some vars are not read, as they are not used by the CGIs (modified attributes, event handler commands, etc.) */
				if (temp_hoststatus != NULL) {
					if (!strcmp(var, "host_name"))
						temp_hoststatus->host_name = (char *)strdup(val);
					else if (!strcmp(var, "has_been_checked"))
						temp_hoststatus->has_been_checked = (atoi(val) > 0) ? TRUE : FALSE;
					else if (!strcmp(var, "should_be_scheduled"))
						temp_hoststatus->should_be_scheduled = (atoi(val) > 0) ? TRUE : FALSE;
					else if (!strcmp(var, "check_execution_time"))
						temp_hoststatus->execution_time = strtod(val, NULL);
					else if (!strcmp(var, "check_latency"))
						temp_hoststatus->latency = strtod(val, NULL);
					else if (!strcmp(var, "check_type"))
						temp_hoststatus->check_type = atoi(val);
					else if (!strcmp(var, "current_state"))
						temp_hoststatus->status = atoi(val);
					else if (!strcmp(var, "last_hard_state"))
						temp_hoststatus->last_hard_state = atoi(val);
					else if (!strcmp(var, "plugin_output")) {
						temp_hoststatus->plugin_output = (char *)strdup(val);
						unescape_newlines(temp_hoststatus->plugin_output);
					} else if (!strcmp(var, "long_plugin_output")) {
						temp_hoststatus->long_plugin_output = (char *)strdup(val);
						unescape_newlines(temp_hoststatus->long_plugin_output);
					} else if (!strcmp(var, "performance_data"))
						temp_hoststatus->perf_data = (char *)strdup(val);
					else if (!strcmp(var, "check_source"))
						temp_hoststatus->check_source = (char *)strdup(val);
					else if (!strcmp(var, "current_attempt"))
						temp_hoststatus->current_attempt = atoi(val);
					else if (!strcmp(var, "max_attempts"))
						temp_hoststatus->max_attempts = atoi(val);
					else if (!strcmp(var, "last_check"))
						temp_hoststatus->last_check = strtoul(val, NULL, 10);
					else if (!strcmp(var, "next_check"))
						temp_hoststatus->next_check = strtoul(val, NULL, 10);
					else if (!strcmp(var, "check_options"))
						temp_hoststatus->check_options = atoi(val);
					else if (!strcmp(var, "current_attempt"))
						temp_hoststatus->current_attempt = (atoi(val) > 0) ? TRUE : FALSE;
					else if (!strcmp(var, "state_type"))
						temp_hoststatus->state_type = atoi(val);
					else if (!strcmp(var, "last_state_change"))
						temp_hoststatus->last_state_change = strtoul(val, NULL, 10);
					else if (!strcmp(var, "last_hard_state_change"))
						temp_hoststatus->last_hard_state_change = strtoul(val, NULL, 10);
					else if (!strcmp(var, "last_time_up"))
						temp_hoststatus->last_time_up = strtoul(val, NULL, 10);
					else if (!strcmp(var, "last_time_down"))
						temp_hoststatus->last_time_down = strtoul(val, NULL, 10);
					else if (!strcmp(var, "last_time_unreachable"))
						temp_hoststatus->last_time_unreachable = strtoul(val, NULL, 10);
					else if (!strcmp(var, "last_notification"))
						temp_hoststatus->last_notification = strtoul(val, NULL, 10);
					else if (!strcmp(var, "next_notification"))
						temp_hoststatus->next_notification = strtoul(val, NULL, 10);
					else if (!strcmp(var, "no_more_notifications"))
						temp_hoststatus->no_more_notifications = (atoi(val) > 0) ? TRUE : FALSE;
					else if (!strcmp(var, "current_notification_number"))
						temp_hoststatus->current_notification_number = atoi(val);
					/* state based escalation ranges */
					else if (!strcmp(var, "current_down_notification_number"))
						temp_hoststatus->current_down_notification_number = atoi(val);
					else if (!strcmp(var, "current_unreachable_notification_number"))
						temp_hoststatus->current_unreachable_notification_number = atoi(val);

					else if (!strcmp(var, "notifications_enabled"))
						temp_hoststatus->notifications_enabled = (atoi(val) > 0) ? TRUE : FALSE;
					else if (!strcmp(var, "problem_has_been_acknowledged"))
						temp_hoststatus->problem_has_been_acknowledged = (atoi(val) > 0) ? TRUE : FALSE;
					else if (!strcmp(var, "acknowledgement_type"))
						temp_hoststatus->acknowledgement_type = atoi(val);
					else if (!strcmp(var, "acknowledgement_end_time"))
						temp_hoststatus->acknowledgement_end_time = strtoul(val, NULL, 10);
					else if (!strcmp(var, "active_checks_enabled"))
						temp_hoststatus->checks_enabled = (atoi(val) > 0) ? TRUE : FALSE;
					else if (!strcmp(var, "passive_checks_enabled"))
						temp_hoststatus->accept_passive_host_checks = (atoi(val) > 0) ? TRUE : FALSE;
					else if (!strcmp(var, "event_handler_enabled"))
						temp_hoststatus->event_handler_enabled = (atoi(val) > 0) ? TRUE : FALSE;
					else if (!strcmp(var, "flap_detection_enabled"))
						temp_hoststatus->flap_detection_enabled = (atoi(val) > 0) ? TRUE : FALSE;
					else if (!strcmp(var, "failure_prediction_enabled"))
						temp_hoststatus->failure_prediction_enabled = (atoi(val) > 0) ? TRUE : FALSE;
					else if (!strcmp(var, "process_performance_data"))
						temp_hoststatus->process_performance_data = (atoi(val) > 0) ? TRUE : FALSE;
					else if (!strcmp(var, "obsess_over_host"))
						temp_hoststatus->obsess_over_host = (atoi(val) > 0) ? TRUE : FALSE;
					else if (!strcmp(var, "last_update"))
						temp_hoststatus->last_update = strtoul(val, NULL, 10);
					else if (!strcmp(var, "is_flapping"))
						temp_hoststatus->is_flapping = (atoi(val) > 0) ? TRUE : FALSE;
					else if (!strcmp(var, "percent_state_change"))
						temp_hoststatus->percent_state_change = strtod(val, NULL);
					else if (!strcmp(var, "scheduled_downtime_depth"))
						temp_hoststatus->scheduled_downtime_depth = atoi(val);
					else if (!strcmp(var, "modified_attributes"))
						temp_hoststatus->modified_attributes = strtoul(val, NULL, 10);
					else if (!strcmp(var, "is_reachable"))
						temp_hoststatus->is_reachable = (atoi(val) > 0) ? TRUE : FALSE;
					/*
					else if(!strcmp(var,"state_history")){
						temp_ptr=val;
						for(x=0;x<MAX_STATE_HISTORY_ENTRIES;x++)
							temp_hoststatus->state_history[x]=atoi(my_strsep(&temp_ptr,","));
						temp_hoststatus->state_history_index=0;
					        }
					*/
				}
				break;

			case XSDDEFAULT_SERVICESTATUS_DATA:
				/* NOTE: some vars are not read, as they are not used by the CGIs (modified attributes, event handler commands, etc.) */
				if (temp_servicestatus != NULL) {
					if (!strcmp(var, "host_name"))
						temp_servicestatus->host_name = (char *)strdup(val);
					else if (!strcmp(var, "service_description"))
						temp_servicestatus->description = (char *)strdup(val);
					else if (!strcmp(var, "has_been_checked"))
						temp_servicestatus->has_been_checked = (atoi(val) > 0) ? TRUE : FALSE;
					else if (!strcmp(var, "should_be_scheduled"))
						temp_servicestatus->should_be_scheduled = (atoi(val) > 0) ? TRUE : FALSE;
					else if (!strcmp(var, "check_execution_time"))
						temp_servicestatus->execution_time = strtod(val, NULL);
					else if (!strcmp(var, "check_latency"))
						temp_servicestatus->latency = strtod(val, NULL);
					else if (!strcmp(var, "check_type"))
						temp_servicestatus->check_type = atoi(val);
					else if (!strcmp(var, "current_state"))
						temp_servicestatus->status = atoi(val);
					else if (!strcmp(var, "last_hard_state"))
						temp_servicestatus->last_hard_state = atoi(val);
					else if (!strcmp(var, "current_attempt"))
						temp_servicestatus->current_attempt = atoi(val);
					else if (!strcmp(var, "max_attempts"))
						temp_servicestatus->max_attempts = atoi(val);
					else if (!strcmp(var, "state_type"))
						temp_servicestatus->state_type = atoi(val);
					else if (!strcmp(var, "last_state_change"))
						temp_servicestatus->last_state_change = strtoul(val, NULL, 10);
					else if (!strcmp(var, "last_hard_state_change"))
						temp_servicestatus->last_hard_state_change = strtoul(val, NULL, 10);
					else if (!strcmp(var, "last_time_ok"))
						temp_servicestatus->last_time_ok = strtoul(val, NULL, 10);
					else if (!strcmp(var, "last_time_warning"))
						temp_servicestatus->last_time_warning = strtoul(val, NULL, 10);
					else if (!strcmp(var, "last_time_unknown"))
						temp_servicestatus->last_time_unknown = strtoul(val, NULL, 10);
					else if (!strcmp(var, "last_time_critical"))
						temp_servicestatus->last_time_critical = strtoul(val, NULL, 10);
					else if (!strcmp(var, "plugin_output")) {
						temp_servicestatus->plugin_output = (char *)strdup(val);
						unescape_newlines(temp_servicestatus->plugin_output);
					} else if (!strcmp(var, "long_plugin_output")) {
						temp_servicestatus->long_plugin_output = (char *)strdup(val);
						unescape_newlines(temp_servicestatus->long_plugin_output);
					} else if (!strcmp(var, "performance_data"))
						temp_servicestatus->perf_data = (char *)strdup(val);
					else if (!strcmp(var, "check_source"))
						temp_servicestatus->check_source = (char *)strdup(val);
					else if (!strcmp(var, "last_check"))
						temp_servicestatus->last_check = strtoul(val, NULL, 10);
					else if (!strcmp(var, "next_check"))
						temp_servicestatus->next_check = strtoul(val, NULL, 10);
					else if (!strcmp(var, "check_options"))
						temp_servicestatus->check_options = atoi(val);
					else if (!strcmp(var, "current_notification_number"))
						temp_servicestatus->current_notification_number = atoi(val);
					/* state based escalation ranges */
					else if (!strcmp(var, "current_warning_notification_number"))
						temp_servicestatus->current_warning_notification_number = atoi(val);
					else if (!strcmp(var, "current_critical_notification_number"))
						temp_servicestatus->current_critical_notification_number = atoi(val);
					else if (!strcmp(var, "current_unknown_notification_number"))
						temp_servicestatus->current_unknown_notification_number = atoi(val);

					else if (!strcmp(var, "last_notification"))
						temp_servicestatus->last_notification = strtoul(val, NULL, 10);
					else if (!strcmp(var, "next_notification"))
						temp_servicestatus->next_notification = strtoul(val, NULL, 10);
					else if (!strcmp(var, "no_more_notifications"))
						temp_servicestatus->no_more_notifications = (atoi(val) > 0) ? TRUE : FALSE;
					else if (!strcmp(var, "notifications_enabled"))
						temp_servicestatus->notifications_enabled = (atoi(val) > 0) ? TRUE : FALSE;
					else if (!strcmp(var, "active_checks_enabled"))
						temp_servicestatus->checks_enabled = (atoi(val) > 0) ? TRUE : FALSE;
					else if (!strcmp(var, "passive_checks_enabled"))
						temp_servicestatus->accept_passive_service_checks = (atoi(val) > 0) ? TRUE : FALSE;
					else if (!strcmp(var, "event_handler_enabled"))
						temp_servicestatus->event_handler_enabled = (atoi(val) > 0) ? TRUE : FALSE;
					else if (!strcmp(var, "problem_has_been_acknowledged"))
						temp_servicestatus->problem_has_been_acknowledged = (atoi(val) > 0) ? TRUE : FALSE;
					else if (!strcmp(var, "acknowledgement_type"))
						temp_servicestatus->acknowledgement_type = atoi(val);
					else if (!strcmp(var, "acknowledgement_end_time"))
						temp_servicestatus->acknowledgement_end_time = strtoul(val, NULL, 10);
					else if (!strcmp(var, "flap_detection_enabled"))
						temp_servicestatus->flap_detection_enabled = (atoi(val) > 0) ? TRUE : FALSE;
					else if (!strcmp(var, "failure_prediction_enabled"))
						temp_servicestatus->failure_prediction_enabled = (atoi(val) > 0) ? TRUE : FALSE;
					else if (!strcmp(var, "process_performance_data"))
						temp_servicestatus->process_performance_data = (atoi(val) > 0) ? TRUE : FALSE;
					else if (!strcmp(var, "obsess_over_service"))
						temp_servicestatus->obsess_over_service = (atoi(val) > 0) ? TRUE : FALSE;
					else if (!strcmp(var, "last_update"))
						temp_servicestatus->last_update = strtoul(val, NULL, 10);
					else if (!strcmp(var, "is_flapping"))
						temp_servicestatus->is_flapping = (atoi(val) > 0) ? TRUE : FALSE;
					else if (!strcmp(var, "percent_state_change"))
						temp_servicestatus->percent_state_change = strtod(val, NULL);
					else if (!strcmp(var, "scheduled_downtime_depth"))
						temp_servicestatus->scheduled_downtime_depth = atoi(val);
					else if (!strcmp(var, "modified_attributes"))
						temp_servicestatus->modified_attributes = strtoul(val, NULL, 10);
					else if (!strcmp(var, "is_reachable"))
						temp_servicestatus->is_reachable = (atoi(val) > 0) ? TRUE : FALSE;
					/*
					else if(!strcmp(var,"state_history")){
						temp_ptr=val;
						for(x=0;x<MAX_STATE_HISTORY_ENTRIES;x++)
							temp_servicestatus->state_history[x]=atoi(my_strsep(&temp_ptr,","));
						temp_servicestatus->state_history_index=0;
					        }
					*/
				}
				break;

			case XSDDEFAULT_CONTACTSTATUS_DATA:
				/* unimplemented */
				break;

			case XSDDEFAULT_HOSTCOMMENT_DATA:
			case XSDDEFAULT_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 XSDDEFAULT_HOSTDOWNTIME_DATA:
			case XSDDEFAULT_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, "entry_time"))
					entry_time = strtoul(val, NULL, 10);
				else if (!strcmp(var, "start_time"))
					start_time = 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, "duration"))
					duration = strtoul(val, NULL, 10);
				else if (!strcmp(var, "is_in_effect"))
					is_in_effect = (atoi(val) > 0) ? TRUE : FALSE;
				else if (!strcmp(var, "author"))
					author = (char *)strdup(val);
				else if (!strcmp(var, "comment"))
					comment_data = (char *)strdup(val);
				else if (!strcmp(var, "trigger_time"))
					trigger_time = strtoul(val, NULL, 10);
				break;

			default:
				break;
			}

		}
	}

	/* free memory and close the file */
#ifdef NO_MMAP
	fclose(fp);
#else
	my_free(input);
	mmap_fclose(thefile);
#endif

	/* free memory */
	my_free(xsddefault_status_log);
	my_free(xsddefault_temp_file);

	if (sort_downtime() != OK)
		return ERROR;
	if (sort_comments() != OK)
		return ERROR;

	if (status_file_icinga_version == NULL)
		status_file_icinga_version = PROGRAM_VERSION;

	return OK;
}

#endif

