static int	calcitem_evaluate_expression(DC_ITEM *dc_item, expression_t *exp, char *error, int max_error_len)
{
	const char	*__function_name = "calcitem_evaluate_expression";
	function_t	*f = NULL;
	char		*buf, replace[16], *errstr = NULL;
	int		i, ret = SUCCEED;
	time_t		now;
	zbx_host_key_t	*keys = NULL;
	DC_ITEM		*items = NULL;
	int		*errcodes = NULL;

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

	if (0 == exp->functions_num)
		return ret;

	keys = zbx_malloc(keys, sizeof(zbx_host_key_t) * exp->functions_num);
	items = zbx_malloc(items, sizeof(DC_ITEM) * exp->functions_num);
	errcodes = zbx_malloc(errcodes, sizeof(int) * exp->functions_num);

	for (i = 0; i < exp->functions_num; i++)
	{
		f = &exp->functions[i];

		buf = get_param_dyn(f->params, 1);	/* for first parameter result is not NULL */

		if (SUCCEED != parse_host_key(buf, &f->host, &f->key))
		{
			zbx_snprintf(error, max_error_len,
					"Invalid first parameter in function [%s(%s)].",
					f->func, f->params);
			ret = NOTSUPPORTED;
		}

		zbx_free(buf);

		if (SUCCEED != ret)
			goto out;

		if (NULL == f->host)
			f->host = strdup(dc_item->host.host);

		keys[i].host = f->host;
		keys[i].key = f->key;

		remove_param(f->params, 1);

		zabbix_log(LOG_LEVEL_DEBUG, "%s() function:'%s:%s.%s(%s)'",
				__function_name, f->host, f->key, f->func, f->params);
	}

	DCconfig_get_items_by_keys(items, keys, errcodes, exp->functions_num);

	now = time(NULL);

	for (i = 0; i < exp->functions_num; i++)
	{
		f = &exp->functions[i];

		if (SUCCEED != errcodes[i])
		{
			zbx_snprintf(error, max_error_len,
					"Cannot evaluate function \"%s(%s)\":"
					" item \"%s:%s\" does not exist.",
					f->func, f->params, f->host, f->key);
			ret = NOTSUPPORTED;
			break;
		}

		if (ITEM_STATUS_ACTIVE != items[i].status)
		{
			zbx_snprintf(error, max_error_len,
					"Cannot evaluate function \"%s(%s)\":"
					" item \"%s:%s\" is disabled.",
					f->func, f->params, f->host, f->key);
			ret = NOTSUPPORTED;
			break;
		}

		if (HOST_STATUS_MONITORED != items[i].host.status)
		{
			zbx_snprintf(error, max_error_len,
					"Cannot evaluate function \"%s(%s)\":"
					" item \"%s:%s\" belongs to a disabled host.",
					f->func, f->params, f->host, f->key);
			ret = NOTSUPPORTED;
			break;
		}

		if (ITEM_STATE_NOTSUPPORTED == items[i].state)
		{
			zbx_snprintf(error, max_error_len,
					"Cannot evaluate function \"%s(%s)\": item \"%s:%s\" not supported.",
					f->func, f->params, f->host, f->key);
			ret = NOTSUPPORTED;
			break;
		}

		f->value = zbx_malloc(f->value, MAX_BUFFER_LEN);

		if (SUCCEED != evaluate_function(f->value, &items[i], f->func, f->params, now, &errstr))
		{
			if (NULL != errstr)
			{
				zbx_snprintf(error, max_error_len, "Cannot evaluate function \"%s(%s)\": %s.",
						f->func, f->params, errstr);
				zbx_free(errstr);
			}
			else
			{
				zbx_snprintf(error, max_error_len, "Cannot evaluate function \"%s(%s)\".",
						f->func, f->params);
			}

			ret = NOTSUPPORTED;
			break;
		}

		if (SUCCEED != is_double_suffix(f->value) || '-' == *f->value)
		{
			char	*wrapped;

			wrapped = zbx_dsprintf(NULL, "(%s)", f->value);

			zbx_free(f->value);
			f->value = wrapped;
		}
		else
			f->value = zbx_realloc(f->value, strlen(f->value) + 1);

		zbx_snprintf(replace, sizeof(replace), "{%d}", f->functionid);
		buf = string_replace(exp->exp, replace, f->value);
		zbx_free(exp->exp);
		exp->exp = buf;
	}

	DCconfig_clean_items(items, errcodes, exp->functions_num);
out:
	zbx_free(errcodes);
	zbx_free(items);
	zbx_free(keys);

	return ret;
}
Example #2
0
static int	calcitem_evaluate_expression(DC_ITEM *dc_item, expression_t *exp,
		char *error, int max_error_len)
{
	const char	*__function_name = "calcitem_evaluate_expression";
	function_t	*f = NULL;
	char		*sql = NULL, *host_esc, *key_esc,
			*buf, replace[16];
	int		sql_alloc = 1024, sql_offset = 0,
			i, ret = SUCCEED;
	time_t		now;
	DB_RESULT	db_result;
	DB_ROW		db_row;
	DB_ITEM		item;

	zabbix_log(LOG_LEVEL_DEBUG, "In %s() expression:'%s'", __function_name, exp->exp);

	if (0 == exp->functions_num)
		return ret;

	for (i = 0; i < exp->functions_num; i++)
	{
		f = &exp->functions[i];
		
		buf = get_param_dyn(f->params, 1);	/* for first parameter result is not NULL */

		if (SUCCEED != parse_host_key(buf, &f->host, &f->key))
		{
			zbx_snprintf(error, max_error_len,
					"Invalid first parameter in function [%s(%s)]",
					f->func, f->params);
			ret = NOTSUPPORTED;
		}

		zbx_free(buf);

		if (SUCCEED != ret)
			break;

		if (NULL == f->host)
			f->host = strdup(dc_item->host.host);

		remove_param(f->params, 1);

		zabbix_log(LOG_LEVEL_DEBUG, "%s() function:'%s:%s.%s(%s)'",
				__function_name, f->host, f->key, f->func, f->params);
	}

	if (SUCCEED != ret)
		return ret;

	now = time(NULL);
	sql = zbx_malloc(sql, sql_alloc);

	zbx_snprintf_alloc(&sql, &sql_alloc, &sql_offset, 512,
			"select %s"
			" where h.hostid=i.hostid"
				" and h.status=%d"
				" and i.status=%d"
				" and (",
			ZBX_SQL_ITEM_SELECT,
			HOST_STATUS_MONITORED,
			ITEM_STATUS_ACTIVE);

	for (i = 0; i < exp->functions_num; i++)
	{
		f = &exp->functions[i];

		if (i != 0)
			zbx_snprintf_alloc(&sql, &sql_alloc, &sql_offset, 8, " or ");

		host_esc = DBdyn_escape_string(f->host);
		key_esc = DBdyn_escape_string(f->key);

		zbx_snprintf_alloc(&sql, &sql_alloc, &sql_offset,
				32 + strlen(host_esc) + strlen(key_esc),
				"(h.host='%s' and i.key_='%s')",
				host_esc, key_esc);

		zbx_free(key_esc);
		zbx_free(host_esc);
	}

	zbx_snprintf_alloc(&sql, &sql_alloc, &sql_offset, 130,
			")" DB_NODE,
			DBnode_local("h.hostid"));

	db_result = DBselect("%s", sql);

	zbx_free(sql);

	while (NULL != (db_row = DBfetch(db_result)))
	{
		DBget_item_from_db(&item, db_row);

		for (i = 0; i < exp->functions_num; i++)
		{
			f = &exp->functions[i];

			if (0 != strcmp(f->key, item.key_orig))
				continue;
					
			if (0 != strcmp(f->host, item.host_name))
				continue;

			f->found = 1;
			f->value = zbx_malloc(f->value, MAX_BUFFER_LEN);

			if (SUCCEED != evaluate_function(f->value, &item, f->func, f->params, now))
			{
				zbx_snprintf(error, max_error_len, "Cannot evaluate function [%s(%s)]",
						f->func, f->params);

				ret = NOTSUPPORTED;
				break;
			}
			else
				f->value = zbx_realloc(f->value, strlen(f->value) + 1);
		}

		if (SUCCEED != ret)
			break;
	}
	DBfree_result(db_result);

	if (SUCCEED != ret)
		return ret;

	for (i = 0; i < exp->functions_num; i ++)
	{
		f = &exp->functions[i];

		if (0 == f->found)
		{
			zbx_snprintf(error, max_error_len,
				"Cannot evaluate function [%s(%s)]"
					": item [%s:%s] not found",
					f->func, f->params, f->host, f->key);
			ret = NOTSUPPORTED;
			break;
		}

		zbx_snprintf(replace, sizeof(replace), "{%d}", f->functionid);
		buf = string_replace(exp->exp, replace, f->value);
		zbx_free(exp->exp);
		exp->exp = buf;
	}

	return ret;
}