serviceescalation *add_serviceescalation(char *host_name, char *description, int first_notification, int last_notification, double notification_interval, char *escalation_period, int escalation_options)
{
	serviceescalation *new_serviceescalation = NULL;
	service *svc;
	timeperiod *tp = NULL;

	/* make sure we have the data we need */
	if (host_name == NULL || !*host_name || description == NULL || !*description) {
		nm_log(NSLOG_CONFIG_ERROR, "Error: Service escalation host name or description is NULL\n");
		return NULL;
	}
	if (!(svc = find_service(host_name, description))) {
		nm_log(NSLOG_CONFIG_ERROR, "Error: Service '%s' on host '%s' has an escalation but is not defined anywhere!\n",
		       host_name, description);
		return NULL;
	}
	if (escalation_period && !(tp = find_timeperiod(escalation_period))) {
		nm_log(NSLOG_VERIFICATION_ERROR, "Error: Escalation period '%s' specified in service escalation for service '%s' on host '%s' is not defined anywhere!\n",
		       escalation_period, description, host_name);
		return NULL ;
	}

	new_serviceescalation = nm_calloc(1, sizeof(*new_serviceescalation));

	if (prepend_object_to_objectlist(&svc->escalation_list, new_serviceescalation) != OK) {
		nm_log(NSLOG_CONFIG_ERROR, "Could not add escalation to service '%s' on host '%s'\n",
		       svc->host_name, svc->description);
		return NULL;
	}

	/* assign vars. object names are immutable, so no need to copy */
	new_serviceescalation->host_name = svc->host_name;
	new_serviceescalation->description = svc->description;
	new_serviceescalation->service_ptr = svc;
	new_serviceescalation->escalation_period_ptr = tp;
	if (tp)
		new_serviceescalation->escalation_period = tp->name;

	new_serviceescalation->first_notification = first_notification;
	new_serviceescalation->last_notification = last_notification;
	new_serviceescalation->notification_interval = (notification_interval <= 0) ? 0 : notification_interval;
	new_serviceescalation->escalation_options = escalation_options;

	new_serviceescalation->id = num_objects.serviceescalations++;
	return new_serviceescalation;
}
hostescalation *add_hostescalation(char *host_name, int first_notification, int last_notification, double notification_interval, char *escalation_period, int escalation_options)
{
	hostescalation *new_hostescalation = NULL;
	host *h;
	timeperiod *tp = NULL;

	/* make sure we have the data we need */
	if (host_name == NULL || !*host_name) {
		nm_log(NSLOG_CONFIG_ERROR, "Error: Host escalation host name is NULL\n");
		return NULL;
	}
	if (!(h = find_host(host_name))) {
		nm_log(NSLOG_CONFIG_ERROR, "Error: Host '%s' has an escalation, but is not defined anywhere!\n", host_name);
		return NULL;
	}
	if (escalation_period && !(tp = find_timeperiod(escalation_period))) {
		nm_log(NSLOG_CONFIG_ERROR, "Error: Unable to locate timeperiod '%s' for hostescalation '%s'\n",
		       escalation_period, host_name);
		return NULL;
	}

	new_hostescalation = nm_calloc(1, sizeof(*new_hostescalation));

	/* add the escalation to its host */
	if (prepend_object_to_objectlist(&h->escalation_list, new_hostescalation) != OK) {
		nm_log(NSLOG_CONFIG_ERROR, "Error: Could not add hostescalation to host '%s'\n", host_name);
		free(new_hostescalation);
		return NULL;
	}

	/* assign vars. Object names are immutable, so no need to copy */
	new_hostescalation->host_name = h->name;
	new_hostescalation->host_ptr = h;
	new_hostescalation->escalation_period = tp ? tp->name : NULL;
	new_hostescalation->escalation_period_ptr = tp;
	new_hostescalation->first_notification = first_notification;
	new_hostescalation->last_notification = last_notification;
	new_hostescalation->notification_interval = (notification_interval <= 0) ? 0 : notification_interval;
	new_hostescalation->escalation_options = escalation_options;

	new_hostescalation->id = num_objects.hostescalations++;
	return new_hostescalation;
}
int register_timeperiod(timeperiod *new_timeperiod)
{

	g_return_val_if_fail(timeperiod_hash_table != NULL, ERROR);

	if ((find_timeperiod(new_timeperiod->name))) {
		nm_log(NSLOG_CONFIG_ERROR, "Error: Timeperiod '%s' has already been defined\n", new_timeperiod->name);
		return ERROR;
	}

	g_hash_table_insert(timeperiod_hash_table, new_timeperiod->name, new_timeperiod);

	new_timeperiod->id = num_objects.timeperiods++;
	if (new_timeperiod->id)
		timeperiod_ary[new_timeperiod->id - 1]->next = new_timeperiod;
	else
		timeperiod_list = new_timeperiod;
	timeperiod_ary[new_timeperiod->id] = new_timeperiod;

	return OK;
}
/* adds a new exclusion to a timeperiod */
timeperiodexclusion *add_exclusion_to_timeperiod(timeperiod *period, char *name)
{
	timeperiodexclusion *new_timeperiodexclusion = NULL;
	timeperiod *temp_timeperiod2;

	/* make sure we have enough data */
	if (period == NULL || name == NULL)
		return NULL;

	temp_timeperiod2 = find_timeperiod(name);
	if (temp_timeperiod2 == NULL) {
		nm_log(NSLOG_VERIFICATION_ERROR, "Error: Excluded time period '%s' specified in timeperiod '%s' is not defined anywhere!", name, period->name);
		return NULL;
	}

	new_timeperiodexclusion = nm_malloc(sizeof(timeperiodexclusion));
	new_timeperiodexclusion->timeperiod_name = nm_strdup(name);
	new_timeperiodexclusion->timeperiod_ptr = temp_timeperiod2;

	new_timeperiodexclusion->next = period->exclusions;
	period->exclusions = new_timeperiodexclusion;

	return new_timeperiodexclusion;
}
Example #5
0
int setup_service_variables(service *new_service, const char *display_name, const char *check_command, const char *check_period, int initial_state, int max_attempts, int accept_passive_checks, double check_interval, double retry_interval, double notification_interval, double first_notification_delay, char *notification_period, int notification_options, int notifications_enabled, int is_volatile, const char *event_handler, int event_handler_enabled, int checks_enabled, int flap_detection_enabled, double low_flap_threshold, double high_flap_threshold, int flap_detection_options, int stalking_options, int process_perfdata, int check_freshness, int freshness_threshold, const char *notes, const char *notes_url, const char *action_url, const char *icon_image, const char *icon_image_alt, int retain_status_information, int retain_nonstatus_information, int obsess, unsigned int hourly_value)
{
    timeperiod *cp = NULL, *np = NULL;
    command *cmd;

    /* make sure we have everything we need */
    if (notification_period && !(np = find_timeperiod(notification_period))) {
        nm_log(NSLOG_CONFIG_ERROR, "Error: notification_period '%s' for service '%s' on host '%s' could not be found!\n", notification_period, new_service->description, new_service->host_name);
        return -1;
    }
    if (check_period && !(cp = find_timeperiod(check_period))) {
        nm_log(NSLOG_CONFIG_ERROR, "Error: check_period '%s' for service '%s' on host '%s' not found!\n",
               check_period, new_service->description, new_service->host_name);
        return -1;
    }

    if (check_command == NULL || !*check_command) {
        nm_log(NSLOG_CONFIG_ERROR, "Error: No check command provided for service '%s' on host '%s'\n", new_service->check_command, new_service->description);
        return -1;
    }
    cmd = find_bang_command(check_command);
    if (cmd == NULL) {
        nm_log(NSLOG_VERIFICATION_ERROR, "Error: Service check command '%s' specified in service '%s' for host '%s' not defined anywhere!", check_command, new_service->description, new_service->host_name);
        return -1;
    }


    if (max_attempts <= 0) {
        nm_log(NSLOG_CONFIG_ERROR, "Error: max_check_attempts must be a positive integer for service '%s' on host '%s'\n", new_service->description, new_service->host_name);
        return -1;
    }
    if (check_interval < 0) {
        nm_log(NSLOG_CONFIG_ERROR, "Error: check_interval must be a non-negative integer for service '%s' on host '%s'\n", new_service->description, new_service->host_name);
        return -1;
    }
    if (retry_interval <= 0) {
        nm_log(NSLOG_CONFIG_ERROR, "Error: retry_interval must be a positive integer for service '%s' on host '%s'\n", new_service->description, new_service->host_name);
        return -1;
    }
    if (notification_interval < 0) {
        nm_log(NSLOG_CONFIG_ERROR, "Error: notification_interval must be a non-negative integer for service '%s' on host '%s'\n", new_service->description, new_service->host_name);
        return -1;
    }
    if (first_notification_delay < 0) {
        nm_log(NSLOG_CONFIG_ERROR, "Error: first_notification_delay must be a non-negative integer for service '%s' on host '%s'\n", new_service->description, new_service->host_name);
        return -1;
    }

    /* duplicate vars, but assign what we can */
    new_service->notification_period_ptr = np;
    new_service->check_period_ptr = cp;
    new_service->check_period = cp ? cp->name : NULL;
    new_service->notification_period = np ? np->name : NULL;
    new_service->check_command = nm_strdup(check_command);
    new_service->check_command_ptr = cmd;
    if (display_name) {
        new_service->display_name = nm_strdup(display_name);
    }
    if (event_handler) {
        new_service->event_handler = nm_strdup(event_handler);
        new_service->event_handler_ptr = find_bang_command(event_handler);
        if (new_service->event_handler_ptr == NULL) {
            nm_log(NSLOG_VERIFICATION_ERROR, "Error: Event handler command '%s' specified in service '%s' for host '%s' not defined anywhere", new_service->event_handler, new_service->description, new_service->host_name);
            return -1;
        }
    }
    if (notes) {
        new_service->notes = nm_strdup(notes);
    }
    if (notes_url) {
        new_service->notes_url = nm_strdup(notes_url);
    }
    if (action_url) {
        new_service->action_url = nm_strdup(action_url);
    }
    if (icon_image) {
        new_service->icon_image = nm_strdup(icon_image);
    }
    if (icon_image_alt) {
        new_service->icon_image_alt = nm_strdup(icon_image_alt);
    }

    new_service->hourly_value = hourly_value;
    new_service->check_interval = check_interval;
    new_service->retry_interval = retry_interval;
    new_service->max_attempts = max_attempts;
    new_service->notification_interval = notification_interval;
    new_service->first_notification_delay = first_notification_delay;
    new_service->notification_options = notification_options;
    new_service->is_volatile = (is_volatile > 0) ? TRUE : FALSE;
    new_service->flap_detection_enabled = (flap_detection_enabled > 0) ? TRUE : FALSE;
    new_service->low_flap_threshold = low_flap_threshold;
    new_service->high_flap_threshold = high_flap_threshold;
    new_service->flap_detection_options = flap_detection_options;
    new_service->stalking_options = stalking_options;
    new_service->process_performance_data = (process_perfdata > 0) ? TRUE : FALSE;
    new_service->check_freshness = (check_freshness > 0) ? TRUE : FALSE;
    new_service->freshness_threshold = freshness_threshold;
    new_service->accept_passive_checks = (accept_passive_checks > 0) ? TRUE : FALSE;
    new_service->event_handler_enabled = (event_handler_enabled > 0) ? TRUE : FALSE;
    new_service->checks_enabled = (checks_enabled > 0) ? TRUE : FALSE;
    new_service->retain_status_information = (retain_status_information > 0) ? TRUE : FALSE;
    new_service->retain_nonstatus_information = (retain_nonstatus_information > 0) ? TRUE : FALSE;
    new_service->notifications_enabled = (notifications_enabled > 0) ? TRUE : FALSE;
    new_service->obsess = (obsess > 0) ? TRUE : FALSE;
    new_service->current_attempt = (initial_state == STATE_OK) ? 1 : max_attempts;
    new_service->current_state = initial_state;
    new_service->last_state = initial_state;
    new_service->last_hard_state = initial_state;

    /* check the service check_command */

    return 0;
}
Example #6
0
int main(int argc, char **argv) {
	int result;
	int error = FALSE;
	char *buffer = NULL;
	int display_license = FALSE;
	int display_help = FALSE;
	int c = 0;
	struct tm *tm;
	time_t current_time;
	time_t test_time;
	time_t saved_test_time;
	time_t next_valid_time = 0L;
	time_t chosen_valid_time = 0L;
	char datestring[256];
	host *temp_host = NULL;
	hostgroup *temp_hostgroup = NULL;
	hostsmember *temp_member = NULL;
	timeperiod *temp_timeperiod = NULL;
	int is_valid_time = 0;
	int iterations = 1000;

	plan_tests(6043);

	/* reset program variables */
	reset_variables();

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

	config_file = strdup("smallconfig/icinga.cfg");
	/* read in the configuration files (main config file, resource and object config files) */
	result = read_main_config_file(config_file);
	ok(result == OK, "Read main configuration file okay - if fails, use icinga -v to check");

	result = read_all_object_data(config_file);
	ok(result == OK, "Read all object config files");

	result = pre_flight_check();
	ok(result == OK, "Preflight check okay");

	time(&current_time);
	test_time = current_time;
	saved_test_time = current_time;

	temp_timeperiod = find_timeperiod("none");

	is_valid_time = check_time_against_period(test_time, temp_timeperiod);
	ok(is_valid_time == ERROR, "No valid time because time period is empty");

	get_next_valid_time(current_time, &next_valid_time, temp_timeperiod);
	ok((next_valid_time - current_time) <= 2, "Next valid time should be the current_time, but with a 2 second tolerance");

	temp_timeperiod = find_timeperiod("24x7");

	is_valid_time = check_time_against_period(test_time, temp_timeperiod);
	ok(is_valid_time == OK, "Fine because 24x7");

	get_next_valid_time(current_time, &next_valid_time, temp_timeperiod);
	ok(current_time == next_valid_time, "Current time should be the next valid time");

	/* 2009-10-25 is the day when clocks go back an hour in Europe. Bug happens during 23:00 to 00:00 */
	/* This is 23:01:01 */
	saved_test_time = 1256511661;
	saved_test_time = saved_test_time - (24 * 60 * 60);

	putenv("TZ=UTC");
	tzset();
	test_time = saved_test_time;
	c = 0;
	while (c < iterations) {
		is_valid_time = check_time_against_period(test_time, temp_timeperiod);
		ok(is_valid_time == OK, "Always OK for 24x7 with TZ=UTC");
		chosen_valid_time = 0L;
		_get_next_valid_time(test_time, test_time, &chosen_valid_time, temp_timeperiod);
		ok(test_time == chosen_valid_time, "get_next_valid_time always returns same time");
		test_time += 1800;
		c++;
	}

	putenv("TZ=Europe/London");
	tzset();
	test_time = saved_test_time;
	c = 0;
	while (c < iterations) {
		is_valid_time = check_time_against_period(test_time, temp_timeperiod);
		ok(is_valid_time == OK, "Always OK for 24x7 with TZ=Europe/London");
		_get_next_valid_time(test_time, test_time, &chosen_valid_time, temp_timeperiod);
		ok(test_time == chosen_valid_time, "get_next_valid_time always returns same time, time_t=%lu", test_time);
		test_time += 1800;
		c++;
	}

	/* 2009-11-01 is the day when clocks go back an hour in America. Bug happens during 23:00 to 00:00 */
	/* This is 23:01:01 */
	saved_test_time = 1256511661;
	saved_test_time = saved_test_time - (24 * 60 * 60);

	putenv("TZ=America/New_York");
	tzset();
	test_time = saved_test_time;
	c = 0;
	while (c < iterations) {
		is_valid_time = check_time_against_period(test_time, temp_timeperiod);
		ok(is_valid_time == OK, "Always OK for 24x7 with TZ=America/New_York");
		_get_next_valid_time(test_time, test_time, &chosen_valid_time, temp_timeperiod);
		ok(test_time == chosen_valid_time, "get_next_valid_time always returns same time, time_t=%lu", test_time);
		test_time += 1800;
		c++;
	}

	/* Tests around clock change going back for TZ=Europe/London. 1256511661 = Sun Oct
	 25 23:01:01 2009 */
	/* A little trip to Paris*/
	putenv("TZ=Europe/Paris");
	tzset();


	/* Timeperiod exclude tests, from Jean Gabes */
	temp_timeperiod = find_timeperiod("Test_exclude");
	ok(temp_timeperiod != NULL, "ME: Testing Exclude timeperiod");
	test_time = 1278939600;
	/* printf("Testing at time %s", ctime(&test_time)); */
	is_valid_time = check_time_against_period(test_time, temp_timeperiod);
	ok(is_valid_time == ERROR, "ME: 12 Jul 2010 15:00:00 - false");

	_get_next_valid_time(test_time, test_time, &chosen_valid_time, temp_timeperiod);
	/* printf("JEAN: Got chosent time at %s", ctime(&chosen_valid_time)); */
	todo_start("Bug in exclude");
	ok(chosen_valid_time == 1288103400, "ME: Next valid time=Tue Oct 26 16:30:00 2010");
	todo_end();


	temp_timeperiod = find_timeperiod("Test_exclude2");
	ok(temp_timeperiod != NULL, "ME: Testing Exclude timeperiod 2");
	test_time = 1278939600;
	/* printf("Testing at time %s", ctime(&test_time)); */
	is_valid_time = check_time_against_period(test_time, temp_timeperiod);
	ok(is_valid_time == ERROR, "ME: 12 Jul 2010 15:00:00 - false");
	_get_next_valid_time(test_time, test_time, &chosen_valid_time, temp_timeperiod);
	/* printf("JEAN: Got chosent time at %s", ctime(&chosen_valid_time)); */
	todo_start("Bug in exclude 2");
	ok(chosen_valid_time == 1279058340, "ME: Next valid time=Tue Jul 13 23:59:00 2010");
	todo_end();


	temp_timeperiod = find_timeperiod("Test_exclude3");
	ok(temp_timeperiod != NULL, "ME: Testing Exclude timeperiod 3");
	test_time = 1278939600;
	/* printf("Testing at time %s", ctime(&test_time)); */
	is_valid_time = check_time_against_period(test_time, temp_timeperiod);
	ok(is_valid_time == ERROR, "ME: 12 Jul 2010 15:00:00 - false");
	_get_next_valid_time(test_time, test_time, &chosen_valid_time, temp_timeperiod);
	/* printf("JEAN: Got chosent time at %s", ctime(&chosen_valid_time)); */
	todo_start("Bug in exclude 3");
	ok(chosen_valid_time == 1284474600, "ME: Next valid time=Tue Sep 14 16:30:00 2010");
	todo_end();


	temp_timeperiod = find_timeperiod("Test_exclude4");
	ok(temp_timeperiod != NULL, "ME: Testing Exclude timeperiod 4");
	test_time = 1278939600;
	/* printf("Testing at time %s", ctime(&test_time)); */
	is_valid_time = check_time_against_period(test_time, temp_timeperiod);
	ok(is_valid_time == ERROR, "ME: 12 Jul 2010 15:00:00 - false");
	_get_next_valid_time(test_time, test_time, &chosen_valid_time, temp_timeperiod);
	/* printf("JEAN: Got chosent time at %s", ctime(&chosen_valid_time)); */
	todo_start("Bug in exclude 3");
	ok(chosen_valid_time == 1283265000, "ME: Next valid time=Tue Aug 31 16:30:00 2010");
	todo_end();




	/* Back to New york */
	putenv("TZ=America/New_York");
	tzset();




	temp_timeperiod = find_timeperiod("sunday_only");
	ok(temp_timeperiod != NULL, "Testing Sunday 00:00-01:15,03:15-22:00");
	putenv("TZ=Europe/London");
	tzset();

	test_time = 1256421000;
	is_valid_time = check_time_against_period(test_time, temp_timeperiod);
	ok(is_valid_time == ERROR, "Sat Oct 24 22:50:00 2009 - false");
	_get_next_valid_time(test_time, test_time, &chosen_valid_time, temp_timeperiod);
	ok(chosen_valid_time == 1256425200, "Next valid time=Sun Oct 25 00:00:00 2009");

	test_time = 1256421661;
	is_valid_time = check_time_against_period(test_time, temp_timeperiod);
	ok(is_valid_time == ERROR, "Sat Oct 24 23:01:01 2009 - false");
	_get_next_valid_time(test_time, test_time, &chosen_valid_time, temp_timeperiod);
	ok(chosen_valid_time == 1256425200, "Next valid time=Sun Oct 25 00:00:00 2009");

	test_time = 1256425400;
	is_valid_time = check_time_against_period(test_time, temp_timeperiod);
	ok(is_valid_time == OK, "Sun Oct 25 00:03:20 2009 - true");
	_get_next_valid_time(test_time, test_time, &chosen_valid_time, temp_timeperiod);
	ok(chosen_valid_time == test_time, "Next valid time=Sun Oct 25 00:03:20 2009");

	test_time = 1256429700;
	is_valid_time = check_time_against_period(test_time, temp_timeperiod);
	ok(is_valid_time == OK, "Sun Oct 25 01:15:00 2009 - true");
	_get_next_valid_time(test_time, test_time, &chosen_valid_time, temp_timeperiod);
	ok(chosen_valid_time == test_time, "Next valid time=Sun Oct 25 01:15:00 2009");

	test_time = 1256430400;
	is_valid_time = check_time_against_period(test_time, temp_timeperiod);
	ok(is_valid_time == ERROR, "Sun Oct 25 01:26:40 2009 - false");
	_get_next_valid_time(test_time, test_time, &chosen_valid_time, temp_timeperiod);
	todo_start("Is a bug in get_next_valid_time for a time that falls in the DST change hour period");
	ok(chosen_valid_time == 1256440500, "Next valid time=Sun Oct 25 03:15:00 2009") || printf("chosen_valid_time=%lu\n", chosen_valid_time);
	todo_end();

	test_time = 1256440500;
	is_valid_time = check_time_against_period(test_time, temp_timeperiod);
	ok(is_valid_time == OK, "Sun Oct 25 03:15:00 2009 - true");
	_get_next_valid_time(test_time, test_time, &chosen_valid_time, temp_timeperiod);
	ok(chosen_valid_time == test_time, "Next valid time=Sun Oct 25 03:15:00 2009");

	test_time = 1256500000;
	is_valid_time = check_time_against_period(test_time, temp_timeperiod);
	ok(is_valid_time == OK, "Sun Oct 25 19:46:40 2009 - true");
	_get_next_valid_time(test_time, test_time, &chosen_valid_time, temp_timeperiod);
	ok(chosen_valid_time == 1256500000, "Next valid time=Sun Oct 25 19:46:40 2009");

	test_time = 1256508000;
	is_valid_time = check_time_against_period(test_time, temp_timeperiod);
	ok(is_valid_time == OK, "Sun Oct 25 22:00:00 2009 - true");
	_get_next_valid_time(test_time, test_time, &chosen_valid_time, temp_timeperiod);
	ok(chosen_valid_time == 1256508000, "Next valid time=Sun Oct 25 22:00:00 2009");

	test_time = 1256508001;
	is_valid_time = check_time_against_period(test_time, temp_timeperiod);
	ok(is_valid_time == ERROR, "Sun Oct 25 22:00:01 2009 - false");
	//_get_next_valid_time(test_time, test_time, &chosen_valid_time, temp_timeperiod);
	_get_next_valid_time_per_timeperiod(test_time, &chosen_valid_time, test_time, temp_timeperiod);
	ok(chosen_valid_time == 1257033600, "Next valid time=Sun Nov 1 00:00:00 2009");

	test_time = 1256513000;
	is_valid_time = check_time_against_period(test_time, temp_timeperiod);
	ok(is_valid_time == ERROR, "Sun Oct 25 23:23:20 2009 - false");
	//_get_next_valid_time(test_time, test_time, &chosen_valid_time, temp_timeperiod);
	_get_next_valid_time_per_timeperiod(test_time, &chosen_valid_time, test_time, temp_timeperiod);
	ok(chosen_valid_time == 1257033600, "Next valid time=Sun Nov 1 00:00:00 2009");




	temp_timeperiod = find_timeperiod("weekly_complex");
	ok(temp_timeperiod != NULL, "Testing complex weekly timeperiod definition");
	putenv("TZ=America/New_York");
	tzset();

	test_time = 1268109420;
	is_valid_time = check_time_against_period(test_time, temp_timeperiod);
	ok(is_valid_time == ERROR, "Mon Mar  8 23:37:00 2010 - false");
	//_get_next_valid_time(test_time, test_time, &chosen_valid_time, temp_timeperiod);
	_get_next_valid_time_per_timeperiod(test_time, &chosen_valid_time, test_time, temp_timeperiod);
	ok(chosen_valid_time == 1268115300, "Next valid time=Tue Mar  9 01:15:00 2010");

	cleanup();

	my_free(config_file);

	return exit_status();
}
Example #7
0
void test_parsing(void)
{
	struct external_command *ext_command = NULL;
	contact *created_contact = NULL;
	contact *fetched_contact = NULL;
	const char *cmdstr = "[1234567890] ADD_HOST_COMMENT;my_host;0;15;this is my comment, there are many like it but this one is mine";
	registered_commands_init(20);
	{
		g_clear_error(&error);
		ok(NULL == command_parse(cmdstr, COMMAND_SYNTAX_NOKV, &error), "We can't parse commands when none are registered");
		ok(g_error_matches(error, NM_COMMAND_ERROR, CMD_ERROR_UNKNOWN_COMMAND), "The error code looks like expected");

		ext_command = command_create("ADD_HOST_COMMENT", test__add_host_comment_handler, "This is a description for a command named ADD_HOST_COMMENT", NULL);
		command_argument_add(ext_command, "host", STRING, NULL, NULL);
		b_val = 0;
		command_argument_add(ext_command, "persistent", BOOL, &b_val, NULL);
		i_val = 42;
		command_argument_add(ext_command, "author", INTEGER, &i_val, NULL);
		s_val = "No comment";
		command_argument_add(ext_command, "comment", STRING, s_val, NULL);
		command_register(ext_command, -1);

		g_clear_error(&error);
		ext_command = command_parse("[] UNKNOWN_COMMAND", COMMAND_SYNTAX_NOKV, &error);
		ok(g_error_matches(error, NM_COMMAND_ERROR, CMD_ERROR_MALFORMED_COMMAND), "Malformed command error is raised for malformed commands");
		ok(NULL == ext_command, "No command returned for malformed command");

		g_clear_error(&error);
		ext_command = command_parse("[UNKNOWN_COMMAND", COMMAND_SYNTAX_NOKV, &error);
		ok(g_error_matches(error, NM_COMMAND_ERROR, CMD_ERROR_MALFORMED_COMMAND), "Malformed command error is raised for malformed commands");
		ok(NULL == ext_command, "No command returned for malformed command");

		g_clear_error(&error);
		ext_command = command_parse("[139414354] UNKNOWN_COMMAND", COMMAND_SYNTAX_NOKV, &error);
		ok(g_error_matches(error, NM_COMMAND_ERROR, CMD_ERROR_UNKNOWN_COMMAND), "Unknown command error is raised for unknown commands");
		ok(NULL == ext_command, "No command returned for unknown command");

		g_clear_error(&error);
		ext_command = command_parse(cmdstr, COMMAND_SYNTAX_NOKV, &error);
		ok(error == NULL, "The command parses without error");
		ok(!strcmp("my_host", command_argument_get_value(ext_command, "host")), "Host value parsed successfully");
		ok(0 == *(int *)command_argument_get_value(ext_command, "persistent"), "Persistent value parsed successfully");
		ok(15 == *(int *)command_argument_get_value(ext_command, "author"), "Author value parsed successfully");
		ok(!strcmp("this is my comment, there are many like it but this one is mine", command_argument_get_value(ext_command, "comment")), "Comment value parsed successfully");
		command_destroy(ext_command);

		g_clear_error(&error);
		ext_command = command_parse("[1234567890] ADD_HOST_COMMENT;my_host;0;15;this is my newline\n, there are many like it but this one is\n m\ni\nn\ne", COMMAND_SYNTAX_NOKV, &error);
		ok(error == NULL, "Command containing newlines parses without error");
		ok(!strcmp("this is my newline\n, there are many like it but this one is\n m\ni\nn\ne", command_argument_get_value(ext_command, "comment")), "Comment containing newlines parsed successfully");
		command_destroy(ext_command);

		g_clear_error(&error);
		ext_command = command_parse(cmdstr, COMMAND_SYNTAX_NOKV, &error);
		ok(0 == command_execute_handler(ext_command), "Callback exit value properly passed on");
		ok(!strcmp("my_host", received_host), "Host value passed to callback");
		ok(0 == *received_persistent, "Persistent value passed to callback");
		ok(received_entry_time == 1234567890, "Entry time passed correctly to callback");
		command_destroy(ext_command);
		free(received_host);
		free(received_persistent);

		g_clear_error(&error);
		ext_command = command_parse("[1234567890] ADD_HOST_COMMENT;;1", COMMAND_SYNTAX_NOKV, &error);
		ok(g_error_matches(error, NM_COMMAND_ERROR, CMD_ERROR_PARSE_MISSING_ARG), "Missing arguments are complained about");
		ok(ext_command == NULL, "No command returned for command with missing arguments");

		g_clear_error(&error);
		ext_command = command_parse("[15341345] ADD_HOST_COMMENT", COMMAND_SYNTAX_NOKV, &error);
		ok(g_error_matches(error, NM_COMMAND_ERROR, CMD_ERROR_PARSE_MISSING_ARG), "Missing arguments are complained about (no arguments supplied)");
		ok(ext_command == NULL, "No command returned for command with missing arguments");

		g_clear_error(&error);
		ext_command = command_parse("[1234567890] ADD_HOST_COMMENT;my_host;0;441;this is my comment, there are many like it but this one is mine;Post-semi-colon stuff", COMMAND_SYNTAX_NOKV, &error);
		ok(error == NULL, "Last string argument may contain semi-colons");
		ok(ext_command != NULL, "A command should be returned when last string-argument has semi-colons");
		command_destroy(ext_command);

		g_clear_error(&error);
		ext_command = command_parse("[1234567890] ADD_HOST_COMMENT;my_host;0;Dora the Explora';this is my comment, there are many like it but this one is mine", COMMAND_SYNTAX_NOKV, &error);
		ok(g_error_matches(error, NM_COMMAND_ERROR, CMD_ERROR_PARSE_TYPE_MISMATCH), "Type errors are complained about");
		ok(ext_command == NULL, "No command returned for command with argument type errors");

		g_clear_error(&error);
		ext_command = command_parse("[1234567890] ADD_HOST_COMMENT;my_host;1;4lyfe;this is my comment, there are many like it but this one is mine", COMMAND_SYNTAX_NOKV, &error);
		ok(g_error_matches(error, NM_COMMAND_ERROR, CMD_ERROR_PARSE_TYPE_MISMATCH), "Junk characters after integer arguments are complained about");
		ok(ext_command == NULL, "No command returned for command with argument type mismatch errors");

		g_clear_error(&error);
		ext_command = command_create("ADD_HOST_COMMENT_WITH_TIMESTAMP", test__add_host_comment_handler, "This is a description for a command named ADD_HOST_COMMENT", NULL);
		command_argument_add(ext_command, "host", STRING, NULL, NULL);
		command_argument_add(ext_command, "persistent", BOOL, NULL, NULL);
		i_val = 42;
		command_argument_add(ext_command, "author", INTEGER, &i_val, NULL);
		s_val = "No comment";
		command_argument_add(ext_command, "comment", STRING, s_val, NULL);
		t_val = 0;
		command_argument_add(ext_command, "timestamp", TIMESTAMP, &t_val, NULL);
		command_register(ext_command, -1);

		g_clear_error(&error);
		ext_command = command_parse("[1234567890] ADD_HOST_COMMENT_WITH_TIMESTAMP;my_host;1;441;this is my comment, there are many like it but this one is mine;1234987650", COMMAND_SYNTAX_NOKV, &error);
		ok(error == NULL, "No error when parsing proper commands");
		ok(1234987650 == *(time_t *)command_argument_get_value(ext_command, "timestamp"), "Timestamp value parsed successfully");
		command_destroy(ext_command);


		g_clear_error(&error);
		ext_command = command_parse("[1234567890] ADD_HOST_COMMENT_WITH_TIMESTAMP;my_host;4;441;this is my comment, there are many like it but this one is mine;1234987650", COMMAND_SYNTAX_NOKV, &error);
		ok(g_error_matches(error, NM_COMMAND_ERROR, CMD_ERROR_VALIDATION_FAILURE), "Invalid BOOL value (4) is complained about");
		ok(NULL == ext_command, "No command returned for command with invalid argument values");

		g_clear_error(&error);
		ext_command = command_parse("[1234567890] ADD_HOST_COMMENT_WITH_TIMESTAMP;my_host;1;441;this is my comment, there are many like it but this one is mine;14:49", COMMAND_SYNTAX_NOKV, &error);

		ok(g_error_matches(error, NM_COMMAND_ERROR, CMD_ERROR_PARSE_TYPE_MISMATCH), "Malformed timestamp value is complained about");
		ok(NULL == ext_command, "No command returned for command with argument type mismatch");

		g_clear_error(&error);
		ext_command = command_parse("[1234567890] ADD_HOST_COMMENT_WITH_TIMESTAMP;my_host;1;441;;", COMMAND_SYNTAX_NOKV, &error);
		ok(error == NULL, "Missing arguments which have default values are not complained about");
		ok(!strcmp("No comment", command_argument_get_value(ext_command, "comment")), "Default value is used for missing argument");
		ok(t_val == *(time_t *)command_argument_get_value(ext_command, "timestamp"), "Default value is used for missing argument at end of arg string");
		command_destroy(ext_command);

		g_clear_error(&error);
		ext_command = command_parse("[1234567890] ADD_HOST_COMMENT_WITH_TIMESTAMP;some_host;;441;;13485799", COMMAND_SYNTAX_NOKV, &error);
		ok(g_error_matches(error, NM_COMMAND_ERROR, CMD_ERROR_PARSE_MISSING_ARG), "Missing arguments which don't have default values are complained about");
		ok(NULL == ext_command, "No command returned for command with missing argument and no default");

		g_clear_error(&error);
		ext_command = command_create("ADD_SVC_COMMENT", test__add_service_comment_handler, "This is a description for a command named CMD_ADD_SVC_COMMENT", NULL);
		command_argument_add(ext_command, "service", SERVICE, NULL, NULL);
		command_argument_add(ext_command, "persistent", BOOL, &b_val, NULL);
		command_argument_add(ext_command, "author", INTEGER, &i_val, NULL);
		command_argument_add(ext_command, "comment", STRING, s_val, NULL);
		command_register(ext_command, -1);

		g_clear_error(&error);
		ext_command = command_parse("[1234567890] ADD_SVC_COMMENT;my_host;NO_SUCH_SERVICE;1;441;this is my service comment, there are many like it but this one is mine", COMMAND_SYNTAX_NOKV, &error);
		ok(g_error_matches(error, NM_COMMAND_ERROR, CMD_ERROR_VALIDATION_FAILURE), "Invalid service is complained about");
		ok(NULL == ext_command, "No command returned for command with invalid service");

		g_clear_error(&error);
		ext_command = command_create("ADD_SVC_COMMENT_2", test__add_service_comment_handler, "This is a description for a command with a custom service validator", NULL);
		command_argument_add(ext_command, "service", SERVICE, NULL, custom_service_validator);
		command_argument_add(ext_command, "persistent", BOOL, &b_val, NULL);
		command_argument_add(ext_command, "author", INTEGER, &i_val, NULL);
		command_argument_add(ext_command, "comment", STRING, s_val, NULL);
		command_register(ext_command, -1);

		g_clear_error(&error);
		ext_command = command_parse("[1234567890] ADD_SVC_COMMENT_2;my_host;LETS_PRETEND_THIS_EXISTS;1;441;this is my service comment, there are many like it but this one is mine", COMMAND_SYNTAX_NOKV, &error);
		ok(error == NULL, "Custom validator does not decline our invalid service");
		command_destroy(ext_command);

		g_clear_error(&error);
		ext_command = command_create("DEL_HOST_COMMENT", test__del_host_comment_handler, "This command is used to delete a specific host comment.", NULL);
		command_argument_add(ext_command, "comment_id", ULONG, NULL, NULL);
		command_register(ext_command, -1);

		g_clear_error(&error);
		ext_command = command_parse("[1234567890] DEL_HOST_COMMENT;10;Excess argument;snurre", COMMAND_SYNTAX_NOKV, &error);
		ok(g_error_matches(error, NM_COMMAND_ERROR, CMD_ERROR_PARSE_EXCESS_ARG), "Excess arguments are complained about");
		ok(ext_command == NULL, "No command returned for commands with excess arguments");

		g_clear_error(&error);
		ext_command = command_parse("[1234567890] DEL_HOST_COMMENT;10", COMMAND_SYNTAX_NOKV, &error);
		ok((unsigned long) 10 ==  *(unsigned long *)command_argument_get_value(ext_command, "comment_id"), "ULONG argument parsed correctly");
		command_destroy(ext_command);

		ext_command = command_create("DEL_HOST_COMMENT_2", test__del_host_comment_handler, "This command is used to delete a specific host comment.", "int=comment_id;str=string_arg");
		command_register(ext_command, -1);
		g_clear_error(&error);
		ext_command = command_parse("[1234567890] DEL_HOST_COMMENT_2;10;foobar", COMMAND_SYNTAX_NOKV, &error);
		ok(error == NULL, "No error when parsing command created with argspec");
		ok(!strcmp("foobar", command_argument_get_value(ext_command, "string_arg")), "Can parse command created with argspec (string arg)");
		ok(10 == *(int *)command_argument_get_value(ext_command, "comment_id"), "Can parse command created with argspec (int arg)");
		command_destroy(ext_command);

		g_clear_error(&error);
		ext_command = command_parse("[1234567890] DEL_HOST_COMMENT_2;1;", COMMAND_SYNTAX_NOKV, &error);
		ok (ext_command == NULL, "Missing argument at end of arg string is complained about");
		ok(g_error_matches(error, NM_COMMAND_ERROR, CMD_ERROR_PARSE_MISSING_ARG), "Missing argument at end of arg string raises the correct error");


		g_clear_error(&error);
		ext_command = command_create("DISABLE_NOTIFICATIONS", test__disable_notifications_handler,
			"Disables host and service notifications on a program-wide basis.", NULL);
		command_register(ext_command, -1);
		ext_command = command_parse("[1234567890] DISABLE_NOTIFICATIONS", COMMAND_SYNTAX_NOKV, &error);
		ok(ext_command != NULL, "No problem parsing commands with no arguments (when none required)");
		command_destroy(ext_command);

		g_clear_error(&error);
		ext_command = command_create("DO_THING_WITH_TIMEPERIOD", test__do_thing_with_timeperiod_handler,
				"Does a thing with a timeperiod", NULL);
		command_argument_add(ext_command, "timeperiod", TIMEPERIOD, NULL, NULL);
		command_register(ext_command, -1);

		g_clear_error(&error);
		ext_command = command_parse("[1234567890] DO_THING_WITH_TIMEPERIOD;24x8", COMMAND_SYNTAX_NOKV, &error);
		ok(ext_command == NULL, "No command returned when timeperiod arg is invalid");
		ok(g_error_matches(error, NM_COMMAND_ERROR, CMD_ERROR_VALIDATION_FAILURE), "Validation error raised for invalid timeperiod");

		registered_timeperiod = find_timeperiod("24x7");
		assert(NULL != registered_timeperiod);
		g_clear_error(&error);
		ext_command = command_parse("[1234567890] DO_THING_WITH_TIMEPERIOD;24x7", COMMAND_SYNTAX_NOKV, &error);
		ok(ext_command != NULL, "Command returned when timeperiod arg is not invalid");
		ok(error == NULL, "Validation error not raised for valid timeperiod");
		ok(registered_timeperiod == command_argument_get_value(ext_command, "timeperiod"), "The correct timeperiod is returned");
		command_destroy(ext_command);

		/** CONTACT SETUP*/
		g_clear_error(&error);
		ext_command = command_create("FIND_CONTACT", test__do_thing_with_contact_handler, "Does a thing with contact", NULL);
		command_argument_add(ext_command, "contact", CONTACT, NULL, NULL);
		command_register(ext_command, -1);
		created_contact = find_contact("nagiosadmin");
		assert(NULL != created_contact);

		/** CONTACT TEST*/
		g_clear_error(&error);
		ext_command = command_parse("[1234567890] FIND_CONTACT;bango", COMMAND_SYNTAX_NOKV, &error);
		ok(ext_command == NULL, "No command returned when contact arg is invalid");
		ok(g_error_matches(error, NM_COMMAND_ERROR, CMD_ERROR_VALIDATION_FAILURE), "Validation error raised for invalid contact");

		/** CONTACT TEST*/
		g_clear_error(&error);
		ext_command = command_parse("[1234567890] FIND_CONTACT;nagiosadmin", COMMAND_SYNTAX_NOKV, &error);
		ok(ext_command != NULL, "Command returned when contact arg is not invalid");
		ok(error == NULL, "Validation error not raised for valid contact");
		fetched_contact = command_argument_get_value(ext_command, "contact");
		ok(created_contact->name == fetched_contact->name, "The correct contact is returned");

		/** CONTACT TEARDOWN*/
		command_destroy(ext_command);

		g_clear_error(&error);
		ext_command = command_parse("[1234567890] _MY_CUSTOMARILY_CUSTOM_CUSTARD_COMMAND;foo;bar;baz;33", COMMAND_SYNTAX_NOKV, &error);
		ok(g_error_matches(error, NM_COMMAND_ERROR, CMD_ERROR_CUSTOM_COMMAND), "Custom command reported as such");
		ok(ext_command != NULL, "Raw command returned when parsing custom command");
		ok(!strcmp("foo;bar;baz;33", command_raw_arguments(ext_command)), "Raw arguments properly set for custom command");
		ok(command_entry_time(ext_command) == (time_t)1234567890, "Entry time set for custom command");
		command_destroy(ext_command);

		g_clear_error(&error);
	}
	registered_commands_deinit();

}
Example #8
0
int setup_host_variables(host *new_host, const char *display_name, const char *alias, const char *address, const char *check_period, int initial_state, double check_interval, double retry_interval, int max_attempts, int notification_options, double notification_interval, double first_notification_delay, const char *notification_period, int notifications_enabled, const char *check_command, int checks_enabled, int accept_passive_checks, const char *event_handler, int event_handler_enabled, int flap_detection_enabled, double low_flap_threshold, double high_flap_threshold, int flap_detection_options, int stalking_options, int process_perfdata, int check_freshness, int freshness_threshold, const char *notes, const char *notes_url, const char *action_url, const char *icon_image, const char *icon_image_alt, const char *vrml_image, const char *statusmap_image, int x_2d, int y_2d, int have_2d_coords, double x_3d, double y_3d, double z_3d, int have_3d_coords, int retain_status_information, int retain_nonstatus_information, int obsess, unsigned int hourly_value)
{
	timeperiod *check_tp = NULL, *notify_tp = NULL;

	if (check_period && !(check_tp = find_timeperiod(check_period))) {
		nm_log(NSLOG_CONFIG_ERROR, "Error: Failed to locate check_period '%s' for host '%s'!\n",
		       check_period, new_host->name);
		return -1;
	}
	if (notification_period && !(notify_tp = find_timeperiod(notification_period))) {
		nm_log(NSLOG_CONFIG_ERROR, "Error: Failed to locate notification_period '%s' for host '%s'!\n",
		       notification_period, new_host->name);
		return -1;
	}
	/* check values */
	if (max_attempts <= 0) {
		nm_log(NSLOG_CONFIG_ERROR, "Error: max_check_attempts must be a positive integer host '%s'\n", new_host->name);
		return -1;
	}
	if (check_interval < 0) {
		nm_log(NSLOG_CONFIG_ERROR, "Error: Invalid check_interval value for host '%s'\n", new_host->name);
		return -1;
	}
	if (notification_interval < 0) {
		nm_log(NSLOG_CONFIG_ERROR, "Error: Invalid notification_interval value for host '%s'\n", new_host->name);
		return -1;
	}
	if (first_notification_delay < 0) {
		nm_log(NSLOG_CONFIG_ERROR, "Error: Invalid first_notification_delay value for host '%s'\n", new_host->name);
		return -1;
	}
	if (freshness_threshold < 0) {
		nm_log(NSLOG_CONFIG_ERROR, "Error: Invalid freshness_threshold value for host '%s'\n", new_host->name);
		return -1;
	}

	/* assign string vars */
	if (display_name)
		new_host->display_name = nm_strdup(display_name);
	if (alias)
		new_host->alias = nm_strdup(alias);
	if (address)
		new_host->address = nm_strdup(address);
	if (check_tp) {
		new_host->check_period = check_tp->name;
		new_host->check_period_ptr = check_tp;
	}
	new_host->notification_period = notify_tp ? notify_tp->name : NULL;
	new_host->notification_period_ptr = notify_tp;
	if (check_command) {
		new_host->check_command = nm_strdup(check_command);
		new_host->check_command_ptr = find_bang_command(check_command);
		if (new_host->check_command_ptr == NULL) {
			nm_log(NSLOG_VERIFICATION_ERROR, "Error: Host check command '%s' specified for host '%s' is not defined anywhere!", new_host->check_command, new_host->name);
			return -1;
		}
	}
	if (event_handler) {
		new_host->event_handler = nm_strdup(event_handler);
		new_host->event_handler_ptr = find_bang_command(event_handler);
		if (new_host->event_handler_ptr == NULL) {
			nm_log(NSLOG_VERIFICATION_ERROR, "Error: Event handler command '%s' specified for host '%s' not defined anywhere", new_host->event_handler, new_host->name);
			return -1;
		}
	}
	new_host->notes = notes ? nm_strdup(notes) : NULL;
	new_host->notes_url = notes_url ? nm_strdup(notes_url) : NULL;
	new_host->action_url = action_url ? nm_strdup(action_url) : NULL;
	new_host->icon_image = icon_image ? nm_strdup(icon_image) : NULL;
	new_host->icon_image_alt = icon_image_alt ? nm_strdup(icon_image_alt) : NULL;
	new_host->vrml_image = vrml_image ? nm_strdup(vrml_image) : NULL;
	new_host->statusmap_image = statusmap_image ? nm_strdup(statusmap_image) : NULL;

	/* duplicate non-string vars */
	new_host->hourly_value = hourly_value;
	new_host->max_attempts = max_attempts;
	new_host->check_interval = check_interval;
	new_host->retry_interval = retry_interval;
	new_host->notification_interval = notification_interval;
	new_host->first_notification_delay = first_notification_delay;
	new_host->notification_options = notification_options;
	new_host->flap_detection_enabled = (flap_detection_enabled > 0) ? TRUE : FALSE;
	new_host->low_flap_threshold = low_flap_threshold;
	new_host->high_flap_threshold = high_flap_threshold;
	new_host->flap_detection_options = flap_detection_options;
	new_host->stalking_options = stalking_options;
	new_host->process_performance_data = (process_perfdata > 0) ? TRUE : FALSE;
	new_host->check_freshness = (check_freshness > 0) ? TRUE : FALSE;
	new_host->freshness_threshold = freshness_threshold;
	new_host->checks_enabled = (checks_enabled > 0) ? TRUE : FALSE;
	new_host->accept_passive_checks = (accept_passive_checks > 0) ? TRUE : FALSE;
	new_host->event_handler_enabled = (event_handler_enabled > 0) ? TRUE : FALSE;
	new_host->x_2d = x_2d;
	new_host->y_2d = y_2d;
	new_host->have_2d_coords = (have_2d_coords > 0) ? TRUE : FALSE;
	new_host->x_3d = x_3d;
	new_host->y_3d = y_3d;
	new_host->z_3d = z_3d;
	new_host->have_3d_coords = (have_3d_coords > 0) ? TRUE : FALSE;
	new_host->obsess = (obsess > 0) ? TRUE : FALSE;
	new_host->retain_status_information = (retain_status_information > 0) ? TRUE : FALSE;
	new_host->retain_nonstatus_information = (retain_nonstatus_information > 0) ? TRUE : FALSE;
	new_host->current_state = initial_state;
	new_host->last_state = initial_state;
	new_host->last_hard_state = initial_state;
	new_host->current_attempt = (initial_state == STATE_UP) ? 1 : max_attempts;
	new_host->notifications_enabled = (notifications_enabled > 0) ? TRUE : FALSE;

	return 0;
}
Example #9
0
/* Following main() declaration required by older versions of Perl ut 5.00503 */
int main(int argc, char **argv, char **env) {
	int result;
	int error = FALSE;
	char *buffer = NULL;
	int display_license = FALSE;
	int display_help = FALSE;
	int c = 0;
	struct tm *tm, tm_s;
	time_t now;
	char datestring[256];
	nagios_macros *mac;

	mac = get_global_macros();



#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'},
			{"test-scheduling", no_argument, 0, 's'},
			{"dont-verify-objects", no_argument, 0, 'o'},
			{"dont-verify-paths", no_argument, 0, 'x'},
			{"precache-objects", no_argument, 0, 'p'},
			{"use-precached-objects", no_argument, 0, 'u'},
			{0, 0, 0, 0}
		};
#endif

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


	/* get all command line arguments */
	while(1) {

#ifdef HAVE_GETOPT_H
		c = getopt_long(argc, argv, "+hVvdsoxpu", long_options, &option_index);
#else
		c = getopt(argc, argv, "+hVvdsoxpu");
#endif

		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 = TRUE;
				break;

			case 's': /* scheduling check */
				test_scheduling = TRUE;
				break;

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

			case 'o': /* don't verify objects */
				/*
				verify_object_relationships=FALSE;
				*/
				break;

			case 'x': /* don't verify circular paths */
				verify_circular_paths = FALSE;
				break;

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

			case 'u': /* use precached object config */
				use_precached_objects = TRUE;
				break;

			default:
				break;
			}

		}

	/* make sure we have the right combination of arguments */
	if(precache_objects == TRUE && (test_scheduling == FALSE && verify_config == FALSE)) {
		error = TRUE;
		display_help = TRUE;
		}

#ifdef DEBUG_MEMORY
	mtrace();
#endif

	if(daemon_mode == FALSE) {
		printf("\nNagios Core %s\n", PROGRAM_VERSION);
		printf("Copyright (c) 2009-2011 Nagios Core Development Team and Community Contributors\n");
		printf("Copyright (c) 1999-2009 Ethan Galstad\n");
		printf("Last Modified: %s\n", PROGRAM_MODIFICATION_DATE);
		printf("License: GPL\n\n");
		printf("Website: http://www.nagios.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\n");
		printf("  -s, --test-scheduling        Shows projected/recommended check scheduling and other\n");
		printf("                               diagnostic info based on the current configuration files.\n");
		/*printf("  -o, --dont-verify-objects    Don't verify object relationships - USE WITH CAUTION!\n");*/
		printf("  -x, --dont-verify-paths      Don't check for circular object paths - USE WITH CAUTION!\n");
		printf("  -p, --precache-objects       Precache object configuration - use with -v or -s options\n");
		printf("  -u, --use-precached-objects  Use precached object config file\n");
		printf("  -d, --daemon                 Starts Nagios in daemon mode, instead of as a foreground process\n");
		printf("\n");
		printf("Visit the Nagios website at http://www.nagios.org/ for bug fixes, new\n");
		printf("releases, online documentation, FAQs, information on subscribing to\n");
		printf("the mailing lists, and commercial support options for Nagios.\n");
		printf("\n");

		exit(ERROR);
		}

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

	/* config file is last argument specified */
	config_file = (char *)strdup(argv[optind]);
	if(config_file == NULL) {
		printf("Error allocating memory.\n");
		exit(ERROR);
		}

	/* make sure the config file uses an absolute path */
	if(config_file[0] != '/') {

		/* save the name of the config file */
		buffer = (char *)strdup(config_file);

		/* reallocate a larger chunk of memory */
		config_file = (char *)realloc(config_file, MAX_FILENAME_LENGTH);
		if(config_file == NULL) {
			printf("Error allocating memory.\n");
			exit(ERROR);
			}

		/* get absolute path of current working directory */
		getcwd(config_file, MAX_FILENAME_LENGTH);

		/* append a forward slash */
		strncat(config_file, "/", 1);
		config_file[MAX_FILENAME_LENGTH - 1] = '\x0';

		/* append the config file to the path */
		strncat(config_file, buffer, MAX_FILENAME_LENGTH - strlen(config_file) - 1);
		config_file[MAX_FILENAME_LENGTH - 1] = '\x0';

		my_free(buffer);
		}


	/* we're just verifying the configuration... */
	if(verify_config == TRUE) {

		/* reset program variables */
		reset_variables();

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

		/* read in the configuration files (main config file, resource and object config files) */
		if((result = read_main_config_file(config_file)) == OK) {

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

			/* drop privileges */
			if((result = drop_privileges(nagios_user, nagios_group)) == ERROR)
				printf("   Failed to drop privileges.  Aborting.");
			else {
				/* read object config files */
				if((result = read_all_object_data(config_file)) == OK)
					printf("   Read object config files okay...\n");
				else
					printf("   Error processing object config files!\n");
				}
			}
		else
			printf("   Error processing main config file!\n\n");

		printf("\n");

		/* there was a problem reading the config files */
		if(result != OK) {

			/* if the config filename looks fishy, warn the user */
			if(!strstr(config_file, "nagios.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 '/usr/local/nagios/etc/nagios.cfg'\n");
				}

			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 defintions.  If you are upgrading from a previous\n");
			printf("     version of Nagios, 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");
			}

		/* the config files were okay, so run the pre-flight check */
		else {

			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("\nThings look okay - No serious problems were detected during the pre-flight check\n");
			else {
				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 defintions.  If you are upgrading from a previous\n");
				printf("     version of Nagios, 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");
				}
			}

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

		/* free config_file */
		my_free(config_file);

		/* exit */
		exit(result);
		}


	/* we're just testing scheduling... */
	else if(test_scheduling == TRUE) {

		/* reset program variables */
		reset_variables();

		/* read in the configuration files (main config file and all host config files) */
		result = read_main_config_file(config_file);

		/* drop privileges */
		if(result == OK)
			if((result = drop_privileges(nagios_user, nagios_group)) == ERROR)
				printf("Failed to drop privileges.  Aborting.");

		/* read object config files */
		if(result == OK)
			result = read_all_object_data(config_file);

		/* read initial service and host state information */
		if(result == OK) {
			initialize_retention_data(config_file);
			read_initial_state_information();
			}

		if(result != OK)
			printf("***> One or more problems was encountered while reading configuration data...\n");

		/* run the pre-flight check to make sure everything looks okay */
		if(result == OK) {
			if((result = pre_flight_check()) != OK)
				printf("***> One or more problems was encountered while running the pre-flight check...\n");
			}

		if(result == OK) {

			/* initialize the event timing loop */
			init_timing_loop();

			/* display scheduling information */
			display_scheduling_info();

			if(precache_objects == TRUE) {
				printf("\n");
				printf("OBJECT PRECACHING\n");
				printf("-----------------\n");
				printf("Object config files were precached.\n");
				}
			}

#undef TEST_TIMEPERIODS
#ifdef TEST_TIMEPERIODS
		/* DO SOME TIMEPERIOD TESTING - ADDED 08/11/2009 */
		time_t now, pref_time, valid_time;
		timeperiod *tp;
		tp = find_timeperiod("247_exclusion");
		time(&now);
		pref_time = now;
		get_next_valid_time(pref_time, &valid_time, tp);
		printf("=====\n");
		printf("CURRENT:   %lu = %s", (unsigned long)now, ctime(&now));
		printf("PREFERRED: %lu = %s", (unsigned long)pref_time, ctime(&pref_time));
		printf("NEXT:      %lu = %s", (unsigned long)valid_time, ctime(&valid_time));
		printf("=====\n");
#endif

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

		/* exit */
		exit(result);
		}


	/* else start to monitor things... */
	else {

		/* keep monitoring things until we get a shutdown command */
		do {

			/* reset program variables */
			reset_variables();

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

			/* read in the configuration files (main and resource config files) */
			result = read_main_config_file(config_file);

			/* 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);
			my_free(mac->x[MACRO_PROCESSSTARTTIME]);
			asprintf(&mac->x[MACRO_PROCESSSTARTTIME], "%lu", (unsigned long)program_start);

			/* open debug log */
			open_debug_log();

			/* drop privileges */
			if(drop_privileges(nagios_user, nagios_group) == ERROR) {

				logit(NSLOG_PROCESS_INFO | NSLOG_RUNTIME_ERROR | NSLOG_CONFIG_ERROR, TRUE, "Failed to drop privileges.  Aborting.");

				cleanup();
				exit(ERROR);
				}

#ifdef USE_EVENT_BROKER
			/* initialize modules */
			neb_init_modules();
			neb_init_callback_list();
#endif

			/* this must be logged after we read config data, as user may have changed location of main log file */
			logit(NSLOG_PROCESS_INFO, TRUE, "Nagios %s starting... (PID=%d)\n", PROGRAM_VERSION, (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);
			logit(NSLOG_PROCESS_INFO, TRUE, "Local time is %s", datestring);

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

#ifdef USE_EVENT_BROKER
			/* load modules */
			neb_load_all_modules();

			/* send program data to broker */
			broker_program_state(NEBTYPE_PROCESS_PRELAUNCH, NEBFLAG_NONE, NEBATTR_NONE, NULL);
#endif

			/* read in all object config data */
			if(result == OK)
				result = read_all_object_data(config_file);

			/* there was a problem reading the config files */
			if(result != OK)
				logit(NSLOG_PROCESS_INFO | NSLOG_RUNTIME_ERROR | NSLOG_CONFIG_ERROR, TRUE, "Bailing out due to one or more errors encountered in the configuration files. Run Nagios 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*/
				if((result = pre_flight_check()) != OK)
					logit(NSLOG_PROCESS_INFO | NSLOG_RUNTIME_ERROR | NSLOG_VERIFICATION_ERROR, TRUE, "Bailing out due to errors encountered while running the pre-flight check.  Run Nagios from the command line with the -v option to verify your config before restarting. (PID=%d)\n", (int)getpid());
				}

			/* 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(config_file, TRUE);

					/* shutdown the external command worker thread */
					shutdown_command_file_worker_thread();

					/* close and delete the external command file FIFO */
					close_command_file();

					/* cleanup embedded perl interpreter */
					if(embedded_perl_initialized == TRUE)
						deinit_embedded_perl();
					}

#ifdef USE_EVENT_BROKER
				/* send program data to broker */
				broker_program_state(NEBTYPE_PROCESS_SHUTDOWN, NEBFLAG_PROCESS_INITIATED, NEBATTR_SHUTDOWN_ABNORMAL, NULL);
#endif
				cleanup();
				exit(ERROR);
				}



			/* initialize embedded Perl interpreter */
			/* NOTE 02/15/08 embedded Perl must be initialized if compiled in, regardless of whether or not its enabled in the config file */
			/* It compiled it, but not initialized, Nagios will segfault in readdir() calls, as libperl takes this function over */
			if(embedded_perl_initialized == FALSE) {
				/*				if(enable_embedded_perl==TRUE){*/
#ifdef EMBEDDEDPERL
				init_embedded_perl(env);
#else
				init_embedded_perl(NULL);
#endif
				embedded_perl_initialized = TRUE;
				/*					}*/
				}

			/* handle signals (interrupts) */
			setup_sighandler();


#ifdef USE_EVENT_BROKER
			/* send program data to broker */
			broker_program_state(NEBTYPE_PROCESS_START, NEBFLAG_NONE, NEBATTR_NONE, NULL);
#endif

			/* 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) {
					logit(NSLOG_PROCESS_INFO | NSLOG_RUNTIME_ERROR, TRUE, "Bailing out due to failure to daemonize. (PID=%d)", (int)getpid());

#ifdef USE_EVENT_BROKER
					/* send program data to broker */
					broker_program_state(NEBTYPE_PROCESS_SHUTDOWN, NEBFLAG_PROCESS_INITIATED, NEBATTR_SHUTDOWN_ABNORMAL, NULL);
#endif
					cleanup();
					exit(ERROR);
					}

				asprintf(&buffer, "Finished daemonizing... (New PID=%d)\n", (int)getpid());
				write_to_all_logs(buffer, NSLOG_PROCESS_INFO);
				my_free(buffer);

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

			/* open the command file (named pipe) for reading */
			result = open_command_file();
			if(result != OK) {

				logit(NSLOG_PROCESS_INFO | NSLOG_RUNTIME_ERROR, TRUE, "Bailing out due to errors encountered while trying to initialize the external command file... (PID=%d)\n", (int)getpid());

#ifdef USE_EVENT_BROKER
				/* send program data to broker */
				broker_program_state(NEBTYPE_PROCESS_SHUTDOWN, NEBFLAG_PROCESS_INITIATED, NEBATTR_SHUTDOWN_ABNORMAL, NULL);
#endif
				cleanup();
				exit(ERROR);
				}

			/* initialize status data unless we're starting */
			if(sigrestart == FALSE)
				initialize_status_data(config_file);

			/* read initial service and host state information  */
			initialize_retention_data(config_file);
			read_initial_state_information();

			/* initialize comment data */
			initialize_comment_data(config_file);

			/* initialize scheduled downtime data */
			initialize_downtime_data(config_file);

			/* initialize performance data */
			initialize_performance_data(config_file);

			/* Determine which checks are still executing so they are not
				scheduled when the timing loop is initialized */
			find_executing_checks(check_result_path);

			/* initialize the event timing loop */
			init_timing_loop();

			/* initialize check statistics */
			init_check_stats();

			/* check for updates */
			check_for_nagios_updates(FALSE, TRUE);

			/* update all status data (with retained information) */
			update_all_status_data();

			/* log initial host and service state */
			log_host_states(INITIAL_STATES, NULL);
			log_service_states(INITIAL_STATES, NULL);

			/* reset the restart flag */
			sigrestart = FALSE;

#ifdef USE_EVENT_BROKER
			/* send program data to broker */
			broker_program_state(NEBTYPE_PROCESS_EVENTLOOPSTART, NEBFLAG_NONE, NEBATTR_NONE, NULL);
#endif

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

			/***** start monitoring all services *****/
			/* (doesn't return until a restart or shutdown signal is encountered) */
			event_execution_loop();

			/* 03/01/2007 EG Moved from sighandler() to prevent FUTEX locking problems under NPTL */
			/* 03/21/2007 EG SIGSEGV signals are still logged in sighandler() so we don't loose them */
			/* did we catch a signal? */
			if(caught_signal == TRUE) {

				if(sig_id == SIGHUP)
					asprintf(&buffer, "Caught SIGHUP, restarting...\n");
				else if(sig_id != SIGSEGV)
					asprintf(&buffer, "Caught SIG%s, shutting down...\n", sigs[sig_id]);

				write_to_all_logs(buffer, NSLOG_PROCESS_INFO);
				my_free(buffer);
				}

#ifdef USE_EVENT_BROKER
			/* send program data to broker */
			broker_program_state(NEBTYPE_PROCESS_EVENTLOOPEND, NEBFLAG_NONE, NEBATTR_NONE, NULL);
			if(sigshutdown == TRUE)
				broker_program_state(NEBTYPE_PROCESS_SHUTDOWN, NEBFLAG_USER_INITIATED, NEBATTR_SHUTDOWN_NORMAL, NULL);
			else if(sigrestart == TRUE)
				broker_program_state(NEBTYPE_PROCESS_RESTART, NEBFLAG_USER_INITIATED, NEBATTR_RESTART_NORMAL, NULL);
#endif

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

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

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

			/* clean up the comment data */
			cleanup_comment_data(config_file);

			/* clean up the status data unless we're restarting */
			if(sigrestart == FALSE)
				cleanup_status_data(config_file, TRUE);

			/* close and delete the external command file FIFO unless we're restarting */
			if(sigrestart == FALSE) {
				shutdown_command_file_worker_thread();
				close_command_file();
				}

			/* cleanup embedded perl interpreter */
			if(sigrestart == FALSE)
				deinit_embedded_perl();

			/* shutdown stuff... */
			if(sigshutdown == TRUE) {

				/* make sure lock file has been removed - it may not have been if we received a shutdown command */
				if(daemon_mode == TRUE)
					unlink(lock_file);

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

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

			/* close debug log */
			close_debug_log();

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

		/* free misc memory */
		my_free(config_file);
		}

	return OK;
	}