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; }
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; }