示例#1
0
/* runs the host performance data command */
static int xpddefault_run_host_performance_data_command(nagios_macros *mac, host *hst)
{
	char *raw_command_line = NULL;
	char *processed_command_line = NULL;
	int result = OK;
	int macro_options = STRIP_ILLEGAL_MACRO_CHARS | ESCAPE_MACRO_CHARS;

	if (hst == NULL)
		return ERROR;

	/* we don't have a command */
	if (host_perfdata_command == NULL)
		return OK;

	get_raw_command_line_r(mac, host_perfdata_command_ptr, host_perfdata_command, &raw_command_line, macro_options);
	if (raw_command_line == NULL)
		return ERROR;

	log_debug_info(DEBUGL_PERFDATA, 2, "Raw host performance data command line: %s\n", raw_command_line);

	/* process any macros in the raw command line */
	process_macros_r(mac, raw_command_line, &processed_command_line, macro_options);
	nm_free(raw_command_line);
	if (!processed_command_line)
		return ERROR;

	log_debug_info(DEBUGL_PERFDATA, 2, "Processed host performance data command line: %s\n", processed_command_line);

	/* run the command */
	wproc_run_callback(processed_command_line, perfdata_timeout, xpddefault_perfdata_job_handler, NULL, mac);

	nm_free(processed_command_line);

	return result;
}
void destroy_hostescalation(hostescalation *this_hostescalation)
{
	contactsmember *this_contactsmember;
	/* free memory for the contact group members */
	contactgroupsmember *this_contactgroupsmember;
	if (!this_hostescalation)
		return;
	this_contactgroupsmember = this_hostescalation->contact_groups;

	while (this_contactgroupsmember != NULL) {
		contactgroupsmember *next_contactgroupsmember = this_contactgroupsmember->next;
		nm_free(this_contactgroupsmember);
		this_contactgroupsmember = next_contactgroupsmember;
	}

	/* free memory for contacts */
	this_contactsmember = this_hostescalation->contacts;
	while (this_contactsmember != NULL) {
		contactsmember *next_contactsmember = this_contactsmember->next;
		nm_free(this_contactsmember);
		this_contactsmember = next_contactsmember;
	}
	nm_free(this_hostescalation);
	num_objects.hostescalations--;
}
示例#3
0
/* handles service check results in an obsessive compulsive manner... */
int obsessive_compulsive_service_check_processor(service *svc)
{
	char *raw_command = NULL;
	char *processed_command = NULL;
	int macro_options = STRIP_ILLEGAL_MACRO_CHARS | ESCAPE_MACRO_CHARS;
	nagios_macros mac;
	struct obsessive_compulsive_job *ocj;

	if (svc == NULL)
		return ERROR;

	/* bail out if we shouldn't be obsessing */
	if (obsess_over_services == FALSE || svc->obsess == FALSE)
		return OK;

	/* if there is no valid command, exit */
	if (ocsp_command == NULL)
		return ERROR;

	/* update service macros */
	memset(&mac, 0, sizeof(mac));
	grab_service_macros_r(&mac, svc);

	get_raw_command_line_r(&mac, ocsp_command_ptr, ocsp_command, &raw_command, macro_options);
	if (raw_command == NULL) {
		clear_volatile_macros_r(&mac);
		return ERROR;
	}

	log_debug_info(DEBUGL_CHECKS, 2, "Raw obsessive compulsive service processor command line: %s\n", raw_command);

	/* process any macros in the raw command line */
	process_macros_r(&mac, raw_command, &processed_command, macro_options);
	nm_free(raw_command);
	if (processed_command == NULL) {
		clear_volatile_macros_r(&mac);
		return ERROR;
	}

	log_debug_info(DEBUGL_CHECKS, 2, "Processed obsessive compulsive service processor command line: %s\n", processed_command);

	/* run the command through a worker */
	ocj = nm_calloc(1,sizeof(struct obsessive_compulsive_job));
	ocj->hst = svc->host_ptr;
	ocj->svc = svc;
	if(ERROR == wproc_run_callback(processed_command, ocsp_timeout, obsessive_compulsive_job_handler, ocj, &mac)) {
		nm_log(NSLOG_RUNTIME_ERROR, "Unable to start OCSP job for service '%s on host '%s' to worker\n", svc->description, svc->host_ptr->name);
		free(ocj);
	}

	clear_volatile_macros_r(&mac);
	nm_free(processed_command);

	return OK;
}
示例#4
0
/* handles a host that is flapping */
void set_host_flap(host *hst, double percent_change, double high_threshold, double low_threshold)
{
	char *temp_buffer = NULL;

	if (hst == NULL)
		return;

	log_debug_info(DEBUGL_FLAPPING, 1, "Host '%s' started flapping!\n", hst->name);

	/* log a notice - this one is parsed by the history CGI */
	nm_log(NSLOG_RUNTIME_WARNING, "HOST FLAPPING ALERT: %s;STARTED; Host appears to have started flapping (%2.1f%% change > %2.1f%% threshold)\n", hst->name, percent_change, high_threshold);

	/* add a non-persistent comment to the host */
	nm_asprintf(&temp_buffer, "Notifications for this host are being suppressed because it was detected as having been flapping between different states (%2.1f%% change > %2.1f%% threshold).  When the host state stabilizes and the flapping stops, notifications will be re-enabled.", percent_change, high_threshold);
	add_new_host_comment(FLAPPING_COMMENT, hst->name, time(NULL), "(Naemon Process)", temp_buffer, 0, COMMENTSOURCE_INTERNAL, FALSE, (time_t)0, &(hst->flapping_comment_id));
	nm_free(temp_buffer);

	/* set the flapping indicator */
	hst->is_flapping = TRUE;

	broker_flapping_data(NEBTYPE_FLAPPING_START, NEBFLAG_NONE, NEBATTR_NONE, HOST_FLAPPING, hst, percent_change, high_threshold, low_threshold);

	/* see if we should check to send a recovery notification out when flapping stops */
	if (hst->current_state != STATE_UP && hst->current_notification_number > 0)
		hst->check_flapping_recovery_notification = TRUE;
	else
		hst->check_flapping_recovery_notification = FALSE;

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

	return;
}
示例#5
0
/* send event handler data to broker */
int broker_event_handler(int type, int flags, int attr, int eventhandler_type, void *data, int state, int state_type, struct timeval start_time, struct timeval end_time, double exectime, int timeout, int early_timeout, int retcode, char *cmd, char *cmdline, char *output)
{
	service *temp_service = NULL;
	host *temp_host = NULL;
	char *command_buf = NULL;
	char *command_name = NULL;
	char *command_args = NULL;
	nebstruct_event_handler_data ds;
	int return_code = OK;

	if (!(event_broker_options & BROKER_EVENT_HANDLERS))
		return return_code;

	if (data == NULL)
		return ERROR;

	/* get command name/args */
	if (cmd != NULL) {
		command_buf = nm_strdup(cmd);
		command_name = strtok(command_buf, "!");
		command_args = strtok(NULL, "\x0");
	}

	/* fill struct with relevant data */
	ds.type = type;
	ds.flags = flags;
	ds.attr = attr;
	get_broker_timestamp(&ds.timestamp);

	ds.eventhandler_type = eventhandler_type;
	if (eventhandler_type == SERVICE_EVENTHANDLER || eventhandler_type == GLOBAL_SERVICE_EVENTHANDLER) {
		temp_service = (service *)data;
		ds.host_name = temp_service->host_name;
		ds.service_description = temp_service->description;
	} else {
		temp_host = (host *)data;
		ds.host_name = temp_host->name;
		ds.service_description = NULL;
	}
	ds.object_ptr = data;
	ds.state = state;
	ds.state_type = state_type;
	ds.start_time = start_time;
	ds.end_time = end_time;
	ds.timeout = timeout;
	ds.command_name = command_name;
	ds.command_args = command_args;
	ds.command_line = cmdline;
	ds.early_timeout = early_timeout;
	ds.execution_time = exectime;
	ds.return_code = retcode;
	ds.output = output;

	/* make callbacks */
	return_code = neb_make_callbacks(NEBCALLBACK_EVENT_HANDLER_DATA, (void *)&ds);

	nm_free(command_buf);

	return return_code;
}
示例#6
0
/* send contact notification data to broker */
int broker_contact_notification_method_data(int type, int flags, int attr, int notification_type, int reason_type, struct timeval start_time, struct timeval end_time, void *data, contact *cntct, char *cmd, char *ack_author, char *ack_data, int escalated)
{
	nebstruct_contact_notification_method_data ds;
	host *temp_host = NULL;
	service *temp_service = NULL;
	char *command_buf = NULL;
	char *command_name = NULL;
	char *command_args = NULL;
	int return_code = OK;

	if (!(event_broker_options & BROKER_NOTIFICATIONS))
		return return_code;

	/* get command name/args */
	if (cmd != NULL) {
		command_buf = nm_strdup(cmd);
		command_name = strtok(command_buf, "!");
		command_args = strtok(NULL, "\x0");
	}

	/* fill struct with relevant data */
	ds.type = type;
	ds.flags = flags;
	ds.attr = attr;
	get_broker_timestamp(&ds.timestamp);

	ds.notification_type = notification_type;
	ds.start_time = start_time;
	ds.end_time = end_time;
	ds.reason_type = reason_type;
	ds.contact_name = cntct->name;
	ds.command_name = command_name;
	ds.command_args = command_args;
	if (notification_type == SERVICE_NOTIFICATION) {
		temp_service = (service *)data;
		ds.host_name = temp_service->host_name;
		ds.service_description = temp_service->description;
		ds.state = temp_service->current_state;
		ds.output = temp_service->plugin_output;
	} else {
		temp_host = (host *)data;
		ds.host_name = temp_host->name;
		ds.service_description = NULL;
		ds.state = temp_host->current_state;
		ds.output = temp_host->plugin_output;
	}
	ds.object_ptr = data;
	ds.contact_ptr = (void *)cntct;
	ds.ack_author = ack_author;
	ds.ack_data = ack_data;
	ds.escalated = escalated;

	/* make callbacks */
	return_code = neb_make_callbacks(NEBCALLBACK_CONTACT_NOTIFICATION_METHOD_DATA, (void *)&ds);

	nm_free(command_buf);

	return return_code;
}
示例#7
0
/* send service check data to broker */
int broker_service_check(int type, int flags, int attr, service *svc, int check_type, struct timeval start_time, struct timeval end_time, char *cmd, double latency, double exectime, int timeout, int early_timeout, int retcode, char *cmdline, check_result *cr)
{
	char *command_buf = NULL;
	char *command_name = NULL;
	char *command_args = NULL;
	nebstruct_service_check_data ds;
	int return_code = OK;

	if (!(event_broker_options & BROKER_SERVICE_CHECKS))
		return OK;

	if (svc == NULL)
		return ERROR;

	/* get command name/args */
	if (cmd != NULL) {
		command_buf = nm_strdup(cmd);
		command_name = strtok(command_buf, "!");
		command_args = strtok(NULL, "\x0");
	}

	/* fill struct with relevant data */
	ds.type = type;
	ds.flags = flags;
	ds.attr = attr;
	get_broker_timestamp(&ds.timestamp);

	ds.host_name = svc->host_name;
	ds.service_description = svc->description;
	ds.object_ptr = (void *)svc;
	ds.check_type = check_type;
	ds.current_attempt = svc->current_attempt;
	ds.max_attempts = svc->max_attempts;
	ds.state = svc->current_state;
	ds.state_type = svc->state_type;
	ds.timeout = timeout;
	ds.command_name = command_name;
	ds.command_args = command_args;
	ds.command_line = cmdline;
	ds.start_time = start_time;
	ds.end_time = end_time;
	ds.early_timeout = early_timeout;
	ds.execution_time = exectime;
	ds.latency = latency;
	ds.return_code = retcode;
	ds.output = svc->plugin_output;
	ds.long_output = svc->long_plugin_output;
	ds.perf_data = svc->perf_data;
	ds.check_result_ptr = cr;

	/* make callbacks */
	return_code = neb_make_callbacks(NEBCALLBACK_SERVICE_CHECK_DATA, (void *)&ds);

	/* free data */
	nm_free(command_buf);

	return return_code;
}
示例#8
0
/* cleanup status data before terminating */
int xsddefault_cleanup_status_data(int delete_status_data)
{
	int return_code = OK;

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

	nm_free(status_file);

	return return_code;
}
void destroy_serviceescalation(serviceescalation *this_serviceescalation)
{
	contactsmember *this_contactsmember;
	contactgroupsmember *this_contactgroupsmember;
	if (!this_serviceescalation)
		return;

	this_contactgroupsmember = this_serviceescalation->contact_groups;
	while (this_contactgroupsmember != NULL) {
		contactgroupsmember *next_contactgroupsmember = this_contactgroupsmember->next;
		nm_free(this_contactgroupsmember);
		this_contactgroupsmember = next_contactgroupsmember;
	}

	/* free memory for contacts */
	this_contactsmember = this_serviceescalation->contacts;
	while (this_contactsmember != NULL) {
		contactsmember *next_contactsmember = this_contactsmember->next;
		nm_free(this_contactsmember);
		this_contactsmember = next_contactsmember;
	}
	nm_free(this_serviceescalation);
	num_objects.serviceescalations--;
}
示例#10
0
void destroy_objects_host()
{
	unsigned int i;
	for (i = 0; i < num_objects.hosts; i++) {
		host *this_host = host_ary[i];
		destroy_host(this_host);
	}
	host_list = NULL;
	if (host_hash_table)
		g_hash_table_destroy(host_hash_table);

	host_hash_table = NULL;
	nm_free(host_ary);
	num_objects.hosts = 0;
}
示例#11
0
void destroy_objects_service()
{
    unsigned int i;
    for (i = 0; i < num_objects.services; i++) {
        service *this_service = service_ary[i];
        destroy_service(this_service);
    }
    service_list = NULL;
    if (service_hash_table)
        g_hash_table_destroy(service_hash_table);

    service_hash_table = NULL;
    nm_free(service_ary);
    num_objects.services = 0;
}
示例#12
0
void destroy_objects_timeperiod()
{
	unsigned int i;
	for (i = 0; i < num_objects.timeperiods; i++) {
		timeperiod *this_timeperiod = timeperiod_ary[i];
		destroy_timeperiod(this_timeperiod);
	}
	timeperiod_list = NULL;
	if (timeperiod_hash_table)
		g_hash_table_destroy(timeperiod_hash_table);

	timeperiod_hash_table = NULL;
	nm_free(timeperiod_ary);
	num_objects.timeperiods = 0;
}
示例#13
0
void play(int s)
{
  int id;
  char buf[46] = {0};

  id = nm_alloc(s, 100);

  nm_write(s, id, "Sale CON (ref: Carmageddon)\n", 0, 28);

  nm_write(s, id, "You damned sucker\n", 27, 18);

  nm_read(s, id, buf, 0, 46);
  write(1, buf, 46);

  nm_free(s, id);
}
示例#14
0
static void qh_remove(struct query_handler *qh)
{
	struct query_handler *next, *prev;
	if (!qh)
		return;

	next = qh->next_qh;
	prev = qh->prev_qh;
	if (next)
		next->prev_qh = prev;
	if (prev)
		prev->next_qh = next;
	else
		qhandlers = next;

	nm_free(qh);
}
示例#15
0
void destroy_timeperiod(timeperiod *this_timeperiod)
{
	int x;
	timeperiodexclusion *this_timeperiodexclusion, *next_timeperiodexclusion;

	if (!this_timeperiod)
		return;
	/* free the exception time ranges contained in this timeperiod */
	for (x = 0; x < DATERANGE_TYPES; x++) {
		daterange *this_daterange, *next_daterange;
		for (this_daterange = this_timeperiod->exceptions[x]; this_daterange != NULL; this_daterange = next_daterange) {
			timerange *this_timerange, *next_timerange;
			next_daterange = this_daterange->next;
			for (this_timerange = this_daterange->times; this_timerange != NULL; this_timerange = next_timerange) {
				next_timerange = this_timerange->next;
				nm_free(this_timerange);
			}
			nm_free(this_daterange);
		}
	}

	/* free the day time ranges contained in this timeperiod */
	for (x = 0; x < 7; x++) {
		timerange *this_timerange, *next_timerange;
		for (this_timerange = this_timeperiod->days[x]; this_timerange != NULL; this_timerange = next_timerange) {
			next_timerange = this_timerange->next;
			nm_free(this_timerange);
		}
	}

	/* free exclusions */
	for (this_timeperiodexclusion = this_timeperiod->exclusions; this_timeperiodexclusion != NULL; this_timeperiodexclusion = next_timeperiodexclusion) {
		next_timeperiodexclusion = this_timeperiodexclusion->next;
		nm_free(this_timeperiodexclusion->timeperiod_name);
		nm_free(this_timeperiodexclusion);
	}

	if (this_timeperiod->alias != this_timeperiod->name)
		nm_free(this_timeperiod->alias);
	nm_free(this_timeperiod->name);
	nm_free(this_timeperiod);
}
示例#16
0
/* cleans up performance data */
int cleanup_performance_data(void)
{
	nm_free(host_perfdata_command);
	nm_free(service_perfdata_command);
	nm_free(host_perfdata_file_template);
	nm_free(service_perfdata_file_template);
	nm_free(host_perfdata_file);
	nm_free(service_perfdata_file);
	nm_free(host_perfdata_file_processing_command);
	nm_free(service_perfdata_file_processing_command);
	// one last attempt to write what remains buffered, just in case:
	flush_perfdata(host_perfdata_bq, host_perfdata_fd, host_perfdata_file);
	flush_perfdata(service_perfdata_bq, service_perfdata_fd, service_perfdata_file);
	close(host_perfdata_fd);
	host_perfdata_fd = -1;
	close(service_perfdata_fd);
	service_perfdata_fd = -1;
	nm_bufferqueue_destroy(host_perfdata_bq);
	host_perfdata_bq = NULL;
	nm_bufferqueue_destroy(service_perfdata_bq);
	service_perfdata_bq = NULL;

	return OK;
}
示例#17
0
/* initialize status data */
int xsddefault_initialize_status_data(const char *cfgfile)
{
	nagios_macros *mac;

	/* initialize locations if necessary */
	if (!status_file)
		status_file = nm_strdup(get_default_status_file());

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

	mac = get_global_macros();
	/* save the status file macro */
	nm_free(mac->x[MACRO_STATUSDATAFILE]);
	mac->x[MACRO_STATUSDATAFILE] = nm_strdup(status_file);
	strip(mac->x[MACRO_STATUSDATAFILE]);

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

	return OK;
}
示例#18
0
/* write all status data to file */
int xsddefault_save_status_data(void)
{
	char *tmp_log = 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 result = OK;

	/* users may not want us to write status data */
	if (!status_file || !strcmp(status_file, "/dev/null"))
		return OK;

	nm_asprintf(&tmp_log, "%sXXXXXX", temp_file);
	if (tmp_log == NULL)
		return ERROR;

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

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

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

		nm_free(tmp_log);

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

		close(fd);
		unlink(tmp_log);

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

		nm_free(tmp_log);

		return ERROR;
	}

	/* generate check statistics */
	generate_check_stats();

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

	time(&current_time);

	/* write file info */
	fprintf(fp, "info {\n");
	fprintf(fp, "\tcreated=%lu\n", current_time);
	fprintf(fp, "\tversion=" VERSION "\n");
	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, "\tnagios_pid=%d\n", nagios_pid);
	fprintf(fp, "\tdaemon_mode=%d\n", daemon_mode);
	fprintf(fp, "\tprogram_start=%lu\n", program_start);
	fprintf(fp, "\tlast_log_rotation=%lu\n", last_log_rotation);
	fprintf(fp, "\tenable_notifications=%d\n", enable_notifications);
	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, "\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, "\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->check_command == NULL) ? "" : temp_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, "\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_notification);
		fprintf(fp, "\tnext_notification=%lu\n", temp_host->next_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);
		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, "\tactive_checks_enabled=%d\n", temp_host->checks_enabled);
		fprintf(fp, "\tpassive_checks_enabled=%d\n", temp_host->accept_passive_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, "\tprocess_performance_data=%d\n", temp_host->process_performance_data);
		fprintf(fp, "\tobsess=%d\n", temp_host->obsess);
		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);
		/* 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->check_command == NULL) ? "" : temp_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, "\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);
		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_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, "\tflap_detection_enabled=%d\n", temp_service->flap_detection_enabled);
		fprintf(fp, "\tprocess_performance_data=%d\n", temp_service->process_performance_data);
		fprintf(fp, "\tobsess=%d\n", temp_service->obsess);
		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);
		/* 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, "\tcomment_id=%lu\n", temp_downtime->comment_id);
		fprintf(fp, "\tentry_time=%lu\n", temp_downtime->entry_time);
		fprintf(fp, "\tstart_time=%lu\n", temp_downtime->start_time);
		fprintf(fp, "\tflex_downtime_start=%lu\n", temp_downtime->flex_downtime_start);
		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, "\tstart_notification_sent=%d\n", temp_downtime->start_notification_sent);
		fprintf(fp, "\tauthor=%s\n", temp_downtime->author);
		fprintf(fp, "\tcomment=%s\n", temp_downtime->comment);
		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(tmp_log, status_file)) {
			unlink(tmp_log);
			nm_log(NSLOG_RUNTIME_ERROR, "Error: Unable to update status data file '%s': %s", status_file, strerror(errno));
			result = ERROR;
		}
	}

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

		result = ERROR;

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

	nm_free(tmp_log);

	return result;
}
示例#19
0
static int qh_input(int sd, int events, void *bq_)
{
	nm_bufferqueue *bq = (nm_bufferqueue *)bq_;
	int result;
	size_t len;
	unsigned int query_len = 0;
	char *buf, *space;
	struct query_handler *qh;
	char *handler = NULL, *query = NULL;

	result = nm_bufferqueue_read(bq, sd);
	/* disconnect? */
	if (result == 0 || (result < 0 && errno == EPIPE)) {
		nm_bufferqueue_destroy(bq);
		iobroker_close(nagios_iobs, sd);
		qh_running--;
		return 0;
	}

	/*
	 * A request looks like this: '[@|#]<qh>[<SP>][<query>]\0'.
	 * That is, optional '#' (oneshot) or '@' (keepalive),
	 * followed by the name of a registered handler, followed by
	 * an optional space and an optional query. If the handler
	 * has no "default" handler, a query is required or an error
	 * will be thrown.
	 */

	/* Use data up to the first nul byte */
	nm_bufferqueue_unshift_to_delim(bq, "\0", 1, &len, (void **)&buf);
	if (!buf)
		return 0;

	/* Identify handler part and any magic query bytes */
	if (*buf == '@' || *buf == '#') {
		handler = buf + 1;
	} else {
		handler = buf;
	}

	/* Locate query (if any) */
	if ((space = strchr(buf, ' '))) {
		*space = 0;
		query = space + 1;
		query_len = len - ((unsigned long)query - (unsigned long)buf);
	} else {
		query = "";
		query_len = 0;
	}

	/* locate the handler */
	if (!(qh = qh_find_handler(handler))) {
		/* not found. that's a 404 */
		nsock_printf(sd, "404: %s: No such handler", handler);
		nm_free(buf);
		iobroker_close(nagios_iobs, sd);
		nm_bufferqueue_destroy(bq);
		return 0;
	}

	/* strip trailing newlines */
	while (query_len > 0 && (query[query_len - 1] == 0 || query[query_len - 1] == '\n'))
		query[--query_len] = 0;

	/* now pass the query to the handler */
	if ((result = qh->handler(sd, query, query_len)) >= 100) {
		nsock_printf_nul(sd, "%d: %s", result, qh_strerror(result));
	}

	if (result >= 300 || *buf != '@') {
		/* error code or one-shot query */
		nm_free(buf);
		iobroker_close(nagios_iobs, sd);
		nm_bufferqueue_destroy(bq);
		return 0;
	}
	nm_free(buf);

	/* check for magic handler codes */
	switch (result) {
	case QH_CLOSE: /* oneshot handler */
	case -1:       /* general error */
		iobroker_close(nagios_iobs, sd);
		/* fallthrough */
	case QH_TAKEOVER: /* handler takes over */
	case 101:         /* switch protocol (takeover + message) */
		nm_bufferqueue_destroy(bq);
		break;
	}
	return 0;
}
示例#20
0
/* runs a host event handler command */
static int run_host_event_handler(nagios_macros *mac, const host * const hst)
{
	char *raw_command = NULL;
	char *processed_command = NULL;
	char *raw_logentry = NULL;
	char *processed_logentry = NULL;
	char *command_output = NULL;
	int early_timeout = FALSE;
	double exectime = 0.0;
	int result = 0;
	struct timeval start_time;
	struct timeval end_time;
	int neb_result = OK;
	int macro_options = STRIP_ILLEGAL_MACRO_CHARS | ESCAPE_MACRO_CHARS;

	if (hst == NULL)
		return ERROR;

	/* bail if there's no command */
	if (hst->event_handler == NULL)
		return ERROR;

	log_debug_info(DEBUGL_EVENTHANDLERS, 1, "Running event handler for host '%s'..\n", hst->name);

	/* get start time */
	gettimeofday(&start_time, NULL);

	get_raw_command_line_r(mac, hst->event_handler_ptr, hst->event_handler, &raw_command, macro_options);
	if (raw_command == NULL)
		return ERROR;

	log_debug_info(DEBUGL_EVENTHANDLERS, 2, "Raw host event handler command line: %s\n", raw_command);

	/* process any macros in the raw command line */
	process_macros_r(mac, raw_command, &processed_command, macro_options);
	nm_free(raw_command);
	if (processed_command == NULL)
		return ERROR;

	log_debug_info(DEBUGL_EVENTHANDLERS, 2, "Processed host event handler command line: %s\n", processed_command);

	if (log_event_handlers == TRUE) {
		nm_asprintf(&raw_logentry, "HOST EVENT HANDLER: %s;$HOSTSTATE$;$HOSTSTATETYPE$;$HOSTATTEMPT$;%s\n", hst->name, hst->event_handler);
		process_macros_r(mac, raw_logentry, &processed_logentry, macro_options);
		nm_log(NSLOG_EVENT_HANDLER, "%s", processed_logentry);
	}

	end_time.tv_sec = 0L;
	end_time.tv_usec = 0L;
	neb_result = broker_event_handler(NEBTYPE_EVENTHANDLER_START, NEBFLAG_NONE, NEBATTR_NONE, HOST_EVENTHANDLER, (void *)hst, hst->current_state, hst->state_type, start_time, end_time, exectime, event_handler_timeout, early_timeout, result, hst->event_handler, processed_command, NULL);

	/* neb module wants to override (or cancel) the event handler - perhaps it will run the eventhandler itself */
	if (neb_result == NEBERROR_CALLBACKOVERRIDE) {
		nm_free(processed_command);
		nm_free(raw_logentry);
		nm_free(processed_logentry);
		return OK;
	}

	/* run the command through a worker */
	result = wproc_run_callback(processed_command, event_handler_timeout, event_handler_job_handler, "Host", mac);

	/* check to see if the event handler timed out */
	if (early_timeout == TRUE)
		nm_log(NSLOG_EVENT_HANDLER | NSLOG_RUNTIME_WARNING, "Warning: Host event handler command '%s' timed out after %d seconds\n", processed_command, event_handler_timeout);

	/* get end time */
	gettimeofday(&end_time, NULL);

	broker_event_handler(NEBTYPE_EVENTHANDLER_END, NEBFLAG_NONE, NEBATTR_NONE, HOST_EVENTHANDLER, (void *)hst, hst->current_state, hst->state_type, start_time, end_time, exectime, event_handler_timeout, early_timeout, result, hst->event_handler, processed_command, command_output);

	nm_free(command_output);
	nm_free(processed_command);
	nm_free(raw_logentry);
	nm_free(processed_logentry);

	return OK;
}
示例#21
0
/* runs the global service event handler */
static int run_global_service_event_handler(nagios_macros *mac, service *svc)
{
	char *raw_command = NULL;
	char *processed_command = NULL;
	char *raw_logentry = NULL;
	char *processed_logentry = NULL;
	char *command_output = NULL;
	int early_timeout = FALSE;
	double exectime = 0.0;
	int result = 0;
	struct timeval start_time;
	struct timeval end_time;
	int neb_result = OK;
	int macro_options = STRIP_ILLEGAL_MACRO_CHARS | ESCAPE_MACRO_CHARS;

	if (svc == NULL)
		return ERROR;

	/* bail out if we shouldn't be running event handlers */
	if (enable_event_handlers == FALSE)
		return OK;

	/* a global service event handler command has not been defined */
	if (global_service_event_handler == NULL)
		return ERROR;

	log_debug_info(DEBUGL_EVENTHANDLERS, 1, "Running global event handler for service '%s' on host '%s'...\n", svc->description, svc->host_name);

	/* get start time */
	gettimeofday(&start_time, NULL);

	get_raw_command_line_r(mac, global_service_event_handler_ptr, global_service_event_handler, &raw_command, macro_options);
	if (raw_command == NULL) {
		return ERROR;
	}

	log_debug_info(DEBUGL_EVENTHANDLERS, 2, "Raw global service event handler command line: %s\n", raw_command);

	/* process any macros in the raw command line */
	process_macros_r(mac, raw_command, &processed_command, macro_options);
	nm_free(raw_command);
	if (processed_command == NULL)
		return ERROR;

	log_debug_info(DEBUGL_EVENTHANDLERS, 2, "Processed global service event handler command line: %s\n", processed_command);

	if (log_event_handlers == TRUE) {
		nm_asprintf(&raw_logentry, "GLOBAL SERVICE EVENT HANDLER: %s;%s;$SERVICESTATE$;$SERVICESTATETYPE$;$SERVICEATTEMPT$;%s\n", svc->host_name, svc->description, global_service_event_handler);
		process_macros_r(mac, raw_logentry, &processed_logentry, macro_options);
		nm_log(NSLOG_EVENT_HANDLER, "%s", processed_logentry);
	}

	end_time.tv_sec = 0L;
	end_time.tv_usec = 0L;
	neb_result = broker_event_handler(NEBTYPE_EVENTHANDLER_START, NEBFLAG_NONE, NEBATTR_NONE, GLOBAL_SERVICE_EVENTHANDLER, (void *)svc, svc->current_state, svc->state_type, start_time, end_time, exectime, event_handler_timeout, early_timeout, result, global_service_event_handler, processed_command, NULL);

	/* neb module wants to override (or cancel) the event handler - perhaps it will run the eventhandler itself */
	if (neb_result == NEBERROR_CALLBACKOVERRIDE) {
		nm_free(processed_command);
		nm_free(raw_logentry);
		nm_free(processed_logentry);
		return OK;
	}

	/* run the command through a worker */
	result = wproc_run_callback(processed_command, event_handler_timeout, event_handler_job_handler, "Global service", mac);

	/* check to see if the event handler timed out */
	if (early_timeout == TRUE)
		nm_log(NSLOG_EVENT_HANDLER | NSLOG_RUNTIME_WARNING, "Warning: Global service event handler command '%s' timed out after %d seconds\n", processed_command, event_handler_timeout);

	/* get end time */
	gettimeofday(&end_time, NULL);

	broker_event_handler(NEBTYPE_EVENTHANDLER_END, NEBFLAG_NONE, NEBATTR_NONE, GLOBAL_SERVICE_EVENTHANDLER, (void *)svc, svc->current_state, svc->state_type, start_time, end_time, exectime, event_handler_timeout, early_timeout, result, global_service_event_handler, processed_command, command_output);

	nm_free(command_output);
	nm_free(processed_command);
	nm_free(raw_logentry);
	nm_free(processed_logentry);

	return OK;
}
示例#22
0
void destroy_service(service *this_service)
{
    struct contactgroupsmember *this_contactgroupsmember, *next_contactgroupsmember;
    struct contactsmember *this_contactsmember, *next_contactsmember;
    struct customvariablesmember *this_customvariablesmember, *next_customvariablesmember;
    struct objectlist *slavelist;

    if (!this_service)
        return;

    /* free memory for contact groups */
    this_contactgroupsmember = this_service->contact_groups;
    while (this_contactgroupsmember != NULL) {
        next_contactgroupsmember = this_contactgroupsmember->next;
        nm_free(this_contactgroupsmember);
        this_contactgroupsmember = next_contactgroupsmember;
    }

    /* free memory for contacts */
    this_contactsmember = this_service->contacts;
    while (this_contactsmember != NULL) {
        next_contactsmember = this_contactsmember->next;
        nm_free(this_contactsmember);
        this_contactsmember = next_contactsmember;
    }

    /* free memory for custom variables */
    this_customvariablesmember = this_service->custom_variables;
    while (this_customvariablesmember != NULL) {
        next_customvariablesmember = this_customvariablesmember->next;
        nm_free(this_customvariablesmember->variable_name);
        nm_free(this_customvariablesmember->variable_value);
        nm_free(this_customvariablesmember);
        this_customvariablesmember = next_customvariablesmember;
    }
    while (this_service->servicegroups_ptr)
        remove_service_from_servicegroup(this_service->servicegroups_ptr->object_ptr, this_service);

    for (slavelist = this_service->notify_deps; slavelist; slavelist = slavelist->next)
        destroy_servicedependency(slavelist->object_ptr);
    for (slavelist = this_service->exec_deps; slavelist; slavelist = slavelist->next)
        destroy_servicedependency(slavelist->object_ptr);
    for (slavelist = this_service->escalation_list; slavelist; slavelist = slavelist->next)
        destroy_serviceescalation(slavelist->object_ptr);

    if (this_service->display_name != this_service->description)
        nm_free(this_service->display_name);
    nm_free(this_service->description);
    nm_free(this_service->check_command);
    nm_free(this_service->plugin_output);
    nm_free(this_service->long_plugin_output);
    nm_free(this_service->perf_data);
    nm_free(this_service->event_handler_args);
    free_objectlist(&this_service->servicegroups_ptr);
    free_objectlist(&this_service->notify_deps);
    free_objectlist(&this_service->exec_deps);
    free_objectlist(&this_service->escalation_list);
    nm_free(this_service->event_handler);
    nm_free(this_service->notes);
    nm_free(this_service->notes_url);
    nm_free(this_service->action_url);
    nm_free(this_service->icon_image);
    nm_free(this_service->icon_image_alt);
    nm_free(this_service);
}
示例#23
0
void destroy_host(host *this_host)
{
	struct servicesmember *this_servicesmember, *next_servicesmember;
	struct contactgroupsmember *this_contactgroupsmember, *next_contactgroupsmember;
	struct contactsmember *this_contactsmember, *next_contactsmember;
	struct customvariablesmember *this_customvariablesmember, *next_customvariablesmember;
	struct objectlist *slavelist;

	if (!this_host)
		return;

	/* free memory for service links */
	this_servicesmember = this_host->services;
	while (this_servicesmember != NULL) {
		next_servicesmember = this_servicesmember->next;
		nm_free(this_servicesmember);
		this_servicesmember = next_servicesmember;
	}

	/* free memory for contact groups */
	this_contactgroupsmember = this_host->contact_groups;
	while (this_contactgroupsmember != NULL) {
		next_contactgroupsmember = this_contactgroupsmember->next;
		nm_free(this_contactgroupsmember);
		this_contactgroupsmember = next_contactgroupsmember;
	}

	/* free memory for contacts */
	this_contactsmember = this_host->contacts;
	while (this_contactsmember != NULL) {
		next_contactsmember = this_contactsmember->next;
		nm_free(this_contactsmember);
		this_contactsmember = next_contactsmember;
	}

	/* free memory for custom variables */
	this_customvariablesmember = this_host->custom_variables;
	while (this_customvariablesmember != NULL) {
		next_customvariablesmember = this_customvariablesmember->next;
		nm_free(this_customvariablesmember->variable_name);
		nm_free(this_customvariablesmember->variable_value);
		nm_free(this_customvariablesmember);
		this_customvariablesmember = next_customvariablesmember;
	}

	for (slavelist = this_host->notify_deps; slavelist; slavelist = slavelist->next)
		destroy_hostdependency(slavelist->object_ptr);
	for (slavelist = this_host->exec_deps; slavelist; slavelist = slavelist->next)
		destroy_hostdependency(slavelist->object_ptr);
	for (slavelist = this_host->escalation_list; slavelist; slavelist = slavelist->next)
		destroy_hostescalation(slavelist->object_ptr);
	while (this_host->hostgroups_ptr)
		remove_host_from_hostgroup(this_host->hostgroups_ptr->object_ptr, this_host);

	if (this_host->child_hosts) {
		struct host *curhost = NULL;
		do {
			curhost = NULL;
			g_tree_foreach(this_host->child_hosts, my_g_tree_visit_pick_one, &curhost);
			if(curhost) {
				remove_parent_from_host(curhost, this_host);
			}
		} while(curhost != NULL);
		g_tree_unref(this_host->child_hosts);
		this_host->child_hosts = NULL;
	}
	if (this_host->parent_hosts) {
		struct host *curhost = NULL;
		do {
			curhost = NULL;
			g_tree_foreach(this_host->parent_hosts, my_g_tree_visit_pick_one, &curhost);
			if(curhost) {
				remove_parent_from_host(this_host, curhost);
			}
		} while(curhost != NULL);
		g_tree_unref(this_host->parent_hosts);
		this_host->parent_hosts = NULL;
	}

	if (this_host->display_name != this_host->name)
		nm_free(this_host->display_name);
	if (this_host->alias != this_host->name)
		nm_free(this_host->alias);
	if (this_host->address != this_host->name)
		nm_free(this_host->address);
	nm_free(this_host->name);
	nm_free(this_host->plugin_output);
	nm_free(this_host->long_plugin_output);
	nm_free(this_host->perf_data);
	free_objectlist(&this_host->hostgroups_ptr);
	free_objectlist(&this_host->notify_deps);
	free_objectlist(&this_host->exec_deps);
	free_objectlist(&this_host->escalation_list);
	nm_free(this_host->check_command);
	nm_free(this_host->event_handler);
	nm_free(this_host->notes);
	nm_free(this_host->notes_url);
	nm_free(this_host->action_url);
	nm_free(this_host->icon_image);
	nm_free(this_host->icon_image_alt);
	nm_free(this_host->vrml_image);
	nm_free(this_host->statusmap_image);
	nm_free(this_host);
}
示例#24
0
/* free the memory allocated to the linked lists */
void free_memory(nagios_macros *mac)
{
	int i;
	objectlist *entry, *next;

	destroy_objects_command();
	destroy_objects_timeperiod();
	destroy_objects_host();
	destroy_objects_service();
	destroy_objects_contact();
	destroy_objects_contactgroup();
	destroy_objects_hostgroup();
	destroy_objects_servicegroup();

	free_comment_data();

	nm_free(global_host_event_handler);
	nm_free(global_service_event_handler);

	/* free obsessive compulsive commands */
	nm_free(ocsp_command);
	nm_free(ochp_command);

	nm_free(object_cache_file);
	nm_free(object_precache_file);

	/*
	 * free memory associated with macros.
	 * It's ok to only free the volatile ones, as the non-volatile
	 * are always free()'d before assignment if they're set.
	 * Doing a full free of them here means we'll wipe the constant
	 * macros when we get a reload or restart request through the
	 * command pipe, or when we receive a SIGHUP.
	 */
	clear_volatile_macros_r(mac);

	free_macrox_names();

	for (entry = objcfg_files; entry; entry = next) {
		next = entry->next;
		nm_free(entry->object_ptr);
		nm_free(entry);
	}
	objcfg_files = NULL;
	for (entry = objcfg_dirs; entry; entry = next) {
		next = entry->next;
		nm_free(entry->object_ptr);
		nm_free(entry);
	}
	objcfg_dirs = NULL;

	/* free illegal char strings */
	nm_free(illegal_object_chars);
	nm_free(illegal_output_chars);

	/* free file/path variables */
	nm_free(status_file);
	nm_free(debug_file);
	nm_free(log_file);
	mac->x[MACRO_LOGFILE] = NULL; /* assigned from 'log_file' */
	nm_free(temp_file);
	mac->x[MACRO_TEMPFILE] = NULL; /* assigned from temp_file */
	nm_free(temp_path);
	mac->x[MACRO_TEMPPATH] = NULL; /*assigned from temp_path */
	nm_free(check_result_path);
	nm_free(command_file);
	nm_free(qh_socket_path);
	mac->x[MACRO_COMMANDFILE] = NULL; /* assigned from command_file */
	nm_free(log_archive_path);

	for (i = 0; i < MAX_USER_MACROS; i++) {
		nm_free(macro_user[i]);
	}

	/* these have no other reference */
	nm_free(mac->x[MACRO_ADMINEMAIL]);
	nm_free(mac->x[MACRO_ADMINPAGER]);
	nm_free(mac->x[MACRO_RESOURCEFILE]);
	nm_free(mac->x[MACRO_OBJECTCACHEFILE]);
	nm_free(mac->x[MACRO_MAINCONFIGFILE]);

	return;
}
示例#25
0
int main(int argc, char **argv)
{
	int result;
	int error = FALSE;
	int display_license = FALSE;
	int display_help = FALSE;
	int c = 0;
	int allow_root = FALSE;
	struct tm *tm, tm_s;
	time_t now;
	char datestring[256];
	nagios_macros *mac;
	const char *worker_socket = NULL;
	int i;

#ifdef HAVE_GETOPT_H
	int option_index = 0;
	static struct option long_options[] = {
		{"help", no_argument, 0, 'h'},
		{"version", no_argument, 0, 'V'},
		{"license", no_argument, 0, 'V'},
		{"verify-config", no_argument, 0, 'v'},
		{"daemon", no_argument, 0, 'd'},
		{"precache-objects", no_argument, 0, 'p'},
		{"use-precached-objects", no_argument, 0, 'u'},
		{"enable-timing-point", no_argument, 0, 'T'},
		{"worker", required_argument, 0, 'W'},
		{"allow-root", no_argument, 0, 'R'},
		{0, 0, 0, 0}
	};
#define getopt(argc, argv, o) getopt_long(argc, argv, o, long_options, &option_index)
#endif

	/* make sure we have the correct number of command line arguments */
	if (argc < 2)
		error = TRUE;

	/* get all command line arguments */
	while (1) {
		c = getopt(argc, argv, "+hVvdspuxTW");

		if (c == -1 || c == EOF)
			break;

		switch (c) {

		case '?': /* usage */
		case 'h':
			display_help = TRUE;
			break;

		case 'V': /* version */
			display_license = TRUE;
			break;

		case 'v': /* verify */
			verify_config++;
			break;

		case 's': /* scheduling check */
			printf("Warning: -s is deprecated and will be removed\n");
			break;

		case 'd': /* daemon mode */
			daemon_mode = TRUE;
			break;

		case 'p': /* precache object config */
			precache_objects = TRUE;
			break;

		case 'u': /* use precached object config */
			use_precached_objects = TRUE;
			break;
		case 'T':
			enable_timing_point = TRUE;
			break;
		case 'W':
			worker_socket = optarg;
			break;
		case 'R':
			allow_root = TRUE;
			break;

		case 'x':
			printf("Warning: -x is deprecated and will be removed\n");
			break;

		default:
			break;
		}

	}

	/* Make all GLib domain messages go to the usual places. This also maps
	 * GLib levels to an approximation of their corresponding Naemon levels
	 * (including debug).
	 *
	 * Note that because of the GLib domain restriction, log messages from
	 * other domains (such as if we did g_message(...) ourselves from inside
	 * Naemon) do not currently go to this handler.
	 **/
	nm_g_log_handler_id = g_log_set_handler("GLib", G_LOG_LEVEL_MASK | G_LOG_FLAG_FATAL |
			G_LOG_FLAG_RECURSION, nm_g_log_handler, NULL);
	mac = get_global_macros();

	/* if we're a worker we can skip everything below */
	if (worker_socket) {
		exit(nm_core_worker(worker_socket));
	}

	if (daemon_mode == FALSE) {
		printf("\nNaemon Core " VERSION "\n");
		printf("Copyright (c) 2013-present Naemon Core Development Team and Community Contributors\n");
		printf("Copyright (c) 2009-2013 Nagios Core Development Team and Community Contributors\n");
		printf("Copyright (c) 1999-2009 Ethan Galstad\n");
		printf("License: GPL\n\n");
		printf("Website: http://www.naemon.org\n");
	}

	/* just display the license */
	if (display_license == TRUE) {

		printf("This program is free software; you can redistribute it and/or modify\n");
		printf("it under the terms of the GNU General Public License version 2 as\n");
		printf("published by the Free Software Foundation.\n\n");
		printf("This program is distributed in the hope that it will be useful,\n");
		printf("but WITHOUT ANY WARRANTY; without even the implied warranty of\n");
		printf("MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n");
		printf("GNU General Public License for more details.\n\n");
		printf("You should have received a copy of the GNU General Public License\n");
		printf("along with this program; if not, write to the Free Software\n");
		printf("Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.\n\n");

		exit(OK);
	}

	/* make sure we got the main config file on the command line... */
	if (optind >= argc)
		error = TRUE;

	/* if there are no command line options (or if we encountered an error), print usage */
	if (error == TRUE || display_help == TRUE) {

		printf("Usage: %s [options] <main_config_file>\n", argv[0]);
		printf("\n");
		printf("Options:\n");
		printf("\n");
		printf("  -v, --verify-config          Verify all configuration data (-v -v for more info)\n");
		printf("  -T, --enable-timing-point    Enable timed commentary on initialization\n");
		printf("  -x, --dont-verify-paths      Deprecated (Don't check for circular object paths)\n");
		printf("  -p, --precache-objects       Precache object configuration\n");
		printf("  -u, --use-precached-objects  Use precached object config file\n");
		printf("  -d, --daemon                 Starts Naemon in daemon mode, instead of as a foreground process\n");
		printf("  -W, --worker /path/to/socket Act as a worker for an already running daemon\n");
		printf("  --allow-root                 Let naemon run as root. THIS IS NOT RECOMMENDED AT ALL.\n");
		printf("\n");
		printf("Visit the Naemon website at http://www.naemon.org/ for bug fixes, new\n");
		printf("releases, online documentation, FAQs and more...\n");
		printf("\n");

		exit(ERROR);
	}

	if (getuid() == 0) {
		if (allow_root == FALSE) {
			printf("ERROR: do not start naemon as root user.\n");
			exit(EXIT_FAILURE);
		} else {
			printf("WARNING: you are running as root which is not recommended.\n");
		}
	}



	/*
	 * config file is last argument specified.
	 * Make sure it uses an absolute path
	 */
	config_file = nspath_absolute(argv[optind], NULL);
	if (config_file == NULL) {
		printf("Error allocating memory.\n");
		exit(ERROR);
	}

	config_file_dir = nspath_absolute_dirname(config_file, NULL);

	/*
	 * Set the signal handler for the SIGXFSZ signal here because
	 * we may encounter this signal before the other signal handlers
	 * are set.
	 */
	signal(SIGXFSZ, sighandler);


	/*
	 * Setup rand and srand. Don't bother with better resolution than second
	 */
	srand(time(NULL));

	/*
	 * let's go to town. We'll be noisy if we're verifying config
	 * or running scheduling tests.
	 */
	if (verify_config || precache_objects) {
		reset_variables();

		if (verify_config)
			printf("Reading configuration data...\n");

		/* read our config file */
		result = read_main_config_file(config_file);
		if (result != OK) {
			printf("   Error processing main config file!\n\n");
			exit(EXIT_FAILURE);
		}

		if (verify_config)
			printf("   Read main config file okay...\n");

		/*
		 * this must come after dropping privileges, so we make
		 * sure to test access permissions as the right user.
		 */
		if (test_configured_paths() == ERROR) {
			printf("   One or more path problems detected. Aborting.\n");
			exit(EXIT_FAILURE);
		}

		/* read object config files */
		result = read_all_object_data(config_file);
		if (result != OK) {
			printf("   Error processing object config files!\n\n");
			/* if the config filename looks fishy, warn the user */
			if (!strstr(config_file, "naemon.cfg")) {
				printf("\n***> The name of the main configuration file looks suspicious...\n");
				printf("\n");
				printf("     Make sure you are specifying the name of the MAIN configuration file on\n");
				printf("     the command line and not the name of another configuration file.  The\n");
				printf("     main configuration file is typically '%s'\n", get_default_config_file());
			}

			printf("\n***> One or more problems was encountered while processing the config files...\n");
			printf("\n");
			printf("     Check your configuration file(s) to ensure that they contain valid\n");
			printf("     directives and data definitions.  If you are upgrading from a previous\n");
			printf("     version of Naemon, you should be aware that some variables/definitions\n");
			printf("     may have been removed or modified in this version.  Make sure to read\n");
			printf("     the HTML documentation regarding the config files, as well as the\n");
			printf("     'Whats New' section to find out what has changed.\n\n");
			exit(EXIT_FAILURE);
		}

		if (verify_config) {
			printf("   Read object config files okay...\n\n");
			printf("Running pre-flight check on configuration data...\n\n");
		}

		/* run the pre-flight check to make sure things look okay... */
		result = pre_flight_check();

		if (result != OK) {
			printf("\n***> One or more problems was encountered while running the pre-flight check...\n");
			printf("\n");
			printf("     Check your configuration file(s) to ensure that they contain valid\n");
			printf("     directives and data definitions.  If you are upgrading from a previous\n");
			printf("     version of Naemon, you should be aware that some variables/definitions\n");
			printf("     may have been removed or modified in this version.  Make sure to read\n");
			printf("     the HTML documentation regarding the config files, as well as the\n");
			printf("     'Whats New' section to find out what has changed.\n\n");
			exit(EXIT_FAILURE);
		}

		if (verify_config) {
			printf("\nThings look okay - No serious problems were detected during the pre-flight check\n");
		}

		if (precache_objects) {
			result = fcache_objects(object_precache_file);
			timing_point("Done precaching objects\n");
			if (result == OK) {
				printf("Object precache file created:\n%s\n", object_precache_file);
			} else {
				printf("Failed to precache objects to '%s': %s\n", object_precache_file, strerror(errno));
			}
		}

		/* clean up after ourselves */
		cleanup();

		/* exit */
		timing_point("Exiting\n");

		/* make valgrind shut up about still reachable memory */
		neb_free_module_list();
		free(config_file_dir);
		free(config_file);

		exit(result);
	}


	/* start to monitor things... */

	/*
	 * if we're called with a relative path we must make
	 * it absolute so we can launch our workers.
	 * If not, we needn't bother, as we're using execvp()
	 */
	if (strchr(argv[0], '/'))
		naemon_binary_path = nspath_absolute(argv[0], NULL);
	else
		naemon_binary_path = nm_strdup(argv[0]);

	if (!(nagios_iobs = iobroker_create())) {
		nm_log(NSLOG_RUNTIME_ERROR, "Error: Failed to create IO broker set: %s\n",
		       strerror(errno));
		exit(EXIT_FAILURE);
	}

	/* keep monitoring things until we get a shutdown command */
	sigshutdown = sigrestart = FALSE;
	do {
		/* reset internal book-keeping (in case we're restarting) */
		wproc_num_workers_spawned = wproc_num_workers_online = 0;

		/* reset program variables */
		timing_point("Reseting variables\n");
		reset_variables();
		timing_point("Reset variables\n");

		/* get PID */
		nagios_pid = (int)getpid();

		/* read in the configuration files (main and resource config files) */
		timing_point("Reading main config file\n");
		result = read_main_config_file(config_file);
		if (result != OK) {
			nm_log(NSLOG_CONFIG_ERROR, "Error: Failed to process config file '%s'. Aborting\n", config_file);
			exit(EXIT_FAILURE);
		}
		timing_point("Read main config file\n");

		/* NOTE 11/06/07 EG moved to after we read config files, as user may have overridden timezone offset */
		/* get program (re)start time and save as macro */
		program_start = time(NULL);
		nm_free(mac->x[MACRO_PROCESSSTARTTIME]);
		nm_asprintf(&mac->x[MACRO_PROCESSSTARTTIME], "%lu", (unsigned long)program_start);

		if (test_path_access(naemon_binary_path, X_OK)) {
			nm_log(NSLOG_RUNTIME_ERROR, "Error: failed to access() %s: %s\n", naemon_binary_path, strerror(errno));
			nm_log(NSLOG_RUNTIME_ERROR, "Error: Spawning workers will be impossible. Aborting.\n");
			exit(EXIT_FAILURE);
		}

		if (test_configured_paths() == ERROR) {
			/* error has already been logged */
			exit(EXIT_FAILURE);
		}
		/* enter daemon mode (unless we're restarting...) */
		if (daemon_mode == TRUE && sigrestart == FALSE) {

			result = daemon_init();

			/* we had an error daemonizing, so bail... */
			if (result == ERROR) {
				nm_log(NSLOG_PROCESS_INFO | NSLOG_RUNTIME_ERROR, "Bailing out due to failure to daemonize. (PID=%d)", (int)getpid());
				cleanup();
				exit(EXIT_FAILURE);
			}

			/* get new PID */
			nagios_pid = (int)getpid();
		}

		/* this must be logged after we read config data, as user may have changed location of main log file */
		nm_log(NSLOG_PROCESS_INFO, "Naemon "VERSION" starting... (PID=%d)\n", (int)getpid());

		/* log the local time - may be different than clock time due to timezone offset */
		now = time(NULL);
		tm = localtime_r(&now, &tm_s);
		strftime(datestring, sizeof(datestring), "%a %b %d %H:%M:%S %Z %Y", tm);
		nm_log(NSLOG_PROCESS_INFO, "Local time is %s", datestring);

		/* write log version/info */
		write_log_file_info(NULL);

		/* open debug log now that we're the right user */
		open_debug_log();

		/* initialize modules */
		timing_point("Initializing NEB module API\n");
		neb_init_modules();
		neb_init_callback_list();
		timing_point("Initialized NEB module API\n");

		/* handle signals (interrupts) before we do any socket I/O */
		setup_sighandler();

		/*
		 * Initialize query handler and event subscription service.
		 * This must be done before modules are initialized, so
		 * the modules can use our in-core stuff properly
		 */
		timing_point("Initializing Query handler\n");
		if (qh_init(qh_socket_path) != OK) {
			nm_log(NSLOG_RUNTIME_ERROR, "Error: Failed to initialize query handler. Aborting\n");
			exit(EXIT_FAILURE);
		}
		timing_point("Initialized Query handler\n");

		timing_point("Initializing NERD\n");
		nerd_init();
		timing_point("Initialized NERD\n");

		/* initialize check workers */
		timing_point("Spawning %u workers\n", wproc_num_workers_spawned);
		if (init_workers(num_check_workers) < 0) {
			nm_log(NSLOG_RUNTIME_ERROR, "Failed to spawn workers. Aborting\n");
			exit(EXIT_FAILURE);
		}
		timing_point("Spawned %u workers\n", wproc_num_workers_spawned);

		timing_point("Connecting %u workers\n", wproc_num_workers_online);
		i = 0;
		while (i < 50 && wproc_num_workers_online < wproc_num_workers_spawned) {
			iobroker_poll(nagios_iobs, 50);
			i++;
		}
		timing_point("Connected %u workers\n", wproc_num_workers_online);

		/* read in all object config data */
		if (result == OK) {
			timing_point("Reading all object data\n");
			result = read_all_object_data(config_file);
			timing_point("Read all object data\n");
		}

		/*
		 * the queue has to be initialized before loading the neb modules
		 * to give them the chance to register user events.
		 * (initializing event queue requires number of objects, so do
		 * this after parsing the objects)
		 */
		timing_point("Initializing Event queue\n");
		init_event_queue();
		timing_point("Initialized Event queue\n");

		/* load modules */
		timing_point("Loading modules\n");
		if (neb_load_all_modules() != OK) {
			nm_log(NSLOG_CONFIG_ERROR, "Error: Module loading failed. Aborting.\n");
			/* give already loaded modules a chance to deinitialize */
			neb_unload_all_modules(NEBMODULE_FORCE_UNLOAD, NEBMODULE_NEB_SHUTDOWN);
			exit(EXIT_FAILURE);
		}
		timing_point("Loaded modules\n");

		timing_point("Making first callback\n");
		broker_program_state(NEBTYPE_PROCESS_PRELAUNCH, NEBFLAG_NONE, NEBATTR_NONE);
		timing_point("Made first callback\n");

		/* there was a problem reading the config files */
		if (result != OK) {
			nm_log(NSLOG_PROCESS_INFO | NSLOG_RUNTIME_ERROR | NSLOG_CONFIG_ERROR, "Bailing out due to one or more errors encountered in the configuration files. Run Naemon from the command line with the -v option to verify your config before restarting. (PID=%d)", (int)getpid());
		} else {
			/* run the pre-flight check to make sure everything looks okay*/
			timing_point("Running pre flight check\n");
			if ((result = pre_flight_check()) != OK) {
				nm_log(NSLOG_PROCESS_INFO | NSLOG_RUNTIME_ERROR | NSLOG_VERIFICATION_ERROR, "Bailing out due to errors encountered while running the pre-flight check.  Run Naemon from the command line with the -v option to verify your config before restarting. (PID=%d)\n", (int)getpid());
			}
			timing_point("Ran pre flight check\n");
		}

		/* an error occurred that prevented us from (re)starting */
		if (result != OK) {

			/* if we were restarting, we need to cleanup from the previous run */
			if (sigrestart == TRUE) {

				/* clean up the status data */
				cleanup_status_data(TRUE);
			}

			broker_program_state(NEBTYPE_PROCESS_SHUTDOWN, NEBFLAG_PROCESS_INITIATED, NEBATTR_SHUTDOWN_ABNORMAL);

			cleanup();
			exit(ERROR);
		}

		/* write the objects.cache file */
		timing_point("Caching objects\n");
		fcache_objects(object_cache_file);
		timing_point("Cached objects\n");

		broker_program_state(NEBTYPE_PROCESS_START, NEBFLAG_NONE, NEBATTR_NONE);

		timing_point("Initializing status data\n");
		initialize_status_data(config_file);
		timing_point("Initialized status data\n");

		/* initialize scheduled downtime data */
		timing_point("Initializing downtime data\n");
		initialize_downtime_data();
		timing_point("Initialized downtime data\n");

		/* read initial service and host state information  */
		timing_point("Initializing retention data\n");
		initialize_retention_data();
		timing_point("Initialized retention data\n");

		timing_point("Reading initial state information\n");
		read_initial_state_information();
		timing_point("Read initial state information\n");

		/* initialize comment data */
		timing_point("Initializing comment data\n");
		initialize_comment_data();
		timing_point("Initialized comment data\n");

		/* initialize performance data */
		timing_point("Initializing performance data\n");
		initialize_performance_data(config_file);
		timing_point("Initialized performance data\n");

		/* initialize the check execution subsystem */
		timing_point("Initializing check execution scheduling\n");
		checks_init();
		timing_point("Initialized check execution scheduling\n");

		/* initialize check statistics */
		timing_point("Initializing check stats\n");
		init_check_stats();
		timing_point("Initialized check stats\n");

		/* update all status data (with retained information) */
		timing_point("Updating status data\n");
		update_all_status_data();
		timing_point("Updated status data\n");

		/* log initial host and service state */
		timing_point("Logging initial states\n");
		log_host_states(INITIAL_STATES, NULL);
		log_service_states(INITIAL_STATES, NULL);
		timing_point("Logged initial states\n");

		registered_commands_init(200);
		register_core_commands();
		/* fire up command file worker */
		timing_point("Launching command file worker\n");
		launch_command_file_worker();
		timing_point("Launched command file worker\n");

		broker_program_state(NEBTYPE_PROCESS_EVENTLOOPSTART, NEBFLAG_NONE, NEBATTR_NONE);

		/* get event start time and save as macro */
		event_start = time(NULL);
		nm_free(mac->x[MACRO_EVENTSTARTTIME]);
		nm_asprintf(&mac->x[MACRO_EVENTSTARTTIME], "%lu", (unsigned long)event_start);

		/* let the parent know we're good to go and that it can let go */
		if (daemon_mode == TRUE && sigrestart == FALSE) {
			if ((result = signal_parent(OK)) != OK) {
				broker_program_state(NEBTYPE_PROCESS_SHUTDOWN, NEBFLAG_PROCESS_INITIATED, NEBATTR_SHUTDOWN_ABNORMAL);
				cleanup();
				exit(ERROR);
			}
		}

		timing_point("Entering event execution loop\n");
		/***** start monitoring all services *****/
		/* (doesn't return until a restart or shutdown signal is encountered) */
		sigshutdown = sigrestart = FALSE;
		event_execution_loop();

		/*
		 * immediately deinitialize the query handler so it
		 * can remove modules that have stashed data with it
		 */
		qh_deinit(qh_socket_path);

		/*
		 * handle any incoming signals
		 */
		signal_react();

		broker_program_state(NEBTYPE_PROCESS_EVENTLOOPEND, NEBFLAG_NONE, NEBATTR_NONE);
		if (sigshutdown == TRUE)
			broker_program_state(NEBTYPE_PROCESS_SHUTDOWN, NEBFLAG_USER_INITIATED, NEBATTR_SHUTDOWN_NORMAL);
		else if (sigrestart == TRUE)
			broker_program_state(NEBTYPE_PROCESS_RESTART, NEBFLAG_USER_INITIATED, NEBATTR_RESTART_NORMAL);

		disconnect_command_file_worker();

		/* save service and host state information */
		save_state_information(FALSE);
		cleanup_retention_data();

		/* clean up performance data */
		cleanup_performance_data();

		/* clean up the scheduled downtime data */
		cleanup_downtime_data();

		/* clean up the status data unless we're restarting */
		cleanup_status_data(!sigrestart);

		registered_commands_deinit();
		free_worker_memory(WPROC_FORCE);
		/* shutdown stuff... */
		if (sigshutdown == TRUE) {
			iobroker_destroy(nagios_iobs, IOBROKER_CLOSE_SOCKETS);
			nagios_iobs = NULL;

			/* log a shutdown message */
			nm_log(NSLOG_PROCESS_INFO, "Successfully shutdown... (PID=%d)\n", (int)getpid());
		}

		/* clean up after ourselves */
		cleanup();

		/* close debug log */
		close_debug_log();

	} while (sigrestart == TRUE && sigshutdown == FALSE);

	shutdown_command_file_worker();

	if (daemon_mode == TRUE)
		unlink(lock_file);

	/* free misc memory */
	nm_free(lock_file);
	nm_free(config_file);
	nm_free(config_file_dir);
	nm_free(naemon_binary_path);

	return OK;
}
示例#26
0
/* initializes performance data */
int initialize_performance_data(const char *cfgfile)
{
	char *buffer = NULL;
	char *temp_buffer = NULL;
	command *temp_command = NULL;
	time_t current_time;
	nagios_macros *mac;

	mac = get_global_macros();
	time(&current_time);

	/* reset vars */
	host_perfdata_command_ptr = NULL;
	service_perfdata_command_ptr = NULL;
	host_perfdata_file_processing_command_ptr = NULL;
	service_perfdata_file_processing_command_ptr = NULL;

	/* make sure we have some templates defined */
	if (host_perfdata_file_template == NULL)
		host_perfdata_file_template = nm_strdup(DEFAULT_HOST_PERFDATA_FILE_TEMPLATE);
	if (service_perfdata_file_template == NULL)
		service_perfdata_file_template = nm_strdup(DEFAULT_SERVICE_PERFDATA_FILE_TEMPLATE);

	/* process special chars in templates */
	xpddefault_preprocess_file_templates(host_perfdata_file_template);
	xpddefault_preprocess_file_templates(service_perfdata_file_template);

	/* open the performance data caches */
	host_perfdata_bq = nm_bufferqueue_create();
	host_perfdata_fd = xpddefault_open_perfdata_file(
		host_perfdata_file,
		host_perfdata_file_pipe,
		host_perfdata_file_append);
	service_perfdata_bq = nm_bufferqueue_create();
	service_perfdata_fd = xpddefault_open_perfdata_file(
		service_perfdata_file,
		service_perfdata_file_pipe,
		service_perfdata_file_append);

	/* verify that performance data commands are valid */
	if (host_perfdata_command != NULL) {
		temp_buffer = nm_strdup(host_perfdata_command);
		if ((temp_command = find_bang_command(temp_buffer)) == NULL) {
			nm_log(NSLOG_RUNTIME_WARNING, "Warning: Host performance command '%s' was not found - host performance data will not be processed!\n", host_perfdata_command);
			nm_free(host_perfdata_command);
		}

		nm_free(temp_buffer);

		/* save the command pointer for later */
		host_perfdata_command_ptr = temp_command;
	}

	if (service_perfdata_command != NULL) {
		temp_buffer = nm_strdup(service_perfdata_command);
		if ((temp_command = find_bang_command(temp_buffer)) == NULL) {
			nm_log(NSLOG_RUNTIME_WARNING, "Warning: Service performance command '%s' was not found - service performance data will not be processed!\n", service_perfdata_command);
			nm_free(service_perfdata_command);
		}

		nm_free(temp_buffer);

		/* save the command pointer for later */
		service_perfdata_command_ptr = temp_command;
	}

	if (host_perfdata_file_processing_command != NULL) {
		temp_buffer = nm_strdup(host_perfdata_file_processing_command);
		if ((temp_command = find_bang_command(temp_buffer)) == NULL) {
			nm_log(NSLOG_RUNTIME_WARNING, "Warning: Host performance file processing command '%s' was not found - host performance data file will not be processed!\n", host_perfdata_file_processing_command);
			nm_free(host_perfdata_file_processing_command);
		}

		nm_free(temp_buffer);

		/* save the command pointer for later */
		host_perfdata_file_processing_command_ptr = temp_command;
	}

	if (service_perfdata_file_processing_command != NULL) {
		temp_buffer = nm_strdup(service_perfdata_file_processing_command);
		if ((temp_command = find_bang_command(temp_buffer)) == NULL) {
			nm_log(NSLOG_RUNTIME_WARNING, "Warning: Service performance file processing command '%s' was not found - service performance data file will not be processed!\n", service_perfdata_file_processing_command);
			nm_free(service_perfdata_file_processing_command);
		}

		/* save the command pointer for later */
		service_perfdata_file_processing_command_ptr = temp_command;
	}

	/* periodically process the host perfdata file */
	if (host_perfdata_file_processing_interval > 0 && host_perfdata_file_processing_command != NULL) {
		if (host_perfdata_file_pipe)
			nm_log(NSLOG_RUNTIME_WARNING, "Warning: Host performance file is configured to be a pipe - ignoring host_perfdata_file_processing_interval");
		else
			schedule_event(host_perfdata_file_processing_interval, xpddefault_process_host_perfdata_file, NULL);
	}

	/* periodically process the service perfdata file */
	if (service_perfdata_file_processing_interval > 0 && service_perfdata_file_processing_command != NULL) {
		if (service_perfdata_file_pipe)
			nm_log(NSLOG_RUNTIME_WARNING, "Warning: Service performance file is configured to be a pipe - ignoring service_perfdata_file_processing_interval");
		else
			schedule_event(service_perfdata_file_processing_interval, xpddefault_process_service_perfdata_file, NULL);
	}

	/* save the host perf data file macro */
	nm_free(mac->x[MACRO_HOSTPERFDATAFILE]);
	if (host_perfdata_file != NULL) {
		mac->x[MACRO_HOSTPERFDATAFILE] = nm_strdup(host_perfdata_file);
		strip(mac->x[MACRO_HOSTPERFDATAFILE]);
	}

	/* save the service perf data file macro */
	nm_free(mac->x[MACRO_SERVICEPERFDATAFILE]);
	if (service_perfdata_file != NULL) {
		mac->x[MACRO_SERVICEPERFDATAFILE] = nm_strdup(service_perfdata_file);
		strip(mac->x[MACRO_SERVICEPERFDATAFILE]);
	}

	nm_free(temp_buffer);
	nm_free(buffer);

	return OK;
}
示例#27
0
void fcache_host(FILE *fp, const host *temp_host)
{
	fprintf(fp, "define host {\n");
	fprintf(fp, "\thost_name\t%s\n", temp_host->name);
	if (temp_host->display_name != temp_host->name)
		fprintf(fp, "\tdisplay_name\t%s\n", temp_host->display_name);
	if (temp_host->alias)
		fprintf(fp, "\talias\t%s\n", temp_host->alias);
	if (temp_host->address)
		fprintf(fp, "\taddress\t%s\n", temp_host->address);
	if (g_tree_nnodes(temp_host->parent_hosts) > 0) {
		char *parents;
		parents = implode_hosttree(temp_host->parent_hosts, ",");
		fprintf(fp, "\tparents\t%s\n", parents);
		nm_free(parents);
	}
	if (temp_host->check_period)
		fprintf(fp, "\tcheck_period\t%s\n", temp_host->check_period);
	if (temp_host->check_command)
		fprintf(fp, "\tcheck_command\t%s\n", temp_host->check_command);
	if (temp_host->event_handler)
		fprintf(fp, "\tevent_handler\t%s\n", temp_host->event_handler);
	fcache_contactlist(fp, "\tcontacts\t", temp_host->contacts);
	fcache_contactgrouplist(fp, "\tcontact_groups\t", temp_host->contact_groups);
	if (temp_host->notification_period)
		fprintf(fp, "\tnotification_period\t%s\n", temp_host->notification_period);
	fprintf(fp, "\tinitial_state\t");
	if (temp_host->initial_state == STATE_DOWN)
		fprintf(fp, "d\n");
	else if (temp_host->initial_state == STATE_UNREACHABLE)
		fprintf(fp, "u\n");
	else
		fprintf(fp, "o\n");
	fprintf(fp, "\thourly_value\t%u\n", temp_host->hourly_value);
	fprintf(fp, "\tcheck_interval\t%f\n", temp_host->check_interval);
	fprintf(fp, "\tretry_interval\t%f\n", temp_host->retry_interval);
	fprintf(fp, "\tmax_check_attempts\t%d\n", temp_host->max_attempts);
	fprintf(fp, "\tactive_checks_enabled\t%d\n", temp_host->checks_enabled);
	fprintf(fp, "\tpassive_checks_enabled\t%d\n", temp_host->accept_passive_checks);
	fprintf(fp, "\tobsess\t%d\n", temp_host->obsess);
	fprintf(fp, "\tevent_handler_enabled\t%d\n", temp_host->event_handler_enabled);
	fprintf(fp, "\tlow_flap_threshold\t%f\n", temp_host->low_flap_threshold);
	fprintf(fp, "\thigh_flap_threshold\t%f\n", temp_host->high_flap_threshold);
	fprintf(fp, "\tflap_detection_enabled\t%d\n", temp_host->flap_detection_enabled);
	fprintf(fp, "\tflap_detection_options\t%s\n", opts2str(temp_host->flap_detection_options, host_flag_map, 'o'));
	fprintf(fp, "\tfreshness_threshold\t%d\n", temp_host->freshness_threshold);
	fprintf(fp, "\tcheck_freshness\t%d\n", temp_host->check_freshness);
	fprintf(fp, "\tnotification_options\t%s\n", opts2str(temp_host->notification_options, host_flag_map, 'r'));
	fprintf(fp, "\tnotifications_enabled\t%d\n", temp_host->notifications_enabled);
	fprintf(fp, "\tnotification_interval\t%f\n", temp_host->notification_interval);
	fprintf(fp, "\tfirst_notification_delay\t%f\n", temp_host->first_notification_delay);
	fprintf(fp, "\tstalking_options\t%s\n", opts2str(temp_host->stalking_options, host_flag_map, 'o'));
	fprintf(fp, "\tprocess_perf_data\t%d\n", temp_host->process_performance_data);
	if (temp_host->icon_image)
		fprintf(fp, "\ticon_image\t%s\n", temp_host->icon_image);
	if (temp_host->icon_image_alt)
		fprintf(fp, "\ticon_image_alt\t%s\n", temp_host->icon_image_alt);
	if (temp_host->vrml_image)
		fprintf(fp, "\tvrml_image\t%s\n", temp_host->vrml_image);
	if (temp_host->statusmap_image)
		fprintf(fp, "\tstatusmap_image\t%s\n", temp_host->statusmap_image);
	if (temp_host->have_2d_coords == TRUE)
		fprintf(fp, "\t2d_coords\t%d,%d\n", temp_host->x_2d, temp_host->y_2d);
	if (temp_host->have_3d_coords == TRUE)
		fprintf(fp, "\t3d_coords\t%f,%f,%f\n", temp_host->x_3d, temp_host->y_3d, temp_host->z_3d);
	if (temp_host->notes)
		fprintf(fp, "\tnotes\t%s\n", temp_host->notes);
	if (temp_host->notes_url)
		fprintf(fp, "\tnotes_url\t%s\n", temp_host->notes_url);
	if (temp_host->action_url)
		fprintf(fp, "\taction_url\t%s\n", temp_host->action_url);
	fprintf(fp, "\tretain_status_information\t%d\n", temp_host->retain_status_information);
	fprintf(fp, "\tretain_nonstatus_information\t%d\n", temp_host->retain_nonstatus_information);

	/* custom variables */
	fcache_customvars(fp, temp_host->custom_variables);
	fprintf(fp, "\t}\n\n");
}