Exemple #1
0
/******************************************************************************
 *                                                                            *
 * Function: process_value                                                    *
 *                                                                            *
 * Purpose: process new item value                                            *
 *                                                                            *
 * Parameters:                                                                *
 *                                                                            *
 * Return value:                                                              *
 *                                                                            *
 * Author: Alexei Vladishev, Alexander Vladishev                              *
 *                                                                            *
 * Comments:                                                                  *
 *                                                                            *
 ******************************************************************************/
static void	process_value(zbx_uint64_t itemid, zbx_uint64_t *value_ui64, double *value_dbl,	zbx_timespec_t *ts,
		int ping_result, char *error)
{
	const char	*__function_name = "process_value";
	DC_ITEM		item;
	int		errcode;
	AGENT_RESULT	value;

	zabbix_log(LOG_LEVEL_DEBUG, "In %s()", __function_name);

	DCconfig_get_items_by_itemids(&item, &itemid, &errcode, 1);

	if (SUCCEED != errcode)
		goto clean;

	if (ITEM_STATUS_ACTIVE != item.status)
		goto clean;

	if (HOST_STATUS_MONITORED != item.host.status)
		goto clean;

	if (NOTSUPPORTED == ping_result)
	{
		item.state = ITEM_STATE_NOTSUPPORTED;
		dc_add_history(item.itemid, item.value_type, item.flags, NULL, ts, item.state, error);
	}
	else
	{
		init_result(&value);

		if (NULL != value_ui64)
			SET_UI64_RESULT(&value, *value_ui64);
		else
			SET_DBL_RESULT(&value, *value_dbl);

		item.state = ITEM_STATE_NORMAL;
		dc_add_history(item.itemid, item.value_type, item.flags, &value, ts, item.state, NULL);

		free_result(&value);
	}
clean:
	DCrequeue_items(&item.itemid, &item.state, &ts->sec, NULL, NULL, &errcode, 1);

	DCconfig_clean_items(&item, &errcode, 1);

	zabbix_log(LOG_LEVEL_DEBUG, "End of %s()", __function_name);
}
/******************************************************************************
 *                                                                            *
 * Function: process_value                                                    *
 *                                                                            *
 * Purpose: process new item value                                            *
 *                                                                            *
 * Parameters:                                                                *
 *                                                                            *
 * Return value:                                                              *
 *                                                                            *
 * Author: Alexei Vladishev, Alexander Vladishev                              *
 *                                                                            *
 * Comments:                                                                  *
 *                                                                            *
 ******************************************************************************/
static void	process_value(zbx_uint64_t itemid, zbx_uint64_t *value_ui64, double *value_dbl,	zbx_timespec_t *ts,
		int ping_result, char *error)
{
	const char	*__function_name = "process_value";
	DC_ITEM		item;
	int		errcode;
	AGENT_RESULT	value;

	assert(value_ui64 || value_dbl);

	zabbix_log(LOG_LEVEL_DEBUG, "In %s()", __function_name);

	DCconfig_get_items_by_itemids(&item, &itemid, &errcode, 1);

	if (SUCCEED != errcode)
		goto clean;

	if (NOTSUPPORTED == ping_result)
	{
		dc_add_history(item.itemid, item.value_type, item.flags, NULL, ts,
				ITEM_STATUS_NOTSUPPORTED, error, 0, NULL, 0, 0, 0, 0);
		DCrequeue_reachable_item(item.itemid, ITEM_STATUS_NOTSUPPORTED, ts->sec);
	}
	else
	{
		init_result(&value);

		if (NULL != value_ui64)
			SET_UI64_RESULT(&value, *value_ui64);
		else
			SET_DBL_RESULT(&value, *value_dbl);

		dc_add_history(item.itemid, item.value_type, item.flags, &value, ts,
				ITEM_STATUS_ACTIVE, NULL, 0, NULL, 0, 0, 0, 0);

		DCrequeue_reachable_item(item.itemid, ITEM_STATUS_ACTIVE, ts->sec);

		free_result(&value);
	}
clean:
	DCconfig_clean_items(&item, &errcode, 1);

	zabbix_log(LOG_LEVEL_DEBUG, "End of %s()", __function_name);
}
/******************************************************************************
 *                                                                            *
 * Function: get_pinger_hosts                                                 *
 *                                                                            *
 * Purpose: creates buffer which contains list of hosts to ping               *
 *                                                                            *
 * Parameters:                                                                *
 *                                                                            *
 * Return value: SUCCEED - the file was created successfully                  *
 *               FAIL - otherwise                                             *
 *                                                                            *
 * Author: Alexei Vladishev, Alexander Vladishev                              *
 *                                                                            *
 * Comments:                                                                  *
 *                                                                            *
 ******************************************************************************/
static void	get_pinger_hosts(icmpitem_t **icmp_items, int *icmp_items_alloc, int *icmp_items_count)
{
	const char		*__function_name = "get_pinger_hosts";
	DC_ITEM			items[MAX_ITEMS];
	int			i, num, count, interval, size, timeout, rc;
	char			error[MAX_STRING_LEN], *addr = NULL;
	icmpping_t		icmpping;
	icmppingsec_type_t	type;

	zabbix_log(LOG_LEVEL_DEBUG, "In %s()", __function_name);

	num = DCconfig_get_poller_items(ZBX_POLLER_TYPE_PINGER, items, MAX_ITEMS);

	for (i = 0; i < num; i++)
	{
		ZBX_STRDUP(items[i].key, items[i].key_orig);
		rc = substitute_key_macros(&items[i].key, &items[i].host, NULL, MACRO_TYPE_ITEM_KEY,
				error, sizeof(error));

		if (SUCCEED == rc)
		{
			items[i].interface.addr = (1 == items[i].interface.useip ?
					items[i].interface.ip_orig : items[i].interface.dns_orig);

			rc = parse_key_params(items[i].key, items[i].interface.addr, &icmpping, &addr, &count,
					&interval, &size, &timeout, &type, error, sizeof(error));
		}

		if (SUCCEED == rc)
		{
			add_icmpping_item(icmp_items, icmp_items_alloc, icmp_items_count, count, interval, size,
				timeout, items[i].itemid, addr, icmpping, type);
		}
		else
		{
			zbx_timespec_t	ts;

			zbx_timespec(&ts);

			dc_add_history(items[i].itemid, items[i].value_type, items[i].flags, NULL, &ts,
					ITEM_STATUS_NOTSUPPORTED, error, 0, NULL, 0, 0, 0, 0);

			DCrequeue_reachable_item(items[i].itemid, ITEM_STATUS_NOTSUPPORTED, ts.sec);
		}

		zbx_free(items[i].key);
	}

	DCconfig_clean_items(items, NULL, num);

	zabbix_log(LOG_LEVEL_DEBUG, "End of %s():%d", __function_name, *icmp_items_count);
}
Exemple #4
0
/******************************************************************************
 *                                                                            *
 * Function: proxy_process_new_value                                          *
 *                                                                            *
 * Purpose: process new item value                                            *
 *                                                                            *
 * Parameters: item - item data                                               *
 *             value - new value of the item                                  *
 *                                                                            *
 * Author: Alexei Vladishev                                                   *
 *                                                                            *
 * Comments: for trapper poller process                                       *
 *                                                                            *
 ******************************************************************************/
void	proxy_process_new_value(DB_ITEM *item, AGENT_RESULT *value, time_t now)
{
	zabbix_log( LOG_LEVEL_DEBUG, "In proxy_process_new_value(%s)",
		item->key);

	if (0 == CONFIG_DBSYNCER_FORKS)
	{
		proxy_add_history(item, value, now);
		proxy_update_item(item, value, now);
	}
	else
		dc_add_history(item, value, now);
}
Exemple #5
0
/******************************************************************************
 *                                                                            *
 * Function: set_item_value                                                   *
 *                                                                            *
 * Purpose: set item value for an SNMP Trap item                              *
 *                                                                            *
 * Author: Rudolfs Kreicbergs                                                 *
 *                                                                            *
 ******************************************************************************/
static void	set_item_value(DC_ITEM *item, char *trap, zbx_timespec_t *ts)
{
	AGENT_RESULT	value;
	int		timestamp = 0;

	init_result(&value);

	if (SUCCEED == set_result_type(&value, item->value_type, item->data_type, trap))
	{
		if (ITEM_VALUE_TYPE_LOG == item->value_type)
			calc_timestamp(trap, &timestamp, item->logtimefmt);

		dc_add_history(item->itemid, item->value_type, item->flags, &value,
				ts, ITEM_STATUS_ACTIVE, NULL, timestamp, NULL, 0, 0, 0, 0);
	}
	else
	{
		dc_add_history(item->itemid, item->value_type, item->flags, NULL,
				ts, ITEM_STATUS_NOTSUPPORTED, value.msg, 0, NULL, 0, 0, 0, 0);
	}

	free_result(&value);
}
Exemple #6
0
/******************************************************************************
 *                                                                            *
 * Function: process_new_value                                                *
 *                                                                            *
 * Purpose: process new item value                                            *
 *                                                                            *
 * Parameters: item - item data                                               *
 *             value - new value of the item                                  *
 *                                                                            *
 * Author: Alexei Vladishev                                                   *
 *                                                                            *
 * Comments: for trapper poller process                                       *
 *                                                                            *
 ******************************************************************************/
void	process_new_value(DB_ITEM *item, AGENT_RESULT *value, time_t now)
{
	zabbix_log( LOG_LEVEL_DEBUG, "In process_new_value(%s)",
		item->key);

	if (0 == CONFIG_DBSYNCER_FORKS)
	{
		if (SUCCEED == add_history(item, value, now))
		{
			update_item(item, value, now);
			update_functions(item, now);
			update_triggers(item->itemid);
		}
		else
			update_item(item, value, now);
	}
	else
		dc_add_history(item, value, now);
}
Exemple #7
0
static int	process_value(zbx_uint64_t itemid, AGENT_RESULT *value)
{
	const char	*__function_name = "process_value";
	DB_RESULT	result;
	DB_ROW		row;
	int		ret;

	zabbix_log(LOG_LEVEL_DEBUG, "In %s() itemid:" ZBX_FS_UI64, __function_name, itemid);

	result = DBselect(
			"select i.value_type"
			" from items i,hosts h"
			" where h.hostid=i.hostid"
				" and h.status=%d"
				" and i.status=%d"
				" and i.type=%d"
				" and i.itemid=" ZBX_FS_UI64
				" and (h.maintenance_status=%d or h.maintenance_type=%d)"
				DB_NODE,
			HOST_STATUS_MONITORED,
			ITEM_STATUS_ACTIVE,
			ITEM_TYPE_HTTPTEST,
			itemid,
			HOST_MAINTENANCE_STATUS_OFF, MAINTENANCE_TYPE_NORMAL,
			DBnode_local("h.hostid"));

	if (NULL != (row = DBfetch(result)))
	{
		dc_add_history(itemid, (unsigned char)atoi(row[0]), value, time(NULL),
				ITEM_STATUS_ACTIVE, NULL, 0, NULL, 0, 0, 0, 0);
		ret = SUCCEED;
	}
	else
		ret = FAIL;

	DBfree_result(result);

	zabbix_log(LOG_LEVEL_DEBUG, "End of %s():%s", __function_name, zbx_result_string(ret));

	return ret;
}
Exemple #8
0
static void	update_key_status(zbx_uint64_t hostid, int host_status, time_t now)
{
	const char	*__function_name = "update_key_status";
	DC_ITEM		*items = NULL;
	int		i, num;
	AGENT_RESULT	agent;

	zabbix_log(LOG_LEVEL_DEBUG, "In %s() hostid:" ZBX_FS_UI64 " status:%d",
			__function_name, hostid, host_status);

	num = DCconfig_get_items(hostid, SERVER_STATUS_KEY, &items);
	for (i = 0; i < num; i++)
	{
		init_result(&agent);
		SET_UI64_RESULT(&agent, host_status);

		dc_add_history(items[i].itemid, items[i].value_type, &agent, now, 0, NULL, 0, 0, 0, 0);

		free_result(&agent);
	}

	zbx_free(items);
}
Exemple #9
0
/******************************************************************************
 *                                                                            *
 * Function: process_trap_for_interface                                       *
 *                                                                            *
 * Purpose: add trap to all matching items for the specified interface        *
 *                                                                            *
 * Return value: SUCCEED - a matching item was found                          *
 *               FAIL - no matching item was found (including fallback items) *
 *                                                                            *
 * Author: Rudolfs Kreicbergs                                                 *
 *                                                                            *
 ******************************************************************************/
static int	process_trap_for_interface(zbx_uint64_t interfaceid, char *trap, zbx_timespec_t *ts)
{
	DC_ITEM			*items = NULL;
	const char		*regex;
	char			error[ITEM_ERROR_LEN_MAX];
	size_t			num, i;
	int			ret = FAIL, fb = -1, *lastclocks = NULL, *errcodes = NULL;
	zbx_uint64_t		*itemids = NULL;
	unsigned char		*states = NULL;
	AGENT_RESULT		*results = NULL;
	AGENT_REQUEST		request;
	zbx_vector_ptr_t	regexps;

	zbx_vector_ptr_create(&regexps);

	num = DCconfig_get_snmp_items_by_interfaceid(interfaceid, &items);

	itemids = zbx_malloc(itemids, sizeof(zbx_uint64_t) * num);
	states = zbx_malloc(states, sizeof(unsigned char) * num);
	lastclocks = zbx_malloc(lastclocks, sizeof(int) * num);
	errcodes = zbx_malloc(errcodes, sizeof(int) * num);
	results = zbx_malloc(results, sizeof(AGENT_RESULT) * num);

	for (i = 0; i < num; i++)
	{
		init_result(&results[i]);
		errcodes[i] = FAIL;

		items[i].key = zbx_strdup(items[i].key, items[i].key_orig);
		if (SUCCEED != substitute_key_macros(&items[i].key, NULL, &items[i], NULL,
				MACRO_TYPE_ITEM_KEY, error, sizeof(error)))
		{
			SET_MSG_RESULT(&results[i], zbx_strdup(NULL, error));
			errcodes[i] = NOTSUPPORTED;
			continue;
		}

		if (0 == strcmp(items[i].key, "snmptrap.fallback"))
		{
			fb = i;
			continue;
		}

		init_request(&request);

		if (SUCCEED != parse_item_key(items[i].key, &request))
			goto next;

		if (0 != strcmp(get_rkey(&request), "snmptrap"))
			goto next;

		if (1 < get_rparams_num(&request))
			goto next;

		if (NULL != (regex = get_rparam(&request, 0)))
		{
			if ('@' == *regex)
			{
				DCget_expressions_by_name(&regexps, regex + 1);

				if (0 == regexps.values_num)
				{
					SET_MSG_RESULT(&results[i], zbx_dsprintf(NULL,
							"Global regular expression \"%s\" does not exist.", regex + 1));
					errcodes[i] = NOTSUPPORTED;
					goto next;
				}
			}

			if (SUCCEED != regexp_match_ex(&regexps, trap, regex, ZBX_CASE_SENSITIVE))
				goto next;
		}

		if (SUCCEED == set_result_type(&results[i], items[i].value_type, items[i].data_type, trap))
			errcodes[i] = SUCCEED;
		else
			errcodes[i] = NOTSUPPORTED;
		ret = SUCCEED;
next:
		free_request(&request);
	}

	if (FAIL == ret && -1 != fb)
	{
		if (SUCCEED == set_result_type(&results[fb], items[fb].value_type, items[fb].data_type, trap))
			errcodes[fb] = SUCCEED;
		else
			errcodes[fb] = NOTSUPPORTED;
		ret = SUCCEED;
	}

	for (i = 0; i < num; i++)
	{
		switch (errcodes[i])
		{
			case SUCCEED:
				if (ITEM_VALUE_TYPE_LOG == items[i].value_type)
				{
					calc_timestamp(results[i].log->value, &results[i].log->timestamp,
							items[i].logtimefmt);
				}

				items[i].state = ITEM_STATE_NORMAL;
				dc_add_history(items[i].itemid, items[i].value_type, items[i].flags, &results[i],
						ts, items[i].state, NULL);

				itemids[i] = items[i].itemid;
				states[i] = items[i].state;
				lastclocks[i] = ts->sec;
				break;
			case NOTSUPPORTED:
				items[i].state = ITEM_STATE_NOTSUPPORTED;
				dc_add_history(items[i].itemid, items[i].value_type, items[i].flags, NULL,
						ts, items[i].state, results[i].msg);

				itemids[i] = items[i].itemid;
				states[i] = items[i].state;
				lastclocks[i] = ts->sec;
				break;
		}

		zbx_free(items[i].key);
		free_result(&results[i]);
	}

	zbx_free(results);

	DCrequeue_items(itemids, states, lastclocks, NULL, NULL, errcodes, num);

	zbx_free(errcodes);
	zbx_free(lastclocks);
	zbx_free(states);
	zbx_free(itemids);

	DCconfig_clean_items(items, NULL, num);
	zbx_free(items);

	zbx_regexp_clean_expressions(&regexps);
	zbx_vector_ptr_destroy(&regexps);

	dc_flush_history();

	return ret;
}
Exemple #10
0
static void	process_step_data(zbx_uint64_t httpstepid, zbx_httpstat_t *stat, zbx_timespec_t *ts)
{
    const char	*__function_name = "process_step_data";

    DB_RESULT	result;
    DB_ROW		row;
    unsigned char	types[3], states[3];
    DC_ITEM		items[3];
    zbx_uint64_t	itemids[3];
    int		lastclocks[3], errcodes[3];
    size_t		i, num = 0;
    AGENT_RESULT    value;

    zabbix_log(LOG_LEVEL_DEBUG, "In %s() rspcode:%ld time:" ZBX_FS_DBL " speed:" ZBX_FS_DBL,
               __function_name, stat->rspcode, stat->total_time, stat->speed_download);

    result = DBselect("select type,itemid from httpstepitem where httpstepid=" ZBX_FS_UI64, httpstepid);

    while (NULL != (row = DBfetch(result)))
    {
        if (3 == num)
        {
            THIS_SHOULD_NEVER_HAPPEN;
            break;
        }

        if (ZBX_HTTPITEM_TYPE_RSPCODE != (types[num] = (unsigned char)atoi(row[0])) &&
                ZBX_HTTPITEM_TYPE_TIME != types[num] && ZBX_HTTPITEM_TYPE_SPEED != types[num])
        {
            THIS_SHOULD_NEVER_HAPPEN;
            continue;
        }

        ZBX_STR2UINT64(itemids[num], row[1]);
        num++;
    }
    DBfree_result(result);

    DCconfig_get_items_by_itemids(items, itemids, errcodes, num);

    for (i = 0; i < num; i++)
    {
        if (SUCCEED != errcodes[i])
            continue;

        if (HOST_MAINTENANCE_STATUS_ON == items[i].host.maintenance_status &&
                MAINTENANCE_TYPE_NODATA == items[i].host.maintenance_type)
        {
            continue;
        }

        init_result(&value);

        switch (types[i])
        {
        case ZBX_HTTPITEM_TYPE_RSPCODE:
            SET_UI64_RESULT(&value, stat->rspcode);
            break;
        case ZBX_HTTPITEM_TYPE_TIME:
            SET_DBL_RESULT(&value, stat->total_time);
            break;
        case ZBX_HTTPITEM_TYPE_SPEED:
            SET_DBL_RESULT(&value, stat->speed_download);
            break;
        }

        items[i].state = ITEM_STATE_NORMAL;
        dc_add_history(items[i].itemid, items[i].value_type, 0, &value, ts, items[i].state, NULL);

        states[i] = items[i].state;
        lastclocks[i] = ts->sec;

        free_result(&value);
    }

    DCrequeue_items(itemids, states, lastclocks, NULL, NULL, errcodes, num);

    DCconfig_clean_items(items, errcodes, num);

    zabbix_log(LOG_LEVEL_DEBUG, "End of %s()", __function_name);
}
Exemple #11
0
static void	process_test_data(zbx_uint64_t httptestid, int lastfailedstep, double speed_download,
                              const char *err_str, zbx_timespec_t *ts)
{
    const char	*__function_name = "process_test_data";

    DB_RESULT	result;
    DB_ROW		row;
    unsigned char	types[3], states[3];
    DC_ITEM		items[3];
    zbx_uint64_t	itemids[3];
    int		lastclocks[3], errcodes[3];
    size_t		i, num = 0;
    AGENT_RESULT    value;

    zabbix_log(LOG_LEVEL_DEBUG, "In %s()", __function_name);

    result = DBselect("select type,itemid from httptestitem where httptestid=" ZBX_FS_UI64, httptestid);

    while (NULL != (row = DBfetch(result)))
    {
        if (3 == num)
        {
            THIS_SHOULD_NEVER_HAPPEN;
            break;
        }

        switch (types[num] = (unsigned char)atoi(row[0]))
        {
        case ZBX_HTTPITEM_TYPE_SPEED:
        case ZBX_HTTPITEM_TYPE_LASTSTEP:
            break;
        case ZBX_HTTPITEM_TYPE_LASTERROR:
            if (NULL == err_str)
                continue;
            break;
        default:
            THIS_SHOULD_NEVER_HAPPEN;
            continue;
        }

        ZBX_STR2UINT64(itemids[num], row[1]);
        num++;
    }
    DBfree_result(result);

    DCconfig_get_items_by_itemids(items, itemids, errcodes, num);

    for (i = 0; i < num; i++)
    {
        if (SUCCEED != errcodes[i])
            continue;

        if (HOST_MAINTENANCE_STATUS_ON == items[i].host.maintenance_status &&
                MAINTENANCE_TYPE_NODATA == items[i].host.maintenance_type)
        {
            continue;
        }

        init_result(&value);

        switch (types[i])
        {
        case ZBX_HTTPITEM_TYPE_SPEED:
            SET_UI64_RESULT(&value, speed_download);
            break;
        case ZBX_HTTPITEM_TYPE_LASTSTEP:
            SET_UI64_RESULT(&value, lastfailedstep);
            break;
        case ZBX_HTTPITEM_TYPE_LASTERROR:
            SET_STR_RESULT(&value, zbx_strdup(NULL, err_str));
            break;
        }

        items[i].state = ITEM_STATE_NORMAL;
        dc_add_history(items[i].itemid, items[i].value_type, 0, &value, ts, items[i].state, NULL);

        states[i] = items[i].state;
        lastclocks[i] = ts->sec;

        free_result(&value);
    }

    DCrequeue_items(itemids, states, lastclocks, NULL, NULL, errcodes, num);

    DCconfig_clean_items(items, errcodes, num);

    zabbix_log(LOG_LEVEL_DEBUG, "End of %s()", __function_name);
}
Exemple #12
0
/******************************************************************************
 *                                                                            *
 * Function: get_values                                                       *
 *                                                                            *
 * Purpose: retrieve values of metrics from monitored hosts                   *
 *                                                                            *
 * Parameters:                                                                *
 *                                                                            *
 * Return value:                                                              *
 *                                                                            *
 * Author: Alexei Vladishev                                                   *
 *                                                                            *
 * Comments: always SUCCEED                                                   *
 *                                                                            *
 ******************************************************************************/
static int	get_values(unsigned char poller_type)
{
	const char	*__function_name = "get_values";
	DC_ITEM		items[MAX_REACHABLE_ITEMS];
	AGENT_RESULT	agent;
	zbx_uint64_t	*ids = NULL, *snmpids = NULL, *ipmiids = NULL;
	int		ids_alloc = 0, snmpids_alloc = 0, ipmiids_alloc = 0,
			ids_num = 0, snmpids_num = 0, ipmiids_num = 0,
			i, now, num, res;
	static char	*key = NULL, *ipmi_ip = NULL, *params = NULL,
			*username = NULL, *publickey = NULL, *privatekey = NULL,
			*password = NULL, *snmp_community = NULL, *snmp_oid = NULL,
			*snmpv3_securityname = NULL, *snmpv3_authpassphrase = NULL,
			*snmpv3_privpassphrase = NULL;

	zabbix_log(LOG_LEVEL_DEBUG, "In %s()", __function_name);

	num = DCconfig_get_poller_items(poller_type, items, ZBX_POLLER_TYPE_UNREACHABLE != poller_type
								? MAX_REACHABLE_ITEMS : MAX_UNREACHABLE_ITEMS);

	for (i = 0; i < num; i++)
	{
		zbx_free(key);
		key = strdup(items[i].key_orig);
		substitute_simple_macros(NULL, NULL, NULL, &items[i], NULL,
				&key, MACRO_TYPE_ITEM_KEY, NULL, 0);
		items[i].key = key;

		switch (items[i].type)
		{
			case ITEM_TYPE_SNMPv3:
				zbx_free(snmpv3_securityname);
				zbx_free(snmpv3_authpassphrase);
				zbx_free(snmpv3_privpassphrase);

				snmpv3_securityname = strdup(items[i].snmpv3_securityname_orig);
				snmpv3_authpassphrase = strdup(items[i].snmpv3_authpassphrase_orig);
				snmpv3_privpassphrase = strdup(items[i].snmpv3_privpassphrase_orig);

				substitute_simple_macros(NULL, NULL, NULL, &items[i], NULL,
						&snmpv3_securityname, MACRO_TYPE_ITEM_FIELD, NULL, 0);
				substitute_simple_macros(NULL, NULL, NULL, &items[i], NULL,
						&snmpv3_authpassphrase, MACRO_TYPE_ITEM_FIELD, NULL, 0);
				substitute_simple_macros(NULL, NULL, NULL, &items[i], NULL,
						&snmpv3_privpassphrase, MACRO_TYPE_ITEM_FIELD, NULL, 0);

				items[i].snmpv3_securityname = snmpv3_securityname;
				items[i].snmpv3_authpassphrase = snmpv3_authpassphrase;
				items[i].snmpv3_privpassphrase = snmpv3_privpassphrase;
			case ITEM_TYPE_SNMPv1:
			case ITEM_TYPE_SNMPv2c:
				zbx_free(snmp_community);
				zbx_free(snmp_oid);

				snmp_community = strdup(items[i].snmp_community_orig);
				snmp_oid = strdup(items[i].snmp_oid_orig);

				substitute_simple_macros(NULL, NULL, NULL, &items[i], NULL,
						&snmp_community, MACRO_TYPE_ITEM_FIELD, NULL, 0);
				substitute_simple_macros(NULL, NULL, NULL, &items[i], NULL,
						&snmp_oid, MACRO_TYPE_ITEM_FIELD, NULL, 0);

				items[i].snmp_community = snmp_community;
				items[i].snmp_oid = snmp_oid;
				break;
			case ITEM_TYPE_IPMI:
				zbx_free(ipmi_ip);
				ipmi_ip = strdup(items[i].host.ipmi_ip_orig);
				substitute_simple_macros(NULL, NULL, NULL, &items[i], NULL,
						&ipmi_ip, MACRO_TYPE_HOST_IPMI_IP, NULL, 0);
				items[i].host.ipmi_ip = ipmi_ip;
				break;
			case ITEM_TYPE_DB_MONITOR:
				zbx_free(params);
				params = strdup(items[i].params_orig);
				substitute_simple_macros(NULL, NULL, NULL, &items[i], NULL,
						&params, MACRO_TYPE_ITEM_FIELD, NULL, 0);
				items[i].params = params;
				break;
			case ITEM_TYPE_SSH:
				zbx_free(username);
				zbx_free(publickey);
				zbx_free(privatekey);
				zbx_free(password);
				zbx_free(params);

				username = strdup(items[i].username_orig);
				publickey = strdup(items[i].publickey_orig);
				privatekey = strdup(items[i].privatekey_orig);
				password = strdup(items[i].password_orig);
				params = strdup(items[i].params_orig);

				substitute_simple_macros(NULL, NULL, NULL, &items[i], NULL,
						&username, MACRO_TYPE_ITEM_FIELD, NULL, 0);
				substitute_simple_macros(NULL, NULL, NULL, &items[i], NULL,
						&publickey, MACRO_TYPE_ITEM_FIELD, NULL, 0);
				substitute_simple_macros(NULL, NULL, NULL, &items[i], NULL,
						&privatekey, MACRO_TYPE_ITEM_FIELD, NULL, 0);
				substitute_simple_macros(NULL, NULL, NULL, &items[i], NULL,
						&password, MACRO_TYPE_ITEM_FIELD, NULL, 0);
				substitute_simple_macros(NULL, NULL, NULL, &items[i], NULL,
						&params, MACRO_TYPE_ITEM_FIELD, NULL, 0);

				items[i].username = username;
				items[i].publickey = publickey;
				items[i].privatekey = privatekey;
				items[i].password = password;
				items[i].params = params;
				break;
			case ITEM_TYPE_TELNET:
				zbx_free(username);
				zbx_free(password);
				zbx_free(params);

				username = strdup(items[i].username_orig);
				password = strdup(items[i].password_orig);
				params = strdup(items[i].params_orig);

				substitute_simple_macros(NULL, NULL, NULL, &items[i], NULL,
						&username, MACRO_TYPE_ITEM_FIELD, NULL, 0);
				substitute_simple_macros(NULL, NULL, NULL, &items[i], NULL,
						&password, MACRO_TYPE_ITEM_FIELD, NULL, 0);
				substitute_simple_macros(NULL, NULL, NULL, &items[i], NULL,
						&params, MACRO_TYPE_ITEM_FIELD, NULL, 0);

				items[i].username = username;
				items[i].password = password;
				items[i].params = params;
				break;
		}

		/* Skip unreachable hosts but do not break the loop. */
		switch (items[i].type)
		{
			case ITEM_TYPE_ZABBIX:
				if (SUCCEED == uint64_array_exists(ids, ids_num, items[i].host.hostid))
				{
					DCrequeue_unreachable_item(items[i].itemid);
					zabbix_log(LOG_LEVEL_DEBUG, "Zabbix Host " ZBX_FS_UI64 " is unreachable. Skipping [%s]",
							items[i].host.hostid, items[i].key_orig);
					continue;
				}
				break;
			case ITEM_TYPE_SNMPv1:
			case ITEM_TYPE_SNMPv2c:
			case ITEM_TYPE_SNMPv3:
				if (SUCCEED == uint64_array_exists(snmpids, snmpids_num, items[i].host.hostid))
				{
					DCrequeue_unreachable_item(items[i].itemid);
					zabbix_log(LOG_LEVEL_DEBUG, "SNMP Host " ZBX_FS_UI64 " is unreachable. Skipping [%s]",
							items[i].host.hostid, items[i].key_orig);
					continue;
				}
				break;
			case ITEM_TYPE_IPMI:
				if (SUCCEED == uint64_array_exists(ipmiids, ipmiids_num, items[i].host.hostid))
				{
					DCrequeue_unreachable_item(items[i].itemid);
					zabbix_log(LOG_LEVEL_DEBUG, "IPMI Host " ZBX_FS_UI64 " is unreachable. Skipping [%s]",
							items[i].host.hostid, items[i].key_orig);
					continue;
				}
				break;
			default:
				/* nothing to do */;
		}

		init_result(&agent);

		res = get_value(&items[i], &agent);
		now = time(NULL);

		if (res == SUCCEED)
		{
			activate_host(&items[i], now);

			dc_add_history(items[i].itemid, items[i].value_type, &agent, now,
					ITEM_STATUS_ACTIVE, NULL, 0, NULL, 0, 0, 0, 0);

			DCrequeue_reachable_item(items[i].itemid, ITEM_STATUS_ACTIVE, now);
		}
		else if (res == NOTSUPPORTED || res == AGENT_ERROR)
		{
			activate_host(&items[i], now);

			dc_add_history(items[i].itemid, items[i].value_type, NULL, now,
					ITEM_STATUS_NOTSUPPORTED, agent.msg, 0, NULL, 0, 0, 0, 0);

			DCrequeue_reachable_item(items[i].itemid, ITEM_STATUS_NOTSUPPORTED, now);
		}
		else if (res == NETWORK_ERROR)
		{
			deactivate_host(&items[i], now, agent.msg);

			switch (items[i].type)
			{
				case ITEM_TYPE_ZABBIX:
					uint64_array_add(&ids, &ids_alloc, &ids_num, items[i].host.hostid, 1);
					break;
				case ITEM_TYPE_SNMPv1:
				case ITEM_TYPE_SNMPv2c:
				case ITEM_TYPE_SNMPv3:
					uint64_array_add(&snmpids, &snmpids_alloc, &snmpids_num, items[i].host.hostid, 1);
					break;
				case ITEM_TYPE_IPMI:
					uint64_array_add(&ipmiids, &ipmiids_alloc, &ipmiids_num, items[i].host.hostid, 1);
					break;
				default:
					/* nothing to do */;
			}

			DCrequeue_unreachable_item(items[i].itemid);
		}
		else
		{
			zbx_error("unknown response code returned: %d", res);
			assert(0);
		}

		free_result(&agent);
	}

	zbx_free(key);
	zbx_free(ipmi_ip);
	zbx_free(params);
	zbx_free(username);
	zbx_free(publickey);
	zbx_free(privatekey);
	zbx_free(password);
	zbx_free(snmp_community);
	zbx_free(snmp_oid);
	zbx_free(snmpv3_securityname);
	zbx_free(snmpv3_authpassphrase);
	zbx_free(snmpv3_privpassphrase);

	zbx_free(ids);
	zbx_free(snmpids);
	zbx_free(ipmiids);

	zabbix_log(LOG_LEVEL_DEBUG, "End of %s()", __function_name);

	return num;
}