Пример #1
0
/* enables flap detection for a specific host */
void enable_host_flap_detection(host *hst) {
	unsigned long attr = MODATTR_FLAP_DETECTION_ENABLED;

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

	if (hst == NULL)
		return;

	log_debug_info(DEBUGL_FLAPPING, 1, "Enabling flap detection for host '%s'.\n", hst->name);

	/* nothing to do... */
	if (hst->flap_detection_enabled == TRUE)
		return;

	/* set the attribute modified flag */
	hst->modified_attributes |= attr;

	/* set the flap detection enabled flag */
	hst->flap_detection_enabled = TRUE;

#ifdef USE_EVENT_BROKER
	/* send data to event broker */
	broker_adaptive_host_data(NEBTYPE_ADAPTIVEHOST_UPDATE, NEBFLAG_NONE, NEBATTR_NONE, hst, CMD_NONE, attr, hst->modified_attributes, NULL);
#endif

	/* check for flapping */
	check_for_host_flapping(hst, FALSE, FALSE, TRUE);

	/* update host status */
	update_host_status(hst, FALSE);

	return;
}
Пример #2
0
void game_frame() 
{
	static char cbak;
	static int8_t gpx, gpy;

	// mouse
	vram[cy / 8][cx / 8] = cbak;

	cy += mouse_y; mouse_y=0;
	if (cy < 0) cy = VGA_V_PIXELS;
	else if (cy >= VGA_V_PIXELS) cy = 0;
	
	cx += mouse_x; mouse_x=0;
	if (cx < 0) cx = VGA_H_PIXELS;
	else if (cx >= VGA_H_PIXELS) cx = 0;

	printhex(11,6,cx/8);
	printhex(16,6,cy/8);

	cbak = vram[cy / 8][cx / 8];
	vram[cy / 8][cx / 8] = 127;

	vram[6][19]=mouse_buttons & mousebut_left?'L':'l';
	vram[6][20]=mouse_buttons & mousebut_middle?'M':'m';
	vram[6][21]=mouse_buttons & mousebut_right?'R':'r';

	printhex(23,6,mouse_buttons);

	// gamepad buttons
	update_controller(PAD_X, PAD_Y,gamepad_buttons[0]);
	update_controller(PAD_X, PAD_Y2,gamepad_buttons[1]);


	// analog gamepad
	printhex(40,PAD_Y-2,gamepad_x[0]);
	printhex(43,PAD_Y-2,gamepad_y[0]);

	vram[15 + gpy / 32][36  + gpx / 16] = ' ';

	gpx = gamepad_x[0];
	gpy = gamepad_y[0];
	vram[15 + gpy / 32][36 + gpx / 16] = '+';

	// KB codes 
	for (int i=0;i<6;i++) {
		printhex(5+i*3,KB_Y+2,keyboard_key[0][i]);
	}

	// KB mods
	for (int i=0;i<8;i++)
		vram[KB_Y+3][5+i]=keyboard_mod[0] & (1<<i) ? KBMOD[i] : '-' ;


	// low level stuff
	update_host_status();

}
Пример #3
0
/* handles the details for a host when flap detection is disabled (globally or per-host) */
void handle_host_flap_detection_disabled(host *hst)
{

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

	if (hst == NULL)
		return;

	/* if the host was flapping, remove the flapping indicator */
	if (hst->is_flapping == TRUE) {

		hst->is_flapping = FALSE;

		/* delete the original comment we added earlier */
		if (hst->flapping_comment_id != 0)
			delete_host_comment(hst->flapping_comment_id);
		hst->flapping_comment_id = 0;

		/* log a notice - this one is parsed by the history CGI */
		logit(NSLOG_INFO_MESSAGE, FALSE, "HOST FLAPPING ALERT: %s;DISABLED; Flap detection has been disabled\n", hst->name);

#ifdef USE_EVENT_BROKER
		/* send data to event broker */
		broker_flapping_data(NEBTYPE_FLAPPING_STOP, NEBFLAG_NONE, NEBATTR_FLAPPING_STOP_DISABLED, HOST_FLAPPING, hst, hst->percent_state_change, 0.0, 0.0, NULL);
#endif

		/* send a notification */
		host_notification(hst, NOTIFICATION_FLAPPINGDISABLED, NULL, NULL, NOTIFICATION_OPTION_NONE);

		/* should we send a recovery notification? */
		if (hst->check_flapping_recovery_notification == TRUE && hst->current_state == HOST_UP)
			host_notification(hst, NOTIFICATION_NORMAL, NULL, NULL, NOTIFICATION_OPTION_NONE);

		/* clear the recovery notification flag */
		hst->check_flapping_recovery_notification = FALSE;
	}

	/* update host status */
	update_host_status(hst, FALSE);

	return;
}
Пример #4
0
/* attempts to compensate for a change in the system time */
void compensate_for_system_time_change(unsigned long last_time, unsigned long current_time)
{
	unsigned long time_difference = 0L;
	service *temp_service = NULL;
	host *temp_host = NULL;
	int days = 0;
	int hours = 0;
	int minutes = 0;
	int seconds = 0;
	int delta = 0;


	log_debug_info(DEBUGL_FUNCTIONS, 0, "compensate_for_system_time_change() start\n");

	/*
	 * if current_time < last_time, delta will be negative so we can
	 * still use addition to all effected timestamps
	 */
	delta = current_time - last_time;

	/* we moved back in time... */
	if (last_time > current_time) {
		time_difference = last_time - current_time;
		get_time_breakdown(time_difference, &days, &hours, &minutes, &seconds);
		log_debug_info(DEBUGL_EVENTS, 0, "Detected a backwards time change of %dd %dh %dm %ds.\n", days, hours, minutes, seconds);
	}

	/* we moved into the future... */
	else {
		time_difference = current_time - last_time;
		get_time_breakdown(time_difference, &days, &hours, &minutes, &seconds);
		log_debug_info(DEBUGL_EVENTS, 0, "Detected a forwards time change of %dd %dh %dm %ds.\n", days, hours, minutes, seconds);
	}

	/* log the time change */
	logit(NSLOG_PROCESS_INFO | NSLOG_RUNTIME_WARNING, TRUE, "Warning: A system time change of %d seconds (%dd %dh %dm %ds %s in time) has been detected.  Compensating...\n",
	      delta, days, hours, minutes, seconds,
	      (last_time > current_time) ? "backwards" : "forwards");

	adjust_squeue_for_time_change(&nagios_squeue, delta);

	/* adjust service timestamps */
	for (temp_service = service_list; temp_service != NULL; temp_service = temp_service->next) {

		adjust_timestamp_for_time_change(last_time, current_time, time_difference, &temp_service->last_notification);
		adjust_timestamp_for_time_change(last_time, current_time, time_difference, &temp_service->last_check);
		adjust_timestamp_for_time_change(last_time, current_time, time_difference, &temp_service->next_check);
		adjust_timestamp_for_time_change(last_time, current_time, time_difference, &temp_service->last_state_change);
		adjust_timestamp_for_time_change(last_time, current_time, time_difference, &temp_service->last_hard_state_change);

		/* recalculate next re-notification time */
		temp_service->next_notification = get_next_service_notification_time(temp_service, temp_service->last_notification);

		/* update the status data */
		update_service_status(temp_service, FALSE);
	}

	/* adjust host timestamps */
	for (temp_host = host_list; temp_host != NULL; temp_host = temp_host->next) {

		adjust_timestamp_for_time_change(last_time, current_time, time_difference, &temp_host->last_notification);
		adjust_timestamp_for_time_change(last_time, current_time, time_difference, &temp_host->last_check);
		adjust_timestamp_for_time_change(last_time, current_time, time_difference, &temp_host->next_check);
		adjust_timestamp_for_time_change(last_time, current_time, time_difference, &temp_host->last_state_change);
		adjust_timestamp_for_time_change(last_time, current_time, time_difference, &temp_host->last_hard_state_change);
		adjust_timestamp_for_time_change(last_time, current_time, time_difference, &temp_host->last_state_history_update);

		/* recalculate next re-notification time */
		temp_host->next_notification = get_next_host_notification_time(temp_host, temp_host->last_notification);

		/* update the status data */
		update_host_status(temp_host, FALSE);
	}

	/* adjust program timestamps */
	adjust_timestamp_for_time_change(last_time, current_time, time_difference, &program_start);
	adjust_timestamp_for_time_change(last_time, current_time, time_difference, &event_start);

	/* update the status data */
	update_program_status(FALSE);

	return;
}
Пример #5
0
/* initialize the event timing loop before we start monitoring */
void init_timing_loop(void)
{
	host *temp_host = NULL;
	service *temp_service = NULL;
	time_t current_time = 0L;
	struct timeval tv[9];
	double runtime[9];
	struct timeval now;

	log_debug_info(DEBUGL_FUNCTIONS, 0, "init_timing_loop() start\n");

	/* get the time and seed the prng */
	gettimeofday(&now, NULL);
	current_time = now.tv_sec;
	srand((now.tv_sec << 10) ^ now.tv_usec);


	/******** GET BASIC HOST/SERVICE INFO  ********/

	memset(&scheduling_info, 0, sizeof(scheduling_info));

	if (test_scheduling == TRUE)
		gettimeofday(&tv[0], NULL);

	/* get info on service checks to be scheduled */
	for (temp_service = service_list; temp_service != NULL; temp_service = temp_service->next) {
		scheduling_info.total_services++;

		/* maybe we shouldn't schedule this check */
		if (temp_service->check_interval == 0 || !temp_service->checks_enabled) {
			log_debug_info(DEBUGL_EVENTS, 1, "Service '%s' on host '%s' should not be scheduled.\n", temp_service->description, temp_service->host_name);
			temp_service->should_be_scheduled = FALSE;
			continue;
		}

		scheduling_info.total_scheduled_services++;
	}

	if (test_scheduling == TRUE)
		gettimeofday(&tv[1], NULL);

	/* get info on host checks to be scheduled */
	for (temp_host = host_list; temp_host; temp_host = temp_host->next) {
		scheduling_info.total_hosts++;

		/* host has no check interval */
		if (temp_host->check_interval == 0 || !temp_host->checks_enabled) {
			log_debug_info(DEBUGL_EVENTS, 1, "Host '%s' should not be scheduled.\n", temp_host->name);
			temp_host->should_be_scheduled = FALSE;
			continue;
		}

		scheduling_info.total_scheduled_hosts++;
	}

	if (test_scheduling == TRUE)
		gettimeofday(&tv[2], NULL);

	scheduling_info.average_services_per_host = (double)((double)scheduling_info.total_services / (double)scheduling_info.total_hosts);
	scheduling_info.average_scheduled_services_per_host = (double)((double)scheduling_info.total_scheduled_services / (double)scheduling_info.total_hosts);

	/* adjust the check interval total to correspond to the interval length */
	scheduling_info.service_check_interval_total = (scheduling_info.service_check_interval_total * interval_length);

	/* calculate the average check interval for services */
	scheduling_info.average_service_check_interval = (double)((double)scheduling_info.service_check_interval_total / (double)scheduling_info.total_scheduled_services);

	if (test_scheduling == TRUE)
		gettimeofday(&tv[3], NULL);

	/******** SCHEDULE SERVICE CHECKS  ********/

	log_debug_info(DEBUGL_EVENTS, 2, "Scheduling service checks...");

	for (temp_service = service_list; temp_service != NULL; temp_service = temp_service->next) {
		log_debug_info(DEBUGL_EVENTS, 2, "Service '%s' on host '%s'\n", temp_service->description, temp_service->host_name);
		/* skip this service if it shouldn't be scheduled */
		if (temp_service->should_be_scheduled == FALSE) {
			continue;
		}

		temp_service->next_check = current_time + ranged_urand(0, check_window(temp_service));

		if (scheduling_info.last_service_check < temp_service->next_check)
			scheduling_info.last_service_check = temp_service->next_check;
		if (!scheduling_info.first_service_check || scheduling_info.first_service_check > temp_service->next_check)
			scheduling_info.first_service_check = temp_service->next_check;

		log_debug_info(DEBUGL_EVENTS, 2, "Check Time: %lu --> %s", (unsigned long)temp_service->next_check, ctime(&temp_service->next_check));
	}

	if (test_scheduling == TRUE)
		gettimeofday(&tv[4], NULL);

	/* add scheduled service checks to event queue */
	for (temp_service = service_list; temp_service != NULL; temp_service = temp_service->next) {

		/* update status of all services (scheduled or not) */
		update_service_status(temp_service, FALSE);

		/* skip most services that shouldn't be scheduled */
		if (temp_service->should_be_scheduled == FALSE) {

			/* passive checks are an exception if a forced check was scheduled before we restarted */
			if (!(temp_service->checks_enabled == FALSE && temp_service->next_check != (time_t)0L && (temp_service->check_options & CHECK_OPTION_FORCE_EXECUTION)))
				continue;
		}

		/* create a new service check event */
		temp_service->next_check_event = schedule_new_event(EVENT_SERVICE_CHECK, FALSE, temp_service->next_check, FALSE, 0, NULL, TRUE, (void *)temp_service, NULL, temp_service->check_options);
	}


	if (test_scheduling == TRUE)
		gettimeofday(&tv[5], NULL);

	if (test_scheduling == TRUE)
		gettimeofday(&tv[6], NULL);


	/******** SCHEDULE HOST CHECKS  ********/

	log_debug_info(DEBUGL_EVENTS, 2, "Scheduling host checks...");

	/* determine check times for host checks */
	for (temp_host = host_list; temp_host != NULL; temp_host = temp_host->next) {

		log_debug_info(DEBUGL_EVENTS, 2, "Host '%s'\n", temp_host->name);

		/* skip hosts that shouldn't be scheduled */
		if (temp_host->should_be_scheduled == FALSE) {
			continue;
		}

		temp_host->next_check = current_time + ranged_urand(0, check_window(temp_host));

		log_debug_info(DEBUGL_EVENTS, 2, "Check Time: %lu --> %s", (unsigned long)temp_host->next_check, ctime(&temp_host->next_check));
		if (temp_host->next_check > scheduling_info.last_host_check)
			scheduling_info.last_host_check = temp_host->next_check;
		if (!scheduling_info.first_host_check || scheduling_info.first_host_check > temp_host->next_check)
			scheduling_info.first_host_check = temp_host->next_check;
	}

	if (test_scheduling == TRUE)
		gettimeofday(&tv[7], NULL);

	/* add scheduled host checks to event queue */
	for (temp_host = host_list; temp_host != NULL; temp_host = temp_host->next) {

		/* update status of all hosts (scheduled or not) */
		update_host_status(temp_host, FALSE);

		/* skip most hosts that shouldn't be scheduled */
		if (temp_host->should_be_scheduled == FALSE) {

			/* passive checks are an exception if a forced check was scheduled before Nagios was restarted */
			if (!(temp_host->checks_enabled == FALSE && temp_host->next_check != (time_t)0L && (temp_host->check_options & CHECK_OPTION_FORCE_EXECUTION)))
				continue;
		}

		/* schedule a new host check event */
		temp_host->next_check_event = schedule_new_event(EVENT_HOST_CHECK, FALSE, temp_host->next_check, FALSE, 0, NULL, TRUE, (void *)temp_host, NULL, temp_host->check_options);
	}

	if (test_scheduling == TRUE)
		gettimeofday(&tv[8], NULL);


	/******** SCHEDULE MISC EVENTS ********/

	/* add a check result reaper event */
	schedule_new_event(EVENT_CHECK_REAPER, TRUE, current_time + check_reaper_interval, TRUE, check_reaper_interval, NULL, TRUE, NULL, NULL, 0);

	/* add an orphaned check event */
	if (check_orphaned_services == TRUE || check_orphaned_hosts == TRUE)
		schedule_new_event(EVENT_ORPHAN_CHECK, TRUE, current_time + DEFAULT_ORPHAN_CHECK_INTERVAL, TRUE, DEFAULT_ORPHAN_CHECK_INTERVAL, NULL, TRUE, NULL, NULL, 0);

	/* add a service result "freshness" check event */
	if (check_service_freshness == TRUE)
		schedule_new_event(EVENT_SFRESHNESS_CHECK, TRUE, current_time + service_freshness_check_interval, TRUE, service_freshness_check_interval, NULL, TRUE, NULL, NULL, 0);

	/* add a host result "freshness" check event */
	if (check_host_freshness == TRUE)
		schedule_new_event(EVENT_HFRESHNESS_CHECK, TRUE, current_time + host_freshness_check_interval, TRUE, host_freshness_check_interval, NULL, TRUE, NULL, NULL, 0);

	/* add a status save event */
	schedule_new_event(EVENT_STATUS_SAVE, TRUE, current_time + status_update_interval, TRUE, status_update_interval, NULL, TRUE, NULL, NULL, 0);

	/* add a retention data save event if needed */
	if (retain_state_information == TRUE && retention_update_interval > 0)
		schedule_new_event(EVENT_RETENTION_SAVE, TRUE, current_time + (retention_update_interval * 60), TRUE, (retention_update_interval * 60), NULL, TRUE, NULL, NULL, 0);

	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[2].tv_sec - tv[1].tv_sec) + (double)((tv[2].tv_usec - tv[1].tv_usec) / 1000.0) / 1000.0);
		runtime[2] = (double)((double)(tv[3].tv_sec - tv[2].tv_sec) + (double)((tv[3].tv_usec - tv[2].tv_usec) / 1000.0) / 1000.0);
		runtime[3] = (double)((double)(tv[4].tv_sec - tv[3].tv_sec) + (double)((tv[4].tv_usec - tv[3].tv_usec) / 1000.0) / 1000.0);
		runtime[4] = (double)((double)(tv[5].tv_sec - tv[4].tv_sec) + (double)((tv[5].tv_usec - tv[4].tv_usec) / 1000.0) / 1000.0);
		runtime[5] = (double)((double)(tv[6].tv_sec - tv[5].tv_sec) + (double)((tv[6].tv_usec - tv[5].tv_usec) / 1000.0) / 1000.0);
		runtime[6] = (double)((double)(tv[7].tv_sec - tv[6].tv_sec) + (double)((tv[7].tv_usec - tv[6].tv_usec) / 1000.0) / 1000.0);
		runtime[7] = (double)((double)(tv[8].tv_sec - tv[7].tv_sec) + (double)((tv[8].tv_usec - tv[7].tv_usec) / 1000.0) / 1000.0);

		runtime[8] = (double)((double)(tv[8].tv_sec - tv[0].tv_sec) + (double)((tv[8].tv_usec - tv[0].tv_usec) / 1000.0) / 1000.0);

		printf("EVENT SCHEDULING TIMES\n");
		printf("-------------------------------------\n");
		printf("Get service info:        %.6lf sec\n", runtime[0]);
		printf("Get host info info:      %.6lf sec\n", runtime[1]);
		printf("Get service params:      %.6lf sec\n", runtime[2]);
		printf("Schedule service times:  %.6lf sec\n", runtime[3]);
		printf("Schedule service events: %.6lf sec\n", runtime[4]);
		printf("Get host params:         %.6lf sec\n", runtime[5]);
		printf("Schedule host times:     %.6lf sec\n", runtime[6]);
		printf("Schedule host events:    %.6lf sec\n", runtime[7]);
		printf("                         ============\n");
		printf("TOTAL:                   %.6lf sec\n", runtime[8]);
		printf("\n\n");
	}

	log_debug_info(DEBUGL_FUNCTIONS, 0, "init_timing_loop() end\n");

	return;
}
Пример #6
0
static int should_run_event(timed_event *temp_event)
{
	int run_event = TRUE;	/* default action is to execute the event */
	int nudge_seconds = 0;

	/* we only care about jobs that cause processes to run */
	if (temp_event->event_type != EVENT_HOST_CHECK &&
	    temp_event->event_type != EVENT_SERVICE_CHECK) {
		return TRUE;
	}

	/* if we can't spawn any more jobs, don't bother */
	if (!wproc_can_spawn(&loadctl)) {
		wproc_reap(100, 3000);
		return FALSE;
	}

	/* run a few checks before executing a service check... */
	if (temp_event->event_type == EVENT_SERVICE_CHECK) {
		service *temp_service = (service *)temp_event->event_data;

		/* forced checks override normal check logic */
		if ((temp_service->check_options & CHECK_OPTION_FORCE_EXECUTION))
			return TRUE;

		/* don't run a service check if we're already maxed out on the number of parallel service checks...  */
		if (max_parallel_service_checks != 0 && (currently_running_service_checks >= max_parallel_service_checks)) {
			nudge_seconds = ranged_urand(5, 17);
			logit(NSLOG_RUNTIME_WARNING, TRUE, "\tMax concurrent service checks (%d) has been reached.  Nudging %s:%s by %d seconds...\n", max_parallel_service_checks, temp_service->host_name, temp_service->description, nudge_seconds);
			run_event = FALSE;
		}

		/* don't run a service check if active checks are disabled */
		if (execute_service_checks == FALSE) {
			log_debug_info(DEBUGL_EVENTS | DEBUGL_CHECKS, 1, "We're not executing service checks right now, so we'll skip check event for service '%s;%s'.\n", temp_service->host_name, temp_service->description);
			run_event = FALSE;
		}

		/* reschedule the check if we can't run it now */
		if (run_event == FALSE) {
			remove_event(nagios_squeue, temp_event);

			if (nudge_seconds) {
				/* We nudge the next check time when it is due to too many concurrent service checks */
				temp_service->next_check = (time_t)(temp_service->next_check + nudge_seconds);
			} else {
				temp_service->next_check += check_window(temp_service);
			}

			temp_event->run_time = temp_service->next_check;
			reschedule_event(nagios_squeue, temp_event);
			update_service_status(temp_service, FALSE);

			run_event = FALSE;
		}
	}
	/* run a few checks before executing a host check... */
	else if (temp_event->event_type == EVENT_HOST_CHECK) {
		host *temp_host = (host *)temp_event->event_data;

		/* forced checks override normal check logic */
		if ((temp_host->check_options & CHECK_OPTION_FORCE_EXECUTION))
			return TRUE;

		/* don't run a host check if active checks are disabled */
		if (execute_host_checks == FALSE) {
			log_debug_info(DEBUGL_EVENTS | DEBUGL_CHECKS, 1, "We're not executing host checks right now, so we'll skip host check event for host '%s'.\n", temp_host->name);
			run_event = FALSE;
		}

		/* reschedule the host check if we can't run it right now */
		if (run_event == FALSE) {
			remove_event(nagios_squeue, temp_event);
			temp_host->next_check += check_window(temp_host);
			temp_event->run_time = temp_host->next_check;
			reschedule_event(nagios_squeue, temp_event);
			update_host_status(temp_host, FALSE);
			run_event = FALSE;
		}
	}

	return run_event;
}
Пример #7
0
/* handles scheduled host or service downtime */
int handle_scheduled_downtime(scheduled_downtime *temp_downtime) {
	scheduled_downtime *this_downtime = NULL;
	host *hst = NULL;
	service *svc = NULL;
	time_t event_time = 0L;
	time_t current_time = 0L;
	unsigned long *new_downtime_id = NULL;
#ifdef USE_EVENT_BROKER
	int attr = 0;
#endif


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

	if (temp_downtime == NULL)
		return ERROR;

	/* find the host or service associated with this downtime */
	if (temp_downtime->type == HOST_DOWNTIME) {
		if ((hst = find_host(temp_downtime->host_name)) == NULL)
			return ERROR;
	} else {
		if ((svc = find_service(temp_downtime->host_name, temp_downtime->service_description)) == NULL)
			return ERROR;
	}

	/* if downtime if flexible and host/svc is in an ok state, don't do anything right now (wait for event handler to kick it off) */
	/* start_flex_downtime variable is set to TRUE by event handler functions */
	if (temp_downtime->fixed == FALSE) {

		/* we're not supposed to force a start of flex downtime... */
		if (temp_downtime->start_flex_downtime == FALSE) {

			/* host is up or service is ok, so we don't really do anything right now */
			if ((temp_downtime->type == HOST_DOWNTIME && hst->current_state == HOST_UP) || (temp_downtime->type == SERVICE_DOWNTIME && svc->current_state == STATE_OK)) {

				/* increment pending flex downtime counter */
				if (temp_downtime->type == HOST_DOWNTIME)
					hst->pending_flex_downtime++;
				else
					svc->pending_flex_downtime++;
				temp_downtime->incremented_pending_downtime = TRUE;

				/*** SINCE THE FLEX DOWNTIME MAY NEVER START, WE HAVE TO PROVIDE A WAY OF EXPIRING UNUSED DOWNTIME... ***/

				schedule_new_event(EVENT_EXPIRE_DOWNTIME, TRUE, (temp_downtime->end_time + 1), FALSE, 0, NULL, FALSE, NULL, NULL, 0);

				return OK;
			}
		}
	}

	time(&current_time);

	/* have we come to the end of the scheduled downtime? */
	if (temp_downtime->is_in_effect == TRUE && ( /* downtime needs to be in effect and ... */
		(temp_downtime->fixed == TRUE && current_time >= temp_downtime->end_time) || /* fixed downtime, endtime means end of downtime */
		(temp_downtime->fixed == FALSE && current_time >= (temp_downtime->trigger_time+temp_downtime->duration)) /* flexible downtime, endtime of downtime is trigger_time+duration */
	)){

		if (temp_downtime->type == HOST_DOWNTIME)
			log_debug_info(DEBUGL_DOWNTIME, 0, "Host '%s' ending %s scheduled downtime (id=%lu) with depth=%d, starttime=%lu, entrytime=%lu, triggertime=%lu, endtime=%lu, duration=%lu.\n", hst->name, (temp_downtime->fixed == TRUE) ? "fixed" : "flexible", temp_downtime->downtime_id, hst->scheduled_downtime_depth, temp_downtime->start_time, temp_downtime->entry_time, temp_downtime->trigger_time, temp_downtime->end_time, temp_downtime->duration);
		else
			log_debug_info(DEBUGL_DOWNTIME, 0, "Service '%s' on host '%s' ending %s scheduled downtime (id=%lu) with depth=%d, starttime=%lu, entrytime=%lu, triggertime=%lu, endtime=%lu, duration=%lu.\n", svc->description, svc->host_name, (temp_downtime->fixed == TRUE) ? "fixed" : "flexible", temp_downtime->downtime_id, svc->scheduled_downtime_depth, temp_downtime->start_time, temp_downtime->entry_time, temp_downtime->trigger_time, temp_downtime->end_time, temp_downtime->duration);


#ifdef USE_EVENT_BROKER
		/* send data to event broker */
		attr = NEBATTR_DOWNTIME_STOP_NORMAL;
		broker_downtime_data(NEBTYPE_DOWNTIME_STOP, NEBFLAG_NONE, attr, temp_downtime->type, temp_downtime->host_name, temp_downtime->service_description, temp_downtime->entry_time, temp_downtime->author, temp_downtime->comment, temp_downtime->start_time, temp_downtime->end_time, temp_downtime->fixed, temp_downtime->triggered_by, temp_downtime->duration, temp_downtime->downtime_id, NULL, temp_downtime->is_in_effect, temp_downtime->trigger_time);
#endif

		/* decrement the downtime depth variable */
		if (temp_downtime->type == HOST_DOWNTIME)
			hst->scheduled_downtime_depth--;
		else
			svc->scheduled_downtime_depth--;

		if (temp_downtime->type == HOST_DOWNTIME && hst->scheduled_downtime_depth == 0) {

			log_debug_info(DEBUGL_DOWNTIME, 0, "Host '%s' has exited from a period of scheduled downtime (id=%lu).\n", hst->name, temp_downtime->downtime_id);

			/* log a notice - this one is parsed by the history CGI */
			logit(NSLOG_INFO_MESSAGE, FALSE, "HOST DOWNTIME ALERT: %s;STOPPED; Host has exited from a period of scheduled downtime", hst->name);

			/* send a notification */
			host_notification(hst, NOTIFICATION_DOWNTIMEEND, temp_downtime->author, temp_downtime->comment, NOTIFICATION_OPTION_NONE);
		}

		else if (temp_downtime->type == SERVICE_DOWNTIME && svc->scheduled_downtime_depth == 0) {

			log_debug_info(DEBUGL_DOWNTIME, 0, "Service '%s' on host '%s' has exited from a period of scheduled downtime (id=%lu).\n", svc->description, svc->host_name, temp_downtime->downtime_id);

			/* log a notice - this one is parsed by the history CGI */
			logit(NSLOG_INFO_MESSAGE, FALSE, "SERVICE DOWNTIME ALERT: %s;%s;STOPPED; Service has exited from a period of scheduled downtime", svc->host_name, svc->description);

			/* send a notification */
			service_notification(svc, NOTIFICATION_DOWNTIMEEND, temp_downtime->author, temp_downtime->comment, NOTIFICATION_OPTION_NONE);
		}


		/* update the status data */
		if (temp_downtime->type == HOST_DOWNTIME)
			update_host_status(hst, FALSE);
		else
			update_service_status(svc, FALSE);

		/* decrement pending flex downtime if necessary */
		if (temp_downtime->fixed == FALSE && temp_downtime->incremented_pending_downtime == TRUE) {
			if (temp_downtime->type == HOST_DOWNTIME) {
				if (hst->pending_flex_downtime > 0)
					hst->pending_flex_downtime--;
			} else {
				if (svc->pending_flex_downtime > 0)
					svc->pending_flex_downtime--;
			}
		}

		/* handle (stop) downtime that is triggered by this one */
		while (1) {

			/* list contents might change by recursive calls, so we use this inefficient method to prevent segfaults */
			for (this_downtime = scheduled_downtime_list; this_downtime != NULL; this_downtime = this_downtime->next) {
				if (this_downtime->triggered_by == temp_downtime->downtime_id) {
					handle_scheduled_downtime(this_downtime);
					break;
				}
			}

			if (this_downtime == NULL)
				break;
		}

		/* delete downtime entry */
		if (temp_downtime->type == HOST_DOWNTIME)
			delete_host_downtime(temp_downtime->downtime_id);
		else
			delete_service_downtime(temp_downtime->downtime_id);
	}

	/* else we are just starting the scheduled downtime */
	else {
		if (temp_downtime->type == HOST_DOWNTIME)
			log_debug_info(DEBUGL_DOWNTIME, 0, "Host '%s' starting %s scheduled downtime (id=%lu) with depth=%d, starttime=%lu, entrytime=%lu, endtime=%lu, duration=%lu.\n", hst->name, (temp_downtime->fixed == TRUE) ? "fixed" : "flexible", temp_downtime->downtime_id, hst->scheduled_downtime_depth, temp_downtime->start_time, temp_downtime->entry_time, temp_downtime->end_time, temp_downtime->duration);
		else
			log_debug_info(DEBUGL_DOWNTIME, 0, "Service '%s' on host '%s' starting %s scheduled downtime (id=%lu) with depth=%d, starttime=%lu, entrytime=%lu, endtime=%lu, duration=%lu.\n", svc->description, svc->host_name, (temp_downtime->fixed == TRUE) ? "fixed" : "flexible", temp_downtime->downtime_id, svc->scheduled_downtime_depth, temp_downtime->start_time, temp_downtime->entry_time, temp_downtime->end_time, temp_downtime->duration);

		/* this happens after restart of icinga */
		if (temp_downtime->is_in_effect != TRUE) {
			if (temp_downtime->type == HOST_DOWNTIME && hst->scheduled_downtime_depth == 0) {

				/* set the trigger time, needed to detect the end of a flexible downtime */
				temp_downtime->trigger_time = current_time;

				log_debug_info(DEBUGL_DOWNTIME, 0, "Host '%s' has entered a period of scheduled downtime (id=%lu) at triggertime=%lu.\n", hst->name, temp_downtime->downtime_id, temp_downtime->trigger_time);

				/* log a notice - this one is parsed by the history CGI */
				logit(NSLOG_INFO_MESSAGE, FALSE, "HOST DOWNTIME ALERT: %s;STARTED; Host has entered a period of scheduled downtime", hst->name);

				/* send a notification */
				host_notification(hst, NOTIFICATION_DOWNTIMESTART, temp_downtime->author, temp_downtime->comment, NOTIFICATION_OPTION_NONE);
			}

			else if (temp_downtime->type == SERVICE_DOWNTIME && svc->scheduled_downtime_depth == 0) {

				/* set the trigger time, needed to detect the end of a flexible downtime */
				temp_downtime->trigger_time = current_time;

				log_debug_info(DEBUGL_DOWNTIME, 0, "Service '%s' on host '%s' has entered a period of scheduled downtime (id=%lu) at triggertime=%lu.\n", svc->description, svc->host_name, temp_downtime->downtime_id, temp_downtime->trigger_time);

				/* log a notice - this one is parsed by the history CGI */
				logit(NSLOG_INFO_MESSAGE, FALSE, "SERVICE DOWNTIME ALERT: %s;%s;STARTED; Service has entered a period of scheduled downtime", svc->host_name, svc->description);

				/* send a notification */
				service_notification(svc, NOTIFICATION_DOWNTIMESTART, temp_downtime->author, temp_downtime->comment, NOTIFICATION_OPTION_NONE);
			}
		}

		/* increment the downtime depth variable */
		if (temp_downtime->type == HOST_DOWNTIME)
			hst->scheduled_downtime_depth++;
		else
			svc->scheduled_downtime_depth++;

		/* set the in effect flag */
		temp_downtime->is_in_effect = TRUE;

#ifdef USE_EVENT_BROKER
		/* send data to broker AFTER we know trigger_time, is_in_effect, and downtime_depth */
		broker_downtime_data(NEBTYPE_DOWNTIME_START, NEBFLAG_NONE, NEBATTR_NONE, temp_downtime->type, temp_downtime->host_name, temp_downtime->service_description, temp_downtime->entry_time, temp_downtime->author, temp_downtime->comment, temp_downtime->start_time, temp_downtime->end_time, temp_downtime->fixed, temp_downtime->triggered_by, temp_downtime->duration, temp_downtime->downtime_id, NULL, temp_downtime->is_in_effect, temp_downtime->trigger_time);
#endif
		/* update the status data */
		if (temp_downtime->type == HOST_DOWNTIME)
			update_host_status(hst, FALSE);
		else
			update_service_status(svc, FALSE);

		/* schedule an event */
		if (temp_downtime->fixed == FALSE)
			event_time = (time_t)((unsigned long)time(NULL) + temp_downtime->duration);
		else
			event_time = temp_downtime->end_time;

		if ((new_downtime_id = (unsigned long *)malloc(sizeof(unsigned long *)))) {
			*new_downtime_id = temp_downtime->downtime_id;
			schedule_new_event(EVENT_SCHEDULED_DOWNTIME, TRUE, event_time, FALSE, 0, NULL, FALSE, (void *)new_downtime_id, NULL, 0);
		}

		/* handle (start) downtime that is triggered by this one */
		for (this_downtime = scheduled_downtime_list; this_downtime != NULL; this_downtime = this_downtime->next) {
			if (this_downtime->triggered_by == temp_downtime->downtime_id)
				handle_scheduled_downtime(this_downtime);
		}
	}

	return OK;
}
Пример #8
0
/* unschedules a host or service downtime */
int unschedule_downtime(int type, unsigned long downtime_id) {
	scheduled_downtime *temp_downtime = NULL;
	scheduled_downtime *next_downtime = NULL;
	host *hst = NULL;
	service *svc = NULL;
	timed_event *temp_event = NULL;
#ifdef USE_EVENT_BROKER
	int attr = 0;
#endif

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

	/* find the downtime entry in the list in memory */
	if ((temp_downtime = find_downtime(type, downtime_id)) == NULL)
		return ERROR;

	/* find the host or service associated with this downtime */
	if (temp_downtime->type == HOST_DOWNTIME) {
		if ((hst = find_host(temp_downtime->host_name)) == NULL)
			return ERROR;
	} else {
		if ((svc = find_service(temp_downtime->host_name, temp_downtime->service_description)) == NULL)
			return ERROR;
	}

	/* decrement pending flex downtime if necessary ... */
	if (temp_downtime->fixed == FALSE && temp_downtime->incremented_pending_downtime == TRUE) {
		if (temp_downtime->type == HOST_DOWNTIME)
			hst->pending_flex_downtime--;
		else
			svc->pending_flex_downtime--;
	}

    log_debug_info(DEBUGL_DOWNTIME, 0, "Cancelling %s downtime (id=%lu)\n", temp_downtime->type == HOST_DOWNTIME ? "host" : "service", temp_downtime->downtime_id);

	/* decrement the downtime depth variable and update status data if necessary */
	if (temp_downtime->is_in_effect == TRUE) {

#ifdef USE_EVENT_BROKER
		/* send data to event broker */
		attr = NEBATTR_DOWNTIME_STOP_CANCELLED;
		broker_downtime_data(NEBTYPE_DOWNTIME_STOP, NEBFLAG_NONE, attr, temp_downtime->type, temp_downtime->host_name, temp_downtime->service_description, temp_downtime->entry_time, temp_downtime->author, temp_downtime->comment, temp_downtime->start_time, temp_downtime->end_time, temp_downtime->fixed, temp_downtime->triggered_by, temp_downtime->duration, temp_downtime->downtime_id, NULL, temp_downtime->is_in_effect, temp_downtime->trigger_time);
#endif

		if (temp_downtime->type == HOST_DOWNTIME) {

			hst->scheduled_downtime_depth--;
			update_host_status(hst, FALSE);

			/* log a notice - this is parsed by the history CGI */
			if (hst->scheduled_downtime_depth == 0) {

				logit(NSLOG_INFO_MESSAGE, FALSE, "HOST DOWNTIME ALERT: %s;CANCELLED; Scheduled downtime for host has been cancelled.\n", hst->name);

				/* send a notification */
				host_notification(hst, NOTIFICATION_DOWNTIMECANCELLED, NULL, NULL, NOTIFICATION_OPTION_NONE);
			}
		}

		else {

			svc->scheduled_downtime_depth--;
			update_service_status(svc, FALSE);

			/* log a notice - this is parsed by the history CGI */
			if (svc->scheduled_downtime_depth == 0) {

				logit(NSLOG_INFO_MESSAGE, FALSE, "SERVICE DOWNTIME ALERT: %s;%s;CANCELLED; Scheduled downtime for service has been cancelled.\n", svc->host_name, svc->description);

				/* send a notification */
				service_notification(svc, NOTIFICATION_DOWNTIMECANCELLED, NULL, NULL, NOTIFICATION_OPTION_NONE);
			}
		}
	}

	/* remove scheduled entry from event queue */
	for (temp_event = event_list_high; temp_event != NULL; temp_event = temp_event->next) {
		if (temp_event->event_type != EVENT_SCHEDULED_DOWNTIME)
			continue;
		if (((unsigned long)temp_event->event_data) == downtime_id)
			break;
	}
	if (temp_event != NULL) {
		remove_event(temp_event, &event_list_high, &event_list_high_tail);
		my_free(temp_event->event_data);
		my_free(temp_event);
	}

	/* delete downtime entry */
	if (temp_downtime->type == HOST_DOWNTIME)
		delete_host_downtime(downtime_id);
	else
		delete_service_downtime(downtime_id);

	/* unschedule all downtime entries that were triggered by this one */
	while (1) {

		for (temp_downtime = scheduled_downtime_list; temp_downtime != NULL; temp_downtime = next_downtime) {
			next_downtime = temp_downtime->next;
			if (temp_downtime->triggered_by == downtime_id) {
				unschedule_downtime(ANY_DOWNTIME, temp_downtime->downtime_id);
				break;
			}
		}

		if (temp_downtime == NULL)
			break;
	}

	return OK;
}
Пример #9
0
/* handles scheduled host or service downtime */
int handle_scheduled_downtime(scheduled_downtime *temp_downtime) {
	scheduled_downtime *this_downtime = NULL;
	host *hst = NULL;
	service *svc = NULL;
	time_t event_time = 0L;
	unsigned long *new_downtime_id = NULL;
#ifdef USE_EVENT_BROKER
	int attr = 0;
#endif


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

	if(temp_downtime == NULL)
		return ERROR;

	/* find the host or service associated with this downtime */
	if(temp_downtime->type == HOST_DOWNTIME) {
		if((hst = find_host(temp_downtime->host_name)) == NULL) {
			log_debug_info(DEBUGL_DOWNTIME, 1, "Unable to find host (%s) for downtime\n", temp_downtime->host_name);
			return ERROR;
			}
		}
	else {
		if((svc = find_service(temp_downtime->host_name, temp_downtime->service_description)) == NULL) {
			log_debug_info(DEBUGL_DOWNTIME, 1, "Unable to find service (%s) host (%s) for downtime\n", temp_downtime->service_description, temp_downtime->host_name);
			return ERROR;
			}
		}

	/* have we come to the end of the scheduled downtime? */
	if(temp_downtime->is_in_effect == TRUE) {

#ifdef USE_EVENT_BROKER
		/* send data to event broker */
		attr = NEBATTR_DOWNTIME_STOP_NORMAL;
		broker_downtime_data(NEBTYPE_DOWNTIME_STOP, NEBFLAG_NONE, attr, temp_downtime->type, temp_downtime->host_name, temp_downtime->service_description, temp_downtime->entry_time, temp_downtime->author, temp_downtime->comment, temp_downtime->start_time, temp_downtime->end_time, temp_downtime->fixed, temp_downtime->triggered_by, temp_downtime->duration, temp_downtime->downtime_id, NULL);
#endif

		/* decrement the downtime depth variable */
		if(temp_downtime->type == HOST_DOWNTIME && hst->scheduled_downtime_depth > 0)
			hst->scheduled_downtime_depth--;
		else if (svc->scheduled_downtime_depth > 0)
			svc->scheduled_downtime_depth--;

		if(temp_downtime->type == HOST_DOWNTIME && hst->scheduled_downtime_depth == 0) {

			log_debug_info(DEBUGL_DOWNTIME, 0, "Host '%s' has exited from a period of scheduled downtime (id=%lu).\n", hst->name, temp_downtime->downtime_id);

			/* log a notice - this one is parsed by the history CGI */
			logit(NSLOG_INFO_MESSAGE, FALSE, "HOST DOWNTIME ALERT: %s;STOPPED; Host has exited from a period of scheduled downtime", hst->name);

			/* send a notification */
			host_notification(hst, NOTIFICATION_DOWNTIMEEND, temp_downtime->author, temp_downtime->comment, NOTIFICATION_OPTION_NONE);
			}

		else if(temp_downtime->type == SERVICE_DOWNTIME && svc->scheduled_downtime_depth == 0) {

			log_debug_info(DEBUGL_DOWNTIME, 0, "Service '%s' on host '%s' has exited from a period of scheduled downtime (id=%lu).\n", svc->description, svc->host_name, temp_downtime->downtime_id);

			/* log a notice - this one is parsed by the history CGI */
			logit(NSLOG_INFO_MESSAGE, FALSE, "SERVICE DOWNTIME ALERT: %s;%s;STOPPED; Service has exited from a period of scheduled downtime", svc->host_name, svc->description);

			/* send a notification */
			service_notification(svc, NOTIFICATION_DOWNTIMEEND, temp_downtime->author, temp_downtime->comment, NOTIFICATION_OPTION_NONE);
			}


		/* update the status data */
		if(temp_downtime->type == HOST_DOWNTIME)
			update_host_status(hst, FALSE);
		else
			update_service_status(svc, FALSE);

		/* decrement pending flex downtime if necessary */
		if(temp_downtime->fixed == FALSE && temp_downtime->incremented_pending_downtime == TRUE) {
			if(temp_downtime->type == HOST_DOWNTIME) {
				if(hst->pending_flex_downtime > 0)
					hst->pending_flex_downtime--;
				}
			else {
				if(svc->pending_flex_downtime > 0)
					svc->pending_flex_downtime--;
				}
			}

		/* handle (stop) downtime that is triggered by this one */
		while(1) {

			/* list contents might change by recursive calls, so we use this inefficient method to prevent segfaults */
			for(this_downtime = scheduled_downtime_list; this_downtime != NULL; this_downtime = this_downtime->next) {
				if(this_downtime->triggered_by == temp_downtime->downtime_id) {
					handle_scheduled_downtime(this_downtime);
					break;
					}
				}

			if(this_downtime == NULL)
				break;
			}

		/* delete downtime entry */
		if(temp_downtime->type == HOST_DOWNTIME)
			delete_host_downtime(temp_downtime->downtime_id);
		else
			delete_service_downtime(temp_downtime->downtime_id);
		}

	/* else we are just starting the scheduled downtime */
	else {

#ifdef USE_EVENT_BROKER
		/* send data to event broker */
		broker_downtime_data(NEBTYPE_DOWNTIME_START, NEBFLAG_NONE, NEBATTR_NONE, temp_downtime->type, temp_downtime->host_name, temp_downtime->service_description, temp_downtime->entry_time, temp_downtime->author, temp_downtime->comment, temp_downtime->start_time, temp_downtime->end_time, temp_downtime->fixed, temp_downtime->triggered_by, temp_downtime->duration, temp_downtime->downtime_id, NULL);
#endif

		if(temp_downtime->type == HOST_DOWNTIME && hst->scheduled_downtime_depth == 0) {

			log_debug_info(DEBUGL_DOWNTIME, 0, "Host '%s' has entered a period of scheduled downtime (id=%lu).\n", hst->name, temp_downtime->downtime_id);

			/* log a notice - this one is parsed by the history CGI */
			logit(NSLOG_INFO_MESSAGE, FALSE, "HOST DOWNTIME ALERT: %s;STARTED; Host has entered a period of scheduled downtime", hst->name);

			/* send a notification */
			if( FALSE == temp_downtime->start_notification_sent) {
				host_notification(hst, NOTIFICATION_DOWNTIMESTART, temp_downtime->author, temp_downtime->comment, NOTIFICATION_OPTION_NONE);
				temp_downtime->start_notification_sent = TRUE;
				}
			}

		else if(temp_downtime->type == SERVICE_DOWNTIME && svc->scheduled_downtime_depth == 0) {

			log_debug_info(DEBUGL_DOWNTIME, 0, "Service '%s' on host '%s' has entered a period of scheduled downtime (id=%lu).\n", svc->description, svc->host_name, temp_downtime->downtime_id);

			/* log a notice - this one is parsed by the history CGI */
			logit(NSLOG_INFO_MESSAGE, FALSE, "SERVICE DOWNTIME ALERT: %s;%s;STARTED; Service has entered a period of scheduled downtime", svc->host_name, svc->description);

			/* send a notification */
			if( FALSE == temp_downtime->start_notification_sent) {
				service_notification(svc, NOTIFICATION_DOWNTIMESTART, temp_downtime->author, temp_downtime->comment, NOTIFICATION_OPTION_NONE);
				temp_downtime->start_notification_sent = TRUE;
				}
			}

		/* increment the downtime depth variable */
		if(temp_downtime->type == HOST_DOWNTIME)
			hst->scheduled_downtime_depth++;
		else
			svc->scheduled_downtime_depth++;

		/* set the in effect flag */
		temp_downtime->is_in_effect = TRUE;

		/* update the status data */
		if(temp_downtime->type == HOST_DOWNTIME)
			update_host_status(hst, FALSE);
		else
			update_service_status(svc, FALSE);

		/* schedule an event to end the downtime */
		if(temp_downtime->fixed == FALSE) {
			event_time = (time_t)((unsigned long)temp_downtime->flex_downtime_start
					+ temp_downtime->duration);
			}
		else {
			event_time = temp_downtime->end_time;
			}
		if((new_downtime_id = (unsigned long *)malloc(sizeof(unsigned long *)))) {
			*new_downtime_id = temp_downtime->downtime_id;
			schedule_new_event(EVENT_SCHEDULED_DOWNTIME, TRUE, event_time, FALSE, 0, NULL, FALSE, (void *)new_downtime_id, NULL, 0);
			}

		/* handle (start) downtime that is triggered by this one */
		for(this_downtime = scheduled_downtime_list; this_downtime != NULL; this_downtime = this_downtime->next) {
			if(this_downtime->triggered_by == temp_downtime->downtime_id)
				handle_scheduled_downtime(this_downtime);
			}
		}

	return OK;
	}
Пример #10
0
void poll_host(int host_id) {
    char query1[BUFSIZE];
    char query2[BUFSIZE];
    char *query3;
    char query4[BUFSIZE];
    char errstr[512];
    int num_rows;
    int host_status;
    int assert_fail = 0;
    char *poll_result = NULL;
    char logmessage[LOGSIZE];
    char update_sql[BUFSIZE];

    reindex_t *reindex;
    target_t *entry;
    host_t *host;
    ping_t *ping;

    MYSQL mysql;
    MYSQL_RES *result;
    MYSQL_ROW row;

    /* allocate host and ping structures with appropriate values */
    host = (host_t *) malloc(sizeof(host_t));
    ping = (ping_t *) malloc(sizeof(ping_t));

#ifndef OLD_MYSQL
    mysql_thread_init();
#endif

    snprintf(query1, sizeof(query1), "select action,hostname,snmp_community,snmp_version,snmp_username,snmp_password,rrd_name,rrd_path,arg1,arg2,arg3,local_data_id,rrd_num,snmp_port,snmp_timeout from poller_item where host_id=%i order by rrd_path,rrd_name", host_id);
    snprintf(query2, sizeof(query2), "select id, hostname,snmp_community,snmp_version,snmp_port,snmp_timeout,status,status_event_count,status_fail_date,status_rec_date,status_last_error,min_time,max_time,cur_time,avg_time,total_polls,failed_polls,availability from host where id=%i", host_id);
    snprintf(query4, sizeof(query4), "select data_query_id,action,op,assert_value,arg1 from poller_reindex where host_id=%i", host_id);

    db_connect(set.dbdb, &mysql);

    /* get data about this host */
    result = db_query(&mysql, query2);
    num_rows = (int)mysql_num_rows(result);

    if (num_rows != 1) {
        snprintf(logmessage, LOGSIZE, "Host[%i] ERROR: Unknown Host ID", host_id);
        cacti_log(logmessage);
        return;
    }

    row = mysql_fetch_row(result);

    /* populate host structure */
    host->id = atoi(row[0]);
    if (row[1] != NULL) snprintf(host->hostname, sizeof(host->hostname), "%s", row[1]);
    if (row[2] != NULL) snprintf(host->snmp_community, sizeof(host->snmp_community), "%s", row[2]);
    host->snmp_version = atoi(row[3]);
    host->snmp_port = atoi(row[4]);
    host->snmp_timeout = atoi(row[5]);
    if (row[6] != NULL) host->status = atoi(row[6]);
    host->status_event_count = atoi(row[7]);
    snprintf(host->status_fail_date, sizeof(host->status_fail_date), "%s", row[8]);
    snprintf(host->status_rec_date, sizeof(host->status_rec_date), "%s", row[9]);
    snprintf(host->status_last_error, sizeof(host->status_last_error), "%s", row[10]);
    host->min_time = atof(row[11]);
    host->max_time = atof(row[12]);
    host->cur_time = atof(row[13]);
    host->avg_time = atof(row[14]);
    host->total_polls = atoi(row[15]);
    host->failed_polls = atoi(row[16]);
    host->availability = atof(row[17]);

    host->ignore_host = 0;

    /* initialize SNMP */
    snmp_host_init(host);

    /* perform a check to see if the host is alive by polling it's SysDesc
     * if the host down from an snmp perspective, don't poll it.
     * function sets the ignore_host bit */
    if ((set.availability_method == AVAIL_SNMP) && (host->snmp_community == "")) {
        update_host_status(HOST_UP, host, ping, set.availability_method);

        if (set.verbose >= POLLER_VERBOSITY_MEDIUM) {
            snprintf(logmessage, LOGSIZE, "Host[%s] No host availability check possible for '%s'\n", host->id, host->hostname);
            cacti_log(logmessage);
        }
    } else {
        if (ping_host(host, ping) == HOST_UP) {
            update_host_status(HOST_UP, host, ping, set.availability_method);
        } else {
            host->ignore_host = 1;
            update_host_status(HOST_DOWN, host, ping, set.availability_method);
        }
    }

    /* update host table */
    snprintf(update_sql, sizeof(update_sql), "update host set status='%i',status_event_count='%i', status_fail_date='%s',status_rec_date='%s',status_last_error='%s',min_time='%f',max_time='%f',cur_time='%f',avg_time='%f',total_polls='%i',failed_polls='%i',availability='%.4f' where id='%i'\n",
             host->status,
             host->status_event_count,
             host->status_fail_date,
             host->status_rec_date,
             host->status_last_error,
             host->min_time,
             host->max_time,
             host->cur_time,
             host->avg_time,
             host->total_polls,
             host->failed_polls,
             host->availability,
             host->id);

    db_insert(&mysql, update_sql);

    /* do the reindex check for this host */
    if (!host->ignore_host) {
        reindex = (reindex_t *) malloc(sizeof(reindex_t));

        result = db_query(&mysql, query4);
        num_rows = (int)mysql_num_rows(result);

        if (num_rows > 0) {
            if (set.verbose == POLLER_VERBOSITY_DEBUG) {
                snprintf(logmessage, LOGSIZE, "Host[%i] RECACHE: Processing %i items in the auto reindex cache for '%s'\n", host->id, num_rows, host->hostname);
                cacti_log(logmessage);
            }

            while ((row = mysql_fetch_row(result))) {
                assert_fail = 0;

                reindex->data_query_id = atoi(row[0]);
                reindex->action = atoi(row[1]);
                if (row[2] != NULL) snprintf(reindex->op, sizeof(reindex->op), "%s", row[2]);
                if (row[3] != NULL) snprintf(reindex->assert_value, sizeof(reindex->assert_value), "%s", row[3]);
                if (row[4] != NULL) snprintf(reindex->arg1, sizeof(reindex->arg1), "%s", row[4]);

                switch(reindex->action) {
                case POLLER_ACTION_SNMP: /* snmp */
                    poll_result = snmp_get(host, reindex->arg1);
                    break;
                case POLLER_ACTION_SCRIPT: /* script (popen) */
                    poll_result = exec_poll(host, reindex->arg1);
                    break;
                }

                /* assume ok if host is up and result wasn't obtained */
                if (!strcmp(poll_result,"U")) {
                    assert_fail = 0;
                } else if ((!strcmp(reindex->op, "=")) && (strcmp(reindex->assert_value,poll_result) != 0)) {
                    snprintf(logmessage, LOGSIZE, "ASSERT: '%s=%s' failed. Recaching host '%s', data query #%i\n", reindex->assert_value, poll_result, host->hostname, reindex->data_query_id);
                    cacti_log(logmessage);

                    query3 = (char *)malloc(128);
                    snprintf(query3, 128, "insert into poller_command (poller_id,time,action,command) values (0,NOW(),%i,'%i:%i')", POLLER_COMMAND_REINDEX, host_id, reindex->data_query_id);
                    db_insert(&mysql, query3);
                    free(query3);

                    assert_fail = 1;
                } else if ((!strcmp(reindex->op, ">")) && (strtoll(reindex->assert_value, (char **)NULL, 10) <= strtoll(poll_result, (char **)NULL, 10))) {
                    snprintf(logmessage, LOGSIZE, "ASSERT: '%s>%s' failed. Recaching host '%s', data query #%i\n", reindex->assert_value, poll_result, host->hostname, reindex->data_query_id);
                    cacti_log(logmessage);

                    query3 = (char *)malloc(128);
                    snprintf(query3, 128, "insert into poller_command (poller_id,time,action,command) values (0,NOW(),%i,'%i:%i')", POLLER_COMMAND_REINDEX, host_id, reindex->data_query_id);
                    db_insert(&mysql, query3);
                    free(query3);

                    assert_fail = 1;
                } else if ((!strcmp(reindex->op, "<")) && (strtoll(reindex->assert_value, (char **)NULL, 10) >= strtoll(poll_result, (char **)NULL, 10))) {
                    snprintf(logmessage, LOGSIZE, "ASSERT: '%s<%s' failed. Recaching host '%s', data query #%i\n", reindex->assert_value, poll_result, host->hostname, reindex->data_query_id);
                    cacti_log(logmessage);

                    query3 = (char *)malloc(128);
                    snprintf(query3, 128, "insert into poller_command (poller_id,time,action,command) values (0,NOW(),%i,'%i:%i')", POLLER_COMMAND_REINDEX, host_id, reindex->data_query_id);
                    db_insert(&mysql, query3);
                    free(query3);

                    assert_fail = 1;
                }

                /* update 'poller_reindex' with the correct information if:
                 * 1) the assert fails
                 * 2) the OP code is > or < meaning the current value could have changed without causing
                 *     the assert to fail */
                if ((assert_fail == 1) || (!strcmp(reindex->op, ">")) || (!strcmp(reindex->op, ">"))) {
                    query3 = (char *)malloc(255);
                    snprintf(query3, 255, "update poller_reindex set assert_value='%s' where host_id='%i' and data_query_id='%i' and arg1='%s'", poll_result, host_id, reindex->data_query_id, reindex->arg1);
                    db_insert(&mysql, query3);
                    free(query3);
                }

                free(poll_result);
            }
        }
    }

    /* retreive each hosts polling items from poller cache */
    entry = (target_t *) malloc(sizeof(target_t));

    result = db_query(&mysql, query1);
    num_rows = (int)mysql_num_rows(result);

    while ((row = mysql_fetch_row(result)) && (!host->ignore_host)) {
        /* initialize monitored object */
        entry->target_id = 0;
        entry->action = atoi(row[0]);
        if (row[1] != NULL) snprintf(entry->hostname, sizeof(entry->hostname), "%s", row[1]);
        if (row[2] != NULL) {
            snprintf(entry->snmp_community, sizeof(entry->snmp_community), "%s", row[2]);
        } else {
            snprintf(entry->snmp_community, sizeof(entry->snmp_community), "%s", "");
        }
        entry->snmp_version = atoi(row[3]);
        if (row[4] != NULL) snprintf(entry->snmp_username, sizeof(entry->snmp_username), "%s", row[4]);
        if (row[5] != NULL) snprintf(entry->snmp_password, sizeof(entry->snmp_password), "%s", row[5]);
        if (row[6] != NULL) snprintf(entry->rrd_name, sizeof(entry->rrd_name), "%s", row[6]);
        if (row[7] != NULL) snprintf(entry->rrd_path, sizeof(entry->rrd_path), "%s", row[7]);
        if (row[8] != NULL) snprintf(entry->arg1, sizeof(entry->arg1), "%s", row[8]);
        if (row[9] != NULL) snprintf(entry->arg2, sizeof(entry->arg2), "%s", row[9]);
        if (row[10] != NULL) snprintf(entry->arg3, sizeof(entry->arg3), "%s", row[10]);
        entry->local_data_id = atoi(row[11]);
        entry->rrd_num = atoi(row[12]);
        entry->snmp_port = atoi(row[13]);
        entry->snmp_timeout = atoi(row[14]);
        snprintf(entry->result, sizeof(entry->result), "%s", "U");

        if (!host->ignore_host) {
            switch(entry->action) {
            case POLLER_ACTION_SNMP: /* raw SNMP poll */
                poll_result = snmp_get(host, entry->arg1);
                snprintf(entry->result, sizeof(entry->result), "%s", poll_result);
                free(poll_result);

                if (host->ignore_host) {
                    snprintf(logmessage, LOGSIZE, "Host[%i] ERROR: SNMP timeout detected [%i milliseconds], ignoring host '%s'\n", host_id, host->snmp_timeout, host->hostname);
                    cacti_log(logmessage);
                    snprintf(entry->result, sizeof(entry->result), "%s", "U");
                } else {
                    /* remove double or single quotes from string */
                    strncpy(entry->result, strip_quotes(entry->result), sizeof(entry->result));

                    /* detect erroneous non-numeric result */
                    if (!is_numeric(entry->result)) {
                        strncpy(errstr, entry->result,sizeof(errstr));
                        snprintf(logmessage, LOGSIZE, "Host[%i] WARNING: Result from SNMP not valid. Partial Result: %.20s...\n", host_id, errstr);
                        cacti_log(logmessage);
                        strncpy(entry->result, "U", sizeof(entry->result));
                    }
                }

                if (set.verbose >= POLLER_VERBOSITY_MEDIUM) {
                    snprintf(logmessage, LOGSIZE, "Host[%i] SNMP: v%i: %s, dsname: %s, oid: %s, value: %s\n", host_id, host->snmp_version, host->hostname, entry->rrd_name, entry->arg1, entry->result);
                    cacti_log(logmessage);
                }

                break;
            case POLLER_ACTION_SCRIPT: /* execute script file */
                poll_result = exec_poll(host, entry->arg1);
                snprintf(entry->result, sizeof(entry->result), "%s", poll_result);
                free(poll_result);

                /* remove double or single quotes from string */
                strncpy(entry->result, strip_quotes(entry->result), sizeof(entry->result));

                /* detect erroneous result. can be non-numeric */
                if (!validate_result(entry->result)) {
                    strncpy(errstr, (char *) strip_string_crlf(entry->result),sizeof(errstr));
                    snprintf(logmessage, LOGSIZE, "Host[%i] WARNING: Result from SCRIPT not valid. Partial Result: %.20s...\n", host_id, errstr);
                    cacti_log(logmessage);
                    strncpy(entry->result, "U", sizeof(entry->result));
                }

                if (set.verbose >= POLLER_VERBOSITY_MEDIUM) {
                    snprintf(logmessage, LOGSIZE, "Host[%i] SCRIPT: %s, output: %s\n", host_id, entry->arg1, entry->result);
                    cacti_log(logmessage);
                }

                break;
            case POLLER_ACTION_PHP_SCRIPT_SERVER: /* execute script server */
                poll_result = php_cmd(entry->arg1);
                snprintf(entry->result, sizeof(entry->result), "%s", poll_result);
                free(poll_result);

                /* remove double or single quotes from string */
                strncpy(entry->result, strip_quotes(entry->result), sizeof(entry->result));

                /* detect erroneous result. can be non-numeric */
                if (!validate_result(entry->result)) {
                    strncpy(errstr, entry->result, sizeof(errstr));
                    snprintf(logmessage, LOGSIZE, "Host[%i] WARNING: Result from SERVER not valid.  Partial Result: %.20s...\n", host_id, errstr);
                    cacti_log(logmessage);
                    strncpy(entry->result, "U", sizeof(entry->result));
                }

                if (set.verbose >= POLLER_VERBOSITY_MEDIUM) {
                    snprintf(logmessage, LOGSIZE, "Host[%i] SERVER: %s, output: %s\n", host_id, entry->arg1, entry->result);
                    cacti_log(logmessage);
                }

                break;
            default: /* unknown action, generate error */
                snprintf(logmessage, LOGSIZE, "Host[%i] ERROR: Unknown Poller Action: %s\n", host_id, entry->arg1);
                cacti_log(logmessage);

                break;
            }
        }

        if (entry->result != NULL) {
            /* format database insert string */
            query3 = (char *)malloc(sizeof(entry->result) + sizeof(entry->local_data_id) + 128);
            snprintf(query3, (sizeof(entry->result) + sizeof(entry->local_data_id) + 128), "insert into poller_output (local_data_id,rrd_name,time,output) values (%i,'%s','%s','%s')", entry->local_data_id, entry->rrd_name, start_datetime, entry->result);
            db_insert(&mysql, query3);
            free(query3);
        }
    }

    /* cleanup memory and prepare for function exit */
    snmp_host_cleanup(host);

    free(entry);
    free(host);
    free(ping);

    mysql_free_result(result);

#ifndef OLD_MYSQL
    mysql_thread_end();
#endif

    mysql_close(&mysql);

    if (set.verbose == POLLER_VERBOSITY_DEBUG) {
        snprintf(logmessage, LOGSIZE, "Host[%i] DEBUG: HOST COMPLETE: About to Exit Host Polling Thread Function\n", host_id);
        cacti_log(logmessage);
    }
}