/****************************************************************************** * * * 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); }
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); }
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); }
/****************************************************************************** * * * Function: evaluate_aggregate * * * * Parameters: item - [IN] aggregated item * * grp_func - [IN] one of ZBX_GRP_FUNC_* * * groups - [IN] list of comma-separated host groups * * itemkey - [IN] item key to aggregate * * item_func - [IN] one of ZBX_VALUE_FUNC_* * * param - [IN] item_func parameter (optional) * * * * Return value: SUCCEED - aggregate item evaluated successfully * * FAIL - otherwise * * * ******************************************************************************/ static int evaluate_aggregate(DC_ITEM *item, AGENT_RESULT *res, int grp_func, const char *groups, const char *itemkey, int item_func, const char *param) { const char *__function_name = "evaluate_aggregate"; zbx_vector_uint64_t itemids; history_value_t value, item_result; zbx_history_record_t group_value; int ret = FAIL, now, *errcodes = NULL, i, count; DC_ITEM *items = NULL; zbx_vector_history_record_t values, group_values; unsigned int seconds; zabbix_log(LOG_LEVEL_DEBUG, "In %s() grp_func:%d groups:'%s' itemkey:'%s' item_func:%d param:'%s'", __function_name, grp_func, groups, itemkey, item_func, ZBX_NULL2STR(param)); now = time(NULL); zbx_vector_uint64_create(&itemids); aggregate_get_items(&itemids, groups, itemkey); if (0 == itemids.values_num) { SET_MSG_RESULT(res, zbx_dsprintf(NULL, "No items for key \"%s\" in group(s) \"%s\".", itemkey, groups)); goto clean1; } memset(&value, 0, sizeof(value)); zbx_history_record_vector_create(&group_values); items = zbx_malloc(items, sizeof(DC_ITEM) * itemids.values_num); errcodes = zbx_malloc(errcodes, sizeof(int) * itemids.values_num); DCconfig_get_items_by_itemids(items, itemids.values, errcodes, itemids.values_num); if (ZBX_VALUE_FUNC_LAST == item_func) { count = 1; seconds = 0; } else { if (FAIL == is_uint_suffix(param, &seconds)) { SET_MSG_RESULT(res, zbx_strdup(NULL, "Invalid fourth parameter.")); goto clean2; } count = 0; } for (i = 0; i < itemids.values_num; i++) { if (SUCCEED != errcodes[i]) continue; if (ITEM_STATUS_ACTIVE != items[i].status) continue; if (HOST_STATUS_MONITORED != items[i].host.status) continue; if (ITEM_VALUE_TYPE_FLOAT != items[i].value_type && ITEM_VALUE_TYPE_UINT64 != items[i].value_type) continue; zbx_history_record_vector_create(&values); if (SUCCEED == zbx_vc_get_value_range(items[i].itemid, items[i].value_type, &values, seconds, count, now) && 0 < values.values_num) { evaluate_history_func(&values, items[i].value_type, item_func, &item_result); if (item->value_type == items[i].value_type) group_value.value = item_result; else { if (ITEM_VALUE_TYPE_UINT64 == item->value_type) group_value.value.ui64 = (zbx_uint64_t)item_result.dbl; else group_value.value.dbl = (double)item_result.ui64; } zbx_vector_history_record_append_ptr(&group_values, &group_value); } zbx_history_record_vector_destroy(&values, items[i].value_type); } if (0 == group_values.values_num) { SET_MSG_RESULT(res, zbx_dsprintf(NULL, "No values for key \"%s\" in group(s) \"%s\"", itemkey, groups)); goto clean2; } evaluate_history_func(&group_values, item->value_type, grp_func, &value); if (ITEM_VALUE_TYPE_FLOAT == item->value_type) SET_DBL_RESULT(res, value.dbl); else SET_UI64_RESULT(res, value.ui64); ret = SUCCEED; clean2: DCconfig_clean_items(items, errcodes, itemids.values_num); zbx_free(errcodes); zbx_free(items); zbx_history_record_vector_destroy(&group_values, item->value_type); clean1: zbx_vector_uint64_destroy(&itemids); zabbix_log(LOG_LEVEL_DEBUG, "End of %s():%s", __function_name, zbx_result_string(ret)); return ret; }
/****************************************************************************** * * * Function: send_list_of_active_checks_json * * * * Purpose: send list of active checks to the host * * * * Parameters: sock - open socket of server-agent connection * * json - request buffer * * * * Return value: SUCCEED - list of active checks sent successfully * * FAIL - an error occurred * * * * Author: Alexander Vladishev * * * * Comments: * * * ******************************************************************************/ int send_list_of_active_checks_json(zbx_socket_t *sock, struct zbx_json_parse *jp) { const char *__function_name = "send_list_of_active_checks_json"; char host[HOST_HOST_LEN_MAX], tmp[MAX_STRING_LEN], ip[INTERFACE_IP_LEN_MAX], error[MAX_STRING_LEN], *host_metadata = NULL; struct zbx_json json; int ret = FAIL, i; zbx_uint64_t hostid; size_t host_metadata_alloc = 1; /* for at least NUL-termination char */ unsigned short port; zbx_vector_uint64_t itemids; zbx_vector_ptr_t regexps; zbx_vector_str_t names; zabbix_log(LOG_LEVEL_DEBUG, "In %s()", __function_name); zbx_vector_ptr_create(®exps); zbx_vector_str_create(&names); if (FAIL == zbx_json_value_by_name(jp, ZBX_PROTO_TAG_HOST, host, sizeof(host))) { zbx_snprintf(error, MAX_STRING_LEN, "%s", zbx_json_strerror()); goto error; } host_metadata = zbx_malloc(host_metadata, host_metadata_alloc); if (FAIL == zbx_json_value_by_name_dyn(jp, ZBX_PROTO_TAG_HOST_METADATA, &host_metadata, &host_metadata_alloc)) { *host_metadata = '\0'; } if (FAIL == zbx_json_value_by_name(jp, ZBX_PROTO_TAG_IP, ip, sizeof(ip))) strscpy(ip, sock->peer); if (FAIL == zbx_json_value_by_name(jp, ZBX_PROTO_TAG_PORT, tmp, sizeof(tmp))) *tmp = '\0'; if (FAIL == is_ushort(tmp, &port)) port = ZBX_DEFAULT_AGENT_PORT; if (FAIL == get_hostid_by_host(sock, host, ip, port, host_metadata, &hostid, error)) goto error; zbx_vector_uint64_create(&itemids); get_list_of_active_checks(hostid, &itemids); zbx_json_init(&json, ZBX_JSON_STAT_BUF_LEN); zbx_json_addstring(&json, ZBX_PROTO_TAG_RESPONSE, ZBX_PROTO_VALUE_SUCCESS, ZBX_JSON_TYPE_STRING); zbx_json_addarray(&json, ZBX_PROTO_TAG_DATA); if (0 != itemids.values_num) { DC_ITEM *dc_items; int *errcodes, now; zbx_config_t cfg; dc_items = zbx_malloc(NULL, sizeof(DC_ITEM) * itemids.values_num); errcodes = zbx_malloc(NULL, sizeof(int) * itemids.values_num); DCconfig_get_items_by_itemids(dc_items, itemids.values, errcodes, itemids.values_num); zbx_config_get(&cfg, ZBX_CONFIG_FLAGS_REFRESH_UNSUPPORTED); now = time(NULL); for (i = 0; i < itemids.values_num; i++) { if (SUCCEED != errcodes[i]) { zabbix_log(LOG_LEVEL_DEBUG, "%s() Item [" ZBX_FS_UI64 "] was not found in the" " server cache. Not sending now.", __function_name, itemids.values[i]); continue; } if (ITEM_STATUS_ACTIVE != dc_items[i].status) continue; if (HOST_STATUS_MONITORED != dc_items[i].host.status) continue; if (ITEM_STATE_NOTSUPPORTED == dc_items[i].state) { if (0 == cfg.refresh_unsupported) continue; if (dc_items[i].lastclock + cfg.refresh_unsupported > now) continue; } dc_items[i].key = zbx_strdup(dc_items[i].key, dc_items[i].key_orig); substitute_key_macros(&dc_items[i].key, NULL, &dc_items[i], NULL, MACRO_TYPE_ITEM_KEY, NULL, 0); zbx_json_addobject(&json, NULL); zbx_json_addstring(&json, ZBX_PROTO_TAG_KEY, dc_items[i].key, ZBX_JSON_TYPE_STRING); if (0 != strcmp(dc_items[i].key, dc_items[i].key_orig)) { zbx_json_addstring(&json, ZBX_PROTO_TAG_KEY_ORIG, dc_items[i].key_orig, ZBX_JSON_TYPE_STRING); } zbx_json_adduint64(&json, ZBX_PROTO_TAG_DELAY, dc_items[i].delay); /* The agent expects ALWAYS to have lastlogsize and mtime tags. */ /* Removing those would cause older agents to fail. */ zbx_json_adduint64(&json, ZBX_PROTO_TAG_LASTLOGSIZE, dc_items[i].lastlogsize); zbx_json_adduint64(&json, ZBX_PROTO_TAG_MTIME, dc_items[i].mtime); zbx_json_close(&json); zbx_itemkey_extract_global_regexps(dc_items[i].key, &names); zbx_free(dc_items[i].key); } zbx_config_clean(&cfg); DCconfig_clean_items(dc_items, errcodes, itemids.values_num); zbx_free(errcodes); zbx_free(dc_items); } zbx_vector_uint64_destroy(&itemids); zbx_json_close(&json); DCget_expressions_by_names(®exps, (const char * const *)names.values, names.values_num); if (0 < regexps.values_num) { char buffer[32]; zbx_json_addarray(&json, ZBX_PROTO_TAG_REGEXP); for (i = 0; i < regexps.values_num; i++) { zbx_expression_t *regexp = regexps.values[i]; zbx_json_addobject(&json, NULL); zbx_json_addstring(&json, "name", regexp->name, ZBX_JSON_TYPE_STRING); zbx_json_addstring(&json, "expression", regexp->expression, ZBX_JSON_TYPE_STRING); zbx_snprintf(buffer, sizeof(buffer), "%d", regexp->expression_type); zbx_json_addstring(&json, "expression_type", buffer, ZBX_JSON_TYPE_INT); zbx_snprintf(buffer, sizeof(buffer), "%c", regexp->exp_delimiter); zbx_json_addstring(&json, "exp_delimiter", buffer, ZBX_JSON_TYPE_STRING); zbx_snprintf(buffer, sizeof(buffer), "%d", regexp->case_sensitive); zbx_json_addstring(&json, "case_sensitive", buffer, ZBX_JSON_TYPE_INT); zbx_json_close(&json); } zbx_json_close(&json); } zabbix_log(LOG_LEVEL_DEBUG, "%s() sending [%s]", __function_name, json.buffer); zbx_alarm_on(CONFIG_TIMEOUT); if (SUCCEED != zbx_tcp_send(sock, json.buffer)) strscpy(error, zbx_socket_strerror()); else ret = SUCCEED; zbx_alarm_off(); zbx_json_free(&json); goto out; error: zabbix_log(LOG_LEVEL_WARNING, "cannot send list of active checks to \"%s\": %s", sock->peer, error); zbx_json_init(&json, ZBX_JSON_STAT_BUF_LEN); zbx_json_addstring(&json, ZBX_PROTO_TAG_RESPONSE, ZBX_PROTO_VALUE_FAILED, ZBX_JSON_TYPE_STRING); zbx_json_addstring(&json, ZBX_PROTO_TAG_INFO, error, ZBX_JSON_TYPE_STRING); zabbix_log(LOG_LEVEL_DEBUG, "%s() sending [%s]", __function_name, json.buffer); ret = zbx_tcp_send(sock, json.buffer); zbx_json_free(&json); out: for (i = 0; i < names.values_num; i++) zbx_free(names.values[i]); zbx_vector_str_destroy(&names); zbx_regexp_clean_expressions(®exps); zbx_vector_ptr_destroy(®exps); zbx_free(host_metadata); zabbix_log(LOG_LEVEL_DEBUG, "End of %s():%s", __function_name, zbx_result_string(ret)); return ret; }
/****************************************************************************** * * * Function: send_list_of_active_checks * * * * Purpose: send list of active checks to the host (older version agent) * * * * Parameters: sock - open socket of server-agent connection * * request - request buffer * * * * Return value: SUCCEED - list of active checks sent successfully * * FAIL - an error occurred * * * * Comments: format of the request: ZBX_GET_ACTIVE_CHECKS\n<host name>\n * * format of the list: key:delay:last_log_size * * * ******************************************************************************/ int send_list_of_active_checks(zbx_socket_t *sock, char *request) { const char *__function_name = "send_list_of_active_checks"; char *host = NULL, *p, *buffer = NULL, error[MAX_STRING_LEN]; size_t buffer_alloc = 8 * ZBX_KIBIBYTE, buffer_offset = 0; int ret = FAIL, i; zbx_uint64_t hostid; zbx_vector_uint64_t itemids; zabbix_log(LOG_LEVEL_DEBUG, "In %s()", __function_name); if (NULL != (host = strchr(request, '\n'))) { host++; if (NULL != (p = strchr(host, '\n'))) *p = '\0'; } else { zbx_snprintf(error, sizeof(error), "host is null"); goto out; } /* no host metadata in older versions of agent */ if (FAIL == get_hostid_by_host(sock, host, sock->peer, ZBX_DEFAULT_AGENT_PORT, "", &hostid, error)) goto out; zbx_vector_uint64_create(&itemids); get_list_of_active_checks(hostid, &itemids); buffer = zbx_malloc(buffer, buffer_alloc); if (0 != itemids.values_num) { DC_ITEM *dc_items; int *errcodes, now; zbx_config_t cfg; dc_items = zbx_malloc(NULL, sizeof(DC_ITEM) * itemids.values_num); errcodes = zbx_malloc(NULL, sizeof(int) * itemids.values_num); DCconfig_get_items_by_itemids(dc_items, itemids.values, errcodes, itemids.values_num); zbx_config_get(&cfg, ZBX_CONFIG_FLAGS_REFRESH_UNSUPPORTED); now = time(NULL); for (i = 0; i < itemids.values_num; i++) { if (SUCCEED != errcodes[i]) { zabbix_log(LOG_LEVEL_DEBUG, "%s() Item [" ZBX_FS_UI64 "] was not found in the" " server cache. Not sending now.", __function_name, itemids.values[i]); continue; } if (ITEM_STATUS_ACTIVE != dc_items[i].status) continue; if (HOST_STATUS_MONITORED != dc_items[i].host.status) continue; if (ITEM_STATE_NOTSUPPORTED == dc_items[i].state) { if (0 == cfg.refresh_unsupported) continue; if (dc_items[i].lastclock + cfg.refresh_unsupported > now) continue; } zbx_snprintf_alloc(&buffer, &buffer_alloc, &buffer_offset, "%s:%d:" ZBX_FS_UI64 "\n", dc_items[i].key_orig, dc_items[i].delay, dc_items[i].lastlogsize); } zbx_config_clean(&cfg); DCconfig_clean_items(dc_items, errcodes, itemids.values_num); zbx_free(errcodes); zbx_free(dc_items); } zbx_vector_uint64_destroy(&itemids); zbx_strcpy_alloc(&buffer, &buffer_alloc, &buffer_offset, "ZBX_EOF\n"); zabbix_log(LOG_LEVEL_DEBUG, "%s() sending [%s]", __function_name, buffer); zbx_alarm_on(CONFIG_TIMEOUT); if (SUCCEED != zbx_tcp_send_raw(sock, buffer)) zbx_strlcpy(error, zbx_socket_strerror(), MAX_STRING_LEN); else ret = SUCCEED; zbx_alarm_off(); zbx_free(buffer); out: if (FAIL == ret) zabbix_log(LOG_LEVEL_WARNING, "cannot send list of active checks to \"%s\": %s", sock->peer, error); zabbix_log(LOG_LEVEL_DEBUG, "End of %s():%s", __function_name, zbx_result_string(ret)); return ret; }
/****************************************************************************** * * * Function: lld_filter_load * * * * Purpose: loads lld filter data * * * * Parameters: filter - [IN] the lld filter * * lld_ruleid - [IN] the lld rule id * * error - [OUT] the error description * * * ******************************************************************************/ static int lld_filter_load(lld_filter_t *filter, zbx_uint64_t lld_ruleid, char **error) { DB_RESULT result; DB_ROW row; lld_condition_t *condition; DC_ITEM item; int errcode, ret = SUCCEED; DCconfig_get_items_by_itemids(&item, &lld_ruleid, &errcode, 1); if (SUCCEED != errcode) { *error = zbx_dsprintf(*error, "Invalid discovery rule ID [" ZBX_FS_UI64 "].", lld_ruleid); ret = FAIL; goto out; } result = DBselect( "select item_conditionid,macro,value" " from item_condition" " where itemid=" ZBX_FS_UI64, lld_ruleid); while (NULL != (row = DBfetch(result))) { condition = zbx_malloc(NULL, sizeof(lld_condition_t)); ZBX_STR2UINT64(condition->id, row[0]); condition->macro = zbx_strdup(NULL, row[1]); condition->regexp = zbx_strdup(NULL, row[2]); zbx_vector_ptr_create(&condition->regexps); zbx_vector_ptr_append(&filter->conditions, condition); if ('@' == *condition->regexp) { DCget_expressions_by_name(&condition->regexps, condition->regexp + 1); if (0 == condition->regexps.values_num) { *error = zbx_dsprintf(*error, "Global regular expression \"%s\" does not exist.", condition->regexp + 1); ret = FAIL; break; } } else { substitute_simple_macros(NULL, NULL, NULL, NULL, NULL, NULL, &item, NULL, &condition->regexp, MACRO_TYPE_LLD_FILTER, NULL, 0); } } DBfree_result(result); if (SUCCEED != ret) lld_conditions_free(&filter->conditions); else if (CONDITION_EVAL_TYPE_AND_OR == filter->evaltype) zbx_vector_ptr_sort(&filter->conditions, lld_condition_compare_by_macro); out: DCconfig_clean_items(&item, &errcode, 1); return ret; }