/****************************************************************************** * * * Function: check_response * * * * Purpose: Check whether JSON response is SUCCEED * * * * Parameters: JSON response from Zabbix trapper * * * * Return value: SUCCEED - processed successfully * * FAIL - an error occurred * * * * Author: Alexei Vladishev * * * * Comments: zabbix_sender has almost the same function! * * * ******************************************************************************/ static int check_response(char *response) { const char *__function_name = "check_response"; struct zbx_json_parse jp; char value[MAX_STRING_LEN]; char info[MAX_STRING_LEN]; int ret = SUCCEED; zabbix_log(LOG_LEVEL_DEBUG, "In %s() response:'%s'", __function_name, response); ret = zbx_json_open(response, &jp); if (SUCCEED == ret) ret = zbx_json_value_by_name(&jp, ZBX_PROTO_TAG_RESPONSE, value, sizeof(value)); if (SUCCEED == ret && 0 != strcmp(value, ZBX_PROTO_VALUE_SUCCESS)) ret = FAIL; if (SUCCEED == ret && SUCCEED == zbx_json_value_by_name(&jp, ZBX_PROTO_TAG_INFO, info, sizeof(info))) zabbix_log(LOG_LEVEL_DEBUG, "info from server: '%s'", info); zabbix_log(LOG_LEVEL_DEBUG, "End of %s():%s", __function_name, zbx_result_string(ret)); return ret; }
/****************************************************************************** * * * Function: get_proxy_id * * * * Purpose: * * * * Parameters: * * * * Return value: SUCCEED - processed successfully * * FAIL - an error occurred * * * * Author: Aleksander Vladishev * * * * Comments: * * * ******************************************************************************/ int get_proxy_id(struct zbx_json_parse *jp, zbx_uint64_t *hostid) { DB_RESULT result; DB_ROW row; char host[HOST_HOST_LEN_MAX], host_esc[MAX_STRING_LEN]; int res = FAIL; if (SUCCEED == zbx_json_value_by_name(jp, ZBX_PROTO_TAG_HOST, host, sizeof(host))) { DBescape_string(host, host_esc, sizeof(host_esc)); result = DBselect("select hostid from hosts where host='%s'" " and status in (%d)" DB_NODE, host_esc, HOST_STATUS_PROXY, DBnode_local("hostid")); if (NULL != (row = DBfetch(result)) && FAIL == DBis_null(row[0])) { *hostid = zbx_atoui64(row[0]); res = SUCCEED; } else zabbix_log(LOG_LEVEL_WARNING, "Unknown proxy \"%s\"", host); DBfree_result(result); } else { zabbix_log(LOG_LEVEL_WARNING, "Incorrect data. %s", zbx_json_strerror()); zabbix_syslog("Incorrect data. %s", zbx_json_strerror()); } return res; }
/****************************************************************************** * * * Function: put_data_to_server * * * * Purpose: send data from server * * * * Parameters: * * * * Return value: SUCCESS - processed succesfully * * FAIL - an error occured * * * * Author: Alksander Vladishev * * * * Comments: * * * ******************************************************************************/ int put_data_to_server(zbx_sock_t *sock, struct zbx_json *j) { struct zbx_json_parse jp; int ret = FAIL; char *answer, value[MAX_STRING_LEN]; zabbix_log(LOG_LEVEL_DEBUG, "In put_data_to_server() [datalen:%zd]", j->buffer_size); if (FAIL == send_data_to_server(sock, j->buffer)) goto exit; if (FAIL == recv_data_from_server(sock, &answer)) goto exit; if (FAIL == zbx_json_open(answer, &jp)) goto exit; if (FAIL == zbx_json_value_by_name(&jp, ZBX_PROTO_TAG_RESPONSE, value, sizeof(value))) goto exit; if (0 != strcmp(value, ZBX_PROTO_VALUE_SUCCESS)) goto exit; ret = SUCCEED; exit: zabbix_log(LOG_LEVEL_DEBUG, "End of put_data_to_server():%s", zbx_result_string(ret)); return ret; }
/****************************************************************************** * * * Function: * * * * Purpose: * * * * Parameters: * * * * Return value: * * * * Comments: * * * ******************************************************************************/ static int process_jatrap(zbx_sock_t * sock, char *s) { int ret = SUCCEED; struct zbx_json_parse jp; char value[MAX_STRING_LEN]; char *message = NULL; static JOBARG_JOBNET_INFO ji; zbx_rtrim(s, " \r\n"); zabbix_log(LOG_LEVEL_DEBUG, "Jatrapper got [%s] len %zd", s, strlen(s)); /*JSON Format check */ if (SUCCEED != zbx_json_open(s, &jp)) { ja_log("JATRAPPER200037", 0, NULL, 0); message = zbx_dsprintf(message, "Received message error: [JSON format error]"); ret = FAIL; reply_jobresult_response(sock, ret, message); zbx_free(message); return ret; } /*[kind] check */ if (SUCCEED != zbx_json_value_by_name(&jp, JA_PROTO_TAG_KIND, value, sizeof(value))) { ja_log("JATRAPPER200036", 0, NULL, 0); message = zbx_dsprintf(message, "Received message error: [kind] not found"); ret = FAIL; reply_jobresult_response(sock, ret, message); zbx_free(message); return ret; } if (0 == strcmp(value, JA_PROTO_VALUE_JOBRESULT)) { /*from Job agent */ } else if (0 == strcmp(value, JA_PROTO_VALUE_JOBNETRUN)) { /*from external I/F */ message = evaluate_jobnetrun(sock, &jp, &ret); reply_jobnetrun_response(sock, ret, message); } else if (0 == strcmp(value, JA_PROTO_VALUE_JOBNETSTATUSRQ)) { /*from jobnet-status request */ init_jobnetinfo(&ji); message = evaluate_jobnetstatusrq(sock, &jp, &ret, &ji); reply_jobnetstatusrq_response(sock, ret, &ji, message); } else { ja_log("JATRAPPER200035", 0, NULL, 0); message = zbx_dsprintf(message, "Received message error: [kind] is not correct."); ret = FAIL; reply_jobresult_response(sock, ret, message); } zbx_free(message); return ret; }
/****************************************************************************** * * * Function: zbx_recv_response * * * * Purpose: read a response message (in JSON format) from socket, optionally * * extract "info" value. * * * * Parameters: sock - [IN] socket descriptor * * timeout - [IN] timeout for this operation * * error - [OUT] pointer to error message * * * * Return value: SUCCEED - "response":"success" successfully retrieved * * FAIL - otherwise * * Comments: * * Allocates memory. * * * * If an error occurs, the function allocates dynamic memory for an error * * message and writes its address into location pointed to by "error" * * parameter. * * * * When the "info" value is present in the response message then function * * copies the "info" value into the "error" buffer as additional * * information * * * * IMPORTANT: it is a responsibility of the caller to release the * * "error" memory ! * * * ******************************************************************************/ int zbx_recv_response(zbx_socket_t *sock, int timeout, char **error) { const char *__function_name = "zbx_recv_response"; struct zbx_json_parse jp; char value[16]; int ret = FAIL; zabbix_log(LOG_LEVEL_DEBUG, "In %s()", __function_name); if (SUCCEED != zbx_tcp_recv_to(sock, timeout)) { /* since we have successfully sent data earlier, we assume the other */ /* side is just too busy processing our data if there is no response */ *error = zbx_strdup(*error, zbx_socket_strerror()); goto out; } zabbix_log(LOG_LEVEL_DEBUG, "%s() '%s'", __function_name, sock->buffer); /* deal with empty string here because zbx_json_open() does not produce an error message in this case */ if ('\0' == *sock->buffer) { *error = zbx_strdup(*error, "empty string received"); goto out; } if (SUCCEED != zbx_json_open(sock->buffer, &jp)) { *error = zbx_strdup(*error, zbx_json_strerror()); goto out; } if (SUCCEED != zbx_json_value_by_name(&jp, ZBX_PROTO_TAG_RESPONSE, value, sizeof(value))) { *error = zbx_strdup(*error, "no \"" ZBX_PROTO_TAG_RESPONSE "\" tag"); goto out; } if (0 != strcmp(value, ZBX_PROTO_VALUE_SUCCESS)) { char *info = NULL; size_t info_alloc = 0; if (SUCCEED == zbx_json_value_by_name_dyn(&jp, ZBX_PROTO_TAG_INFO, &info, &info_alloc)) *error = zbx_strdup(*error, info); else *error = zbx_dsprintf(*error, "negative response \"%s\"", value); zbx_free(info); goto out; } ret = SUCCEED; out: zabbix_log(LOG_LEVEL_DEBUG, "End of %s():%s", __function_name, zbx_result_string(ret)); return ret; }
/****************************************************************************** * * * Function: check_response * * * * Purpose: Check whether JSON response is SUCCEED * * * * Parameters: result SUCCEED or FAIL * * * * Return value: SUCCEED - processed successfully * * FAIL - an error occurred * * * * Author: Alexei Vladishev * * * * Comments: active agent has almost the same function! * * * ******************************************************************************/ static int check_response(char *response) { struct zbx_json_parse jp; char value[MAX_STRING_LEN]; char info[MAX_STRING_LEN]; int ret; ret = zbx_json_open(response, &jp); if (SUCCEED == ret) ret = zbx_json_value_by_name(&jp, ZBX_PROTO_TAG_RESPONSE, value, sizeof(value)); if (SUCCEED == ret && 0 != strcmp(value, ZBX_PROTO_VALUE_SUCCESS)) ret = FAIL; if (SUCCEED == ret && SUCCEED == zbx_json_value_by_name(&jp, ZBX_PROTO_TAG_INFO, info, sizeof(info))) printf("info from server: \"%s\"\n", info); return ret; }
/****************************************************************************** * * * Function: check_response * * * * Purpose: Check if json response is SUCCEED * * * * Parameters: result SUCCEED or FAIL * * * * Return value: SUCCEED - processed successfully * * FAIL - an error occured * * * * Author: Alexei Vladishev * * * * Comments: zabbix_sender has exactly the same function! * * * ******************************************************************************/ static int check_response(char *response) { struct zbx_json_parse jp; char value[MAX_STRING_LEN]; char info[MAX_STRING_LEN]; int ret = SUCCEED; zabbix_log( LOG_LEVEL_DEBUG, "In check_response(%s)", response); ret = zbx_json_open(response, &jp); if (SUCCEED == ret) { ret = zbx_json_value_by_name(&jp, ZBX_PROTO_TAG_RESPONSE,value, sizeof(value)); } if(SUCCEED == ret) { if(strcmp(value, ZBX_PROTO_VALUE_SUCCESS) != 0) { ret = FAIL; } } if (SUCCEED == ret) { if(SUCCEED == zbx_json_value_by_name(&jp, ZBX_PROTO_TAG_INFO, info, sizeof(info))) { zabbix_log(LOG_LEVEL_DEBUG, "Info from server: %s", info); } } return ret; }
static int process_trap(zbx_sock_t *sock, char *s, int max_len) { char *server,*key,*value_string, *data; char copy[MAX_STRING_LEN]; char host_dec[MAX_STRING_LEN],key_dec[MAX_STRING_LEN],value_dec[MAX_STRING_LEN]; char lastlogsize[MAX_STRING_LEN]; char timestamp[MAX_STRING_LEN]; char source[MAX_STRING_LEN]; char severity[MAX_STRING_LEN]; int sender_nodeid, nodeid; char *answer; int ret=SUCCEED, res; size_t datalen; struct zbx_json_parse jp; char value[MAX_STRING_LEN]; AGENT_VALUE av; zbx_rtrim(s, " \r\n\0"); datalen = strlen(s); zabbix_log( LOG_LEVEL_DEBUG, "Trapper got [%s] len %zd", s, datalen); if (0 == strncmp(s,"ZBX_GET_ACTIVE_CHECKS", 21)) /* Request for list of active checks */ { ret = send_list_of_active_checks(sock, s); /* Request for last ids */ } else if (strncmp(s,"ZBX_GET_HISTORY_LAST_ID", 23) == 0) { send_history_last_id(sock, s); return ret; } else if (strncmp(s,"ZBX_GET_TRENDS_LAST_ID", 22) == 0) { send_trends_last_id(sock, s); return ret; /* Process information sent by zabbix_sender */ } else { /* Command? */ if(strncmp(s,"Command",7) == 0) { node_process_command(sock, s); return ret; } /* Node data exchange? */ if(strncmp(s,"Data",4) == 0) { node_sync_lock(0); /* zabbix_log( LOG_LEVEL_WARNING, "Node data received [len:%d]", strlen(s)); */ res = node_sync(s, &sender_nodeid, &nodeid); if (FAIL == res) send_data_to_node(sender_nodeid, sock, "FAIL"); else { res = calculate_checksums(nodeid, NULL, 0); if (SUCCEED == res && NULL != (data = get_config_data(nodeid, ZBX_NODE_SLAVE))) { res = send_data_to_node(sender_nodeid, sock, data); zbx_free(data); if (SUCCEED == res) res = recv_data_from_node(sender_nodeid, sock, &answer); if (SUCCEED == res && 0 == strcmp(answer, "OK")) res = update_checksums(nodeid, ZBX_NODE_SLAVE, SUCCEED, NULL, 0, NULL); } } node_sync_unlock(0); return ret; } /* Slave node history ? */ if(strncmp(s,"History",7) == 0) { /* zabbix_log( LOG_LEVEL_WARNING, "Slave node history received [len:%d]", strlen(s)); */ if (node_history(s, datalen) == SUCCEED) { if (zbx_tcp_send_raw(sock,"OK") != SUCCEED) { zabbix_log( LOG_LEVEL_WARNING, "Error sending confirmation to node"); zabbix_syslog("Trapper: error sending confirmation to node"); } } return ret; } /* JSON protocol? */ else if (SUCCEED == zbx_json_open(s, &jp)) { if (SUCCEED == zbx_json_value_by_name(&jp, ZBX_PROTO_TAG_REQUEST, value, sizeof(value))) { if (0 == strcmp(value, ZBX_PROTO_VALUE_PROXY_CONFIG) && zbx_process == ZBX_PROCESS_SERVER) { send_proxyconfig(sock, &jp); } else if (0 == strcmp(value, ZBX_PROTO_VALUE_AGENT_DATA) || 0 == strcmp(value, ZBX_PROTO_VALUE_SENDER_DATA)) { ret = process_new_values(sock, &jp, 0); } else if (0 == strcmp(value, ZBX_PROTO_VALUE_HISTORY_DATA) && zbx_process == ZBX_PROCESS_SERVER) { ret = process_proxy_values(sock, &jp); } else if (0 == strcmp(value, ZBX_PROTO_VALUE_DISCOVERY_DATA) && zbx_process == ZBX_PROCESS_SERVER) { ret = process_discovery_data(sock, &jp); } else if (0 == strcmp(value, ZBX_PROTO_VALUE_PROXY_HEARTBEAT) && zbx_process == ZBX_PROCESS_SERVER) { ret = process_proxy_heartbeat(sock, &jp); } else if (0 == strcmp(value, ZBX_PROTO_VALUE_GET_ACTIVE_CHECKS)) { ret = send_list_of_active_checks_json(sock, &jp); } else { zabbix_log( LOG_LEVEL_WARNING, "Unknown request received [%s]", value); } } return ret; } /* New XML protocol? */ else if(s[0]=='<') { zabbix_log( LOG_LEVEL_DEBUG, "XML received [%s]", s); comms_parse_response(s,host_dec,key_dec,value_dec,lastlogsize,timestamp,source,severity,sizeof(host_dec)-1); server=host_dec; value_string=value_dec; key=key_dec; } else { strscpy(copy,s); server=(char *)strtok(s,":"); if(NULL == server) { return FAIL; } key=(char *)strtok(NULL,":"); if(NULL == key) { return FAIL; } value_string=strchr(copy,':'); value_string=strchr(value_string+1,':'); if(NULL == value_string) { return FAIL; } /* It points to ':', so have to increment */ value_string++; lastlogsize[0]=0; timestamp[0]=0; source[0]=0; severity[0]=0; } zabbix_log( LOG_LEVEL_DEBUG, "Value [%s]", value_string); av.clock = time(NULL); zbx_strlcpy(av.host_name, server, sizeof(av.host_name)); zbx_strlcpy(av.key, key, sizeof(av.key)); av.value = value_string; av.lastlogsize = atoi(lastlogsize); av.timestamp = atoi(timestamp); av.source = source; av.severity = atoi(severity); process_mass_data(sock, 0, &av, 1, NULL, 0); if( zbx_tcp_send_raw(sock, SUCCEED == ret ? "OK" : "NOT OK") != SUCCEED) { zabbix_log( LOG_LEVEL_WARNING, "Error sending result back"); zabbix_syslog("Trapper: error sending result back"); } zabbix_log( LOG_LEVEL_DEBUG, "After write()"); } return ret; }
/****************************************************************************** * * * Function: process_new_values * * * * Purpose: process values sent by active agents and senders * * * * Parameters: * * * * Return value: SUCCEED - processed successfully * * FAIL - an error occured * * * * Author: Alexei Vladishev * * * * Comments: * * * ******************************************************************************/ static int process_new_values(zbx_sock_t *sock, struct zbx_json_parse *jp, const zbx_uint64_t proxy_hostid) { struct zbx_json_parse jp_data, jp_row; const char *p; char info[MAX_STRING_LEN], tmp[MAX_STRING_LEN]; int ret = SUCCEED; int processed = 0; double sec; time_t now, proxy_timediff = 0; #define VALUES_MAX 256 static AGENT_VALUE *values = NULL, *av; int value_num = 0; zabbix_log(LOG_LEVEL_DEBUG, "In process_new_values()"); now = time(NULL); sec = zbx_time(); if (NULL == values) values = zbx_malloc(values, VALUES_MAX * sizeof(AGENT_VALUE)); if (SUCCEED == zbx_json_value_by_name(jp, ZBX_PROTO_TAG_CLOCK, tmp, sizeof(tmp))) proxy_timediff = now - atoi(tmp); /* {"request":"ZBX_SENDER_DATA","data":[{"key":"system.cpu.num",...,...},{...},...]} * ^ */ if (NULL == (p = zbx_json_pair_by_name(jp, ZBX_PROTO_TAG_DATA))) { zabbix_log(LOG_LEVEL_WARNING, "Can't find \"data\" pair"); ret = FAIL; } if(SUCCEED == ret) { /* {"request":"ZBX_SENDER_DATA","data":[{"key":"system.cpu.num",...,...},{...},...]} * ^------------------------------------------^ */ if (FAIL == (ret = zbx_json_brackets_open(p, &jp_data))) zabbix_log(LOG_LEVEL_WARNING, "Can't proceed jason request. %s", zbx_json_strerror()); } /* {"request":"ZBX_SENDER_DATA","data":[{"key":"system.cpu.num",...,...},{...},...]} * ^ */ p = NULL; while (SUCCEED == ret && NULL != (p = zbx_json_next(&jp_data, p))) { /* {"request":"ZBX_SENDER_DATA","data":[{"key":"system.cpu.num",...,...},{...},...]} * ^------------------------------^ */ if (FAIL == (ret = zbx_json_brackets_open(p, &jp_row))) break; /* zabbix_log(LOG_LEVEL_DEBUG, "Next \"%.*s\"", jp_row.end - jp_row.start + 1, jp_row.start);*/ av = &values[value_num]; memset(av, 0, sizeof(AGENT_VALUE)); if (SUCCEED == zbx_json_value_by_name(&jp_row, ZBX_PROTO_TAG_CLOCK, tmp, sizeof(tmp))) av->clock = atoi(tmp) + proxy_timediff; else av->clock = now; if (FAIL == zbx_json_value_by_name(&jp_row, ZBX_PROTO_TAG_HOST, av->host_name, sizeof(av->host_name))) continue; if (FAIL == zbx_json_value_by_name(&jp_row, ZBX_PROTO_TAG_KEY, av->key, sizeof(av->key))) continue; if (FAIL == zbx_json_value_by_name(&jp_row, ZBX_PROTO_TAG_VALUE, tmp, sizeof(tmp))) continue; av->value = strdup(tmp); if (SUCCEED == zbx_json_value_by_name(&jp_row, ZBX_PROTO_TAG_LOGLASTSIZE, tmp, sizeof(tmp))) av->lastlogsize = atoi(tmp); if (SUCCEED == zbx_json_value_by_name(&jp_row, ZBX_PROTO_TAG_LOGTIMESTAMP, tmp, sizeof(tmp))) av->timestamp = atoi(tmp); if (SUCCEED == zbx_json_value_by_name(&jp_row, ZBX_PROTO_TAG_LOGSOURCE, tmp, sizeof(tmp))) av->source = strdup(tmp); if (SUCCEED == zbx_json_value_by_name(&jp_row, ZBX_PROTO_TAG_LOGSEVERITY, tmp, sizeof(tmp))) av->severity = atoi(tmp); value_num ++; if (value_num == VALUES_MAX) { process_mass_data(sock, proxy_hostid, values, value_num, &processed, proxy_timediff); clean_agent_values(values, value_num); value_num = 0; } } if (value_num > 0) process_mass_data(sock, proxy_hostid, values, value_num, &processed, proxy_timediff); clean_agent_values(values, value_num); zbx_snprintf(info, sizeof(info), "Processed %d Failed %d Total %d Seconds spent " ZBX_FS_DBL, processed, value_num - processed, value_num, zbx_time() - sec); if (send_result(sock, ret, info) != SUCCEED) { zabbix_log( LOG_LEVEL_WARNING, "Error sending result back"); zabbix_syslog("Trapper: error sending result back"); } return ret; }
/****************************************************************************** * * * Function: node_process_command * * * * Purpose: process command received from a master node or php * * * * Return value: SUCCEED - processed successfully * * FAIL - an error occurred * * * ******************************************************************************/ int node_process_command(zbx_sock_t *sock, const char *data, struct zbx_json_parse *jp) { char *result = NULL, *send = NULL, tmp[64]; int nodeid = -1, next_nodeid, ret = FAIL; zbx_uint64_t scriptid, hostid; struct zbx_json j; zabbix_log(LOG_LEVEL_DEBUG, "In node_process_command()"); zbx_json_init(&j, ZBX_JSON_STAT_BUF_LEN); if (SUCCEED != zbx_json_value_by_name(jp, ZBX_PROTO_TAG_NODEID, tmp, sizeof(tmp)) || FAIL == is_uint31(tmp, &nodeid)) { result = zbx_dsprintf(result, "Failed to parse command request tag: %s.", ZBX_PROTO_TAG_NODEID); goto finish; } if (SUCCEED != zbx_json_value_by_name(jp, ZBX_PROTO_TAG_SCRIPTID, tmp, sizeof(tmp)) || FAIL == is_uint64(tmp, &scriptid)) { result = zbx_dsprintf(result, "Failed to parse command request tag: %s.", ZBX_PROTO_TAG_SCRIPTID); goto finish; } if (SUCCEED != zbx_json_value_by_name(jp, ZBX_PROTO_TAG_HOSTID, tmp, sizeof(tmp)) || FAIL == is_uint64(tmp, &hostid)) { result = zbx_dsprintf(result, "Failed to parse command request tag: %s.", ZBX_PROTO_TAG_HOSTID); goto finish; } if (nodeid == CONFIG_NODEID) { if (SUCCEED == (ret = execute_script(scriptid, hostid, &result))) { zbx_json_addstring(&j, ZBX_PROTO_TAG_RESPONSE, ZBX_PROTO_VALUE_SUCCESS, ZBX_JSON_TYPE_STRING); zbx_json_addstring(&j, ZBX_PROTO_TAG_DATA, result, ZBX_JSON_TYPE_STRING); send = j.buffer; } } else if (SUCCEED == get_next_point_to_node(CONFIG_NODEID, nodeid, &next_nodeid)) { zabbix_log(LOG_LEVEL_WARNING, "NODE %d: Sending command for Node %d to Node %d", CONFIG_NODEID, nodeid, next_nodeid); if (SUCCEED == (ret = send_script(next_nodeid, data, &result))) send = result; } else result = zbx_dsprintf(result, "NODE %d: Unknown Node ID [%d].", CONFIG_NODEID, nodeid); finish: if (FAIL == ret) { zbx_json_addstring(&j, ZBX_PROTO_TAG_RESPONSE, ZBX_PROTO_VALUE_FAILED, ZBX_JSON_TYPE_STRING); zbx_json_addstring(&j, ZBX_PROTO_TAG_INFO, (NULL != result ? result : "Unknown error."), ZBX_JSON_TYPE_STRING); send = j.buffer; } alarm(CONFIG_TIMEOUT); if (SUCCEED != zbx_tcp_send_raw(sock, send)) { zabbix_log(LOG_LEVEL_WARNING, "NODE %d: Error sending result of command to node %d", CONFIG_NODEID, nodeid); } else { zabbix_log(LOG_LEVEL_DEBUG, "NODE %d: Sending back command '%s' result '%s'", CONFIG_NODEID, data, send); } alarm(0); zbx_json_free(&j); zbx_free(result); return ret; }
/****************************************************************************** * * * Function: parse_list_of_checks * * * * Purpose: Parse list of active checks received from server * * * * Parameters: str - NULL terminated string received from server * * host - address of host * * port - port number on host * * * * Return value: returns SUCCEED on successful parsing, * * FAIL on an incorrect format of string * * * * Author: Eugene Grigorjev, Alexei Vladishev (new json protocol) * * * * Comments: * * String represented as "ZBX_EOF" termination list * * With '\n' delimiter between elements. * * Each element represented as: * * <key>:<refresh time>:<last log size>:<modification time> * * * ******************************************************************************/ static int parse_list_of_checks(char *str, const char *host, unsigned short port) { const char *p; char name[MAX_STRING_LEN], key_orig[MAX_STRING_LEN], expression[MAX_STRING_LEN], tmp[MAX_STRING_LEN], exp_delimiter; int delay, mtime, expression_type, case_sensitive; zbx_uint64_t lastlogsize; struct zbx_json_parse jp; struct zbx_json_parse jp_data, jp_row; zabbix_log(LOG_LEVEL_DEBUG, "In parse_list_of_checks()"); disable_all_metrics(); if (SUCCEED != zbx_json_open(str, &jp)) goto json_error; if (SUCCEED != zbx_json_value_by_name(&jp, ZBX_PROTO_TAG_RESPONSE, tmp, sizeof(tmp))) goto json_error; if (0 != strcmp(tmp, ZBX_PROTO_VALUE_SUCCESS)) { if (SUCCEED == zbx_json_value_by_name(&jp, ZBX_PROTO_TAG_INFO, tmp, sizeof(tmp))) zabbix_log(LOG_LEVEL_WARNING, "no active checks on server [%s:%hu]: %s", host, port, tmp); else zabbix_log(LOG_LEVEL_WARNING, "no active checks on server"); return FAIL; } if (SUCCEED != zbx_json_brackets_by_name(&jp, ZBX_PROTO_TAG_DATA, &jp_data)) goto json_error; p = NULL; while (NULL != (p = zbx_json_next(&jp_data, p))) { /* {"data":[{"key":"system.cpu.num",...,...},{...},...]} * ^------------------------------^ */ if (SUCCEED != zbx_json_brackets_open(p, &jp_row)) goto json_error; if (SUCCEED != zbx_json_value_by_name(&jp_row, ZBX_PROTO_TAG_KEY, name, sizeof(name)) || '\0' == *name) { zabbix_log(LOG_LEVEL_WARNING, "cannot retrieve value of tag \"%s\"", ZBX_PROTO_TAG_KEY); continue; } if (SUCCEED != zbx_json_value_by_name(&jp_row, ZBX_PROTO_TAG_KEY_ORIG, key_orig, sizeof(key_orig)) || '\0' == *key_orig) { zbx_strlcpy(key_orig, name, sizeof(key_orig)); } if (SUCCEED != zbx_json_value_by_name(&jp_row, ZBX_PROTO_TAG_DELAY, tmp, sizeof(tmp)) || '\0' == *tmp) { zabbix_log(LOG_LEVEL_WARNING, "cannot retrieve value of tag \"%s\"", ZBX_PROTO_TAG_DELAY); continue; } delay = atoi(tmp); if (SUCCEED != zbx_json_value_by_name(&jp_row, ZBX_PROTO_TAG_LOGLASTSIZE, tmp, sizeof(tmp)) || SUCCEED != is_uint64(tmp, &lastlogsize)) { zabbix_log(LOG_LEVEL_WARNING, "cannot retrieve value of tag \"%s\"", ZBX_PROTO_TAG_LOGLASTSIZE); continue; } if (SUCCEED != zbx_json_value_by_name(&jp_row, ZBX_PROTO_TAG_MTIME, tmp, sizeof(tmp)) || '\0' == *tmp) { zabbix_log(LOG_LEVEL_WARNING, "cannot retrieve value of tag \"%s\"", ZBX_PROTO_TAG_MTIME); mtime = 0; } else mtime = atoi(tmp); add_check(name, key_orig, delay, lastlogsize, mtime); } zbx_regexp_clean_expressions(®exps); if (SUCCEED == zbx_json_brackets_by_name(&jp, ZBX_PROTO_TAG_REGEXP, &jp_data)) { p = NULL; while (NULL != (p = zbx_json_next(&jp_data, p))) { /* {"regexp":[{"name":"regexp1",...,...},{...},...]} * ^------------------------^ */ if (SUCCEED != zbx_json_brackets_open(p, &jp_row)) goto json_error; if (SUCCEED != zbx_json_value_by_name(&jp_row, "name", name, sizeof(name))) { zabbix_log(LOG_LEVEL_WARNING, "cannot retrieve value of tag \"%s\"", "name"); continue; } if (SUCCEED != zbx_json_value_by_name(&jp_row, "expression", expression, sizeof(expression)) || '\0' == *expression) { zabbix_log(LOG_LEVEL_WARNING, "cannot retrieve value of tag \"%s\"", "expression"); continue; } if (SUCCEED != zbx_json_value_by_name(&jp_row, "expression_type", tmp, sizeof(tmp)) || '\0' == *tmp) { zabbix_log(LOG_LEVEL_WARNING, "cannot retrieve value of tag \"%s\"", "expression_type"); continue; } expression_type = atoi(tmp); if (SUCCEED != zbx_json_value_by_name(&jp_row, "exp_delimiter", tmp, sizeof(tmp))) { zabbix_log(LOG_LEVEL_WARNING, "cannot retrieve value of tag \"%s\"", "exp_delimiter"); continue; } exp_delimiter = tmp[0]; if (SUCCEED != zbx_json_value_by_name(&jp_row, "case_sensitive", tmp, sizeof(tmp)) || '\0' == *tmp) { zabbix_log(LOG_LEVEL_WARNING, "cannot retrieve value of tag \"%s\"", "case_sensitive"); continue; } case_sensitive = atoi(tmp); add_regexp_ex(®exps, name, expression, expression_type, exp_delimiter, case_sensitive); } } return SUCCEED; json_error: zabbix_log(LOG_LEVEL_ERR, "cannot parse list of active checks: %s", zbx_json_strerror()); return FAIL; }
static int process_trap(zbx_socket_t *sock, char *s, zbx_timespec_t *ts) { int ret = SUCCEED; zbx_rtrim(s, " \r\n"); zabbix_log(LOG_LEVEL_DEBUG, "trapper got '%s'", s); if ('{' == *s) /* JSON protocol */ { struct zbx_json_parse jp; char value[MAX_STRING_LEN]; if (SUCCEED != zbx_json_open(s, &jp)) { zbx_send_response(sock, FAIL, zbx_json_strerror(), CONFIG_TIMEOUT); zabbix_log(LOG_LEVEL_WARNING, "received invalid JSON object from %s: %s", sock->peer, zbx_json_strerror()); return FAIL; } if (SUCCEED == zbx_json_value_by_name(&jp, ZBX_PROTO_TAG_REQUEST, value, sizeof(value))) { if (0 == strcmp(value, ZBX_PROTO_VALUE_PROXY_CONFIG)) { if (0 != (program_type & ZBX_PROGRAM_TYPE_SERVER)) { send_proxyconfig(sock, &jp); } else if (0 != (program_type & ZBX_PROGRAM_TYPE_PROXY_PASSIVE)) { zabbix_log(LOG_LEVEL_WARNING, "received configuration data from server" " at \"%s\", datalen " ZBX_FS_SIZE_T, sock->peer, (zbx_fs_size_t)(jp.end - jp.start + 1)); recv_proxyconfig(sock, &jp); } else if (0 != (program_type & ZBX_PROGRAM_TYPE_PROXY_ACTIVE)) { /* This is a misconfiguration: the proxy is configured in active mode */ /* but server sends requests to it as to a proxy in passive mode. To */ /* prevent logging of this problem for every request we report it */ /* only when the server sends configuration to the proxy and ignore */ /* it for other requests. */ active_passive_misconfig(sock); } } else if (0 == strcmp(value, ZBX_PROTO_VALUE_AGENT_DATA) || 0 == strcmp(value, ZBX_PROTO_VALUE_SENDER_DATA)) { recv_agenthistory(sock, &jp, ts); } else if (0 == strcmp(value, ZBX_PROTO_VALUE_HISTORY_DATA)) { if (0 != (program_type & ZBX_PROGRAM_TYPE_SERVER)) recv_proxyhistory(sock, &jp, ts); else if (0 != (program_type & ZBX_PROGRAM_TYPE_PROXY_PASSIVE)) send_proxyhistory(sock, ts); } else if (0 == strcmp(value, ZBX_PROTO_VALUE_DISCOVERY_DATA)) { if (0 != (program_type & ZBX_PROGRAM_TYPE_SERVER)) recv_discovery_data(sock, &jp); else if (0 != (program_type & ZBX_PROGRAM_TYPE_PROXY_PASSIVE)) send_discovery_data(sock); } else if (0 == strcmp(value, ZBX_PROTO_VALUE_AUTO_REGISTRATION_DATA)) { if (0 != (program_type & ZBX_PROGRAM_TYPE_SERVER)) recv_areg_data(sock, &jp); else if (0 != (program_type & ZBX_PROGRAM_TYPE_PROXY_PASSIVE)) send_areg_data(sock); } else if (0 == strcmp(value, ZBX_PROTO_VALUE_PROXY_HEARTBEAT)) { if (0 != (program_type & ZBX_PROGRAM_TYPE_SERVER)) recv_proxy_heartbeat(sock, &jp); } else if (0 == strcmp(value, ZBX_PROTO_VALUE_GET_ACTIVE_CHECKS)) { ret = send_list_of_active_checks_json(sock, &jp); } else if (0 == strcmp(value, ZBX_PROTO_VALUE_HOST_AVAILABILITY)) { if (0 != (program_type & ZBX_PROGRAM_TYPE_SERVER)) recv_host_availability(sock, &jp); else if (0 != (program_type & ZBX_PROGRAM_TYPE_PROXY_PASSIVE)) send_host_availability(sock); } else if (0 == strcmp(value, ZBX_PROTO_VALUE_COMMAND)) { ret = node_process_command(sock, s, &jp); } else if (0 == strcmp(value, ZBX_PROTO_VALUE_GET_QUEUE)) { if (0 != (program_type & ZBX_PROGRAM_TYPE_SERVER)) ret = recv_getqueue(sock, &jp); } else zabbix_log(LOG_LEVEL_WARNING, "unknown request received [%s]", value); } } else if (0 == strncmp(s, "ZBX_GET_ACTIVE_CHECKS", 21)) /* request for list of active checks */ { ret = send_list_of_active_checks(sock, s); } else { char value_dec[MAX_BUFFER_LEN], lastlogsize[ZBX_MAX_UINT64_LEN], timestamp[11], source[HISTORY_LOG_SOURCE_LEN_MAX], severity[11]; AGENT_VALUE av; memset(&av, 0, sizeof(AGENT_VALUE)); if ('<' == *s) /* XML protocol */ { comms_parse_response(s, av.host_name, sizeof(av.host_name), av.key, sizeof(av.key), value_dec, sizeof(value_dec), lastlogsize, sizeof(lastlogsize), timestamp, sizeof(timestamp), source, sizeof(source), severity, sizeof(severity)); av.value = value_dec; if (SUCCEED != is_uint64(lastlogsize, &av.lastlogsize)) av.lastlogsize = 0; av.timestamp = atoi(timestamp); av.source = source; av.severity = atoi(severity); } else { char *pl, *pr; pl = s; if (NULL == (pr = strchr(pl, ':'))) return FAIL; *pr = '\0'; zbx_strlcpy(av.host_name, pl, sizeof(av.host_name)); *pr = ':'; pl = pr + 1; if (NULL == (pr = strchr(pl, ':'))) return FAIL; *pr = '\0'; zbx_strlcpy(av.key, pl, sizeof(av.key)); *pr = ':'; av.value = pr + 1; av.severity = 0; } zbx_timespec(&av.ts); if (0 == strcmp(av.value, ZBX_NOTSUPPORTED)) av.state = ITEM_STATE_NOTSUPPORTED; process_mass_data(sock, 0, &av, 1, NULL); zbx_alarm_on(CONFIG_TIMEOUT); if (SUCCEED != zbx_tcp_send_raw(sock, "OK")) zabbix_log(LOG_LEVEL_WARNING, "Error sending result back"); zbx_alarm_off(); } return ret; }
/****************************************************************************** * * * Function: recv_getqueue * * * * Purpose: process queue request * * * * Parameters: sock - [IN] the request socket * * jp - [IN] the request data * * * * Return value: SUCCEED - processed successfully * * FAIL - an error occurred * * * ******************************************************************************/ static int recv_getqueue(zbx_socket_t *sock, struct zbx_json_parse *jp) { const char *__function_name = "recv_getqueue"; int ret = FAIL, request_type = -1, now, i; char type[MAX_STRING_LEN], sessionid[MAX_STRING_LEN]; zbx_vector_ptr_t queue; struct zbx_json json; zbx_hashset_t queue_stats; zbx_queue_stats_t *stats; zabbix_log(LOG_LEVEL_DEBUG, "In %s()", __function_name); if (FAIL == zbx_json_value_by_name(jp, ZBX_PROTO_TAG_SID, sessionid, sizeof(sessionid)) || FAIL == zbx_session_validate(sessionid, USER_TYPE_SUPER_ADMIN)) { zbx_send_response_raw(sock, ret, "Permission denied.", CONFIG_TIMEOUT); goto out; } if (FAIL != zbx_json_value_by_name(jp, ZBX_PROTO_TAG_TYPE, type, sizeof(type))) { if (0 == strcmp(type, ZBX_PROTO_VALUE_GET_QUEUE_OVERVIEW)) request_type = ZBX_GET_QUEUE_OVERVIEW; else if (0 == strcmp(type, ZBX_PROTO_VALUE_GET_QUEUE_PROXY)) request_type = ZBX_GET_QUEUE_PROXY; else if (0 == strcmp(type, ZBX_PROTO_VALUE_GET_QUEUE_DETAILS)) request_type = ZBX_GET_QUEUE_DETAILS; } if (-1 == request_type) { zbx_send_response_raw(sock, ret, "Unsupported request type.", CONFIG_TIMEOUT); goto out; } now = time(NULL); zbx_vector_ptr_create(&queue); DCget_item_queue(&queue, 6, -1); zbx_json_init(&json, ZBX_JSON_STAT_BUF_LEN); switch (request_type) { case ZBX_GET_QUEUE_OVERVIEW: zbx_hashset_create(&queue_stats, 32, ZBX_DEFAULT_UINT64_HASH_FUNC, ZBX_DEFAULT_UINT64_COMPARE_FUNC); /* gather queue stats by item type */ for (i = 0; i < queue.values_num; i++) { zbx_queue_item_t *item = queue.values[i]; zbx_uint64_t id = item->type; if (NULL == (stats = zbx_hashset_search(&queue_stats, &id))) { zbx_queue_stats_t data = {id}; stats = zbx_hashset_insert(&queue_stats, &data, sizeof(data)); } queue_stats_update(stats, now - item->nextcheck); } zbx_json_addstring(&json, ZBX_PROTO_TAG_RESPONSE, ZBX_PROTO_VALUE_SUCCESS, ZBX_JSON_TYPE_STRING); queue_stats_export(&queue_stats, "itemtype", &json); zbx_hashset_destroy(&queue_stats); break; case ZBX_GET_QUEUE_PROXY: zbx_hashset_create(&queue_stats, 32, ZBX_DEFAULT_UINT64_HASH_FUNC, ZBX_DEFAULT_UINT64_COMPARE_FUNC); /* gather queue stats by proxy hostid */ for (i = 0; i < queue.values_num; i++) { zbx_queue_item_t *item = queue.values[i]; zbx_uint64_t id = item->proxy_hostid; if (NULL == (stats = zbx_hashset_search(&queue_stats, &id))) { zbx_queue_stats_t data = {id}; stats = zbx_hashset_insert(&queue_stats, &data, sizeof(data)); } queue_stats_update(stats, now - item->nextcheck); } zbx_json_addstring(&json, ZBX_PROTO_TAG_RESPONSE, ZBX_PROTO_VALUE_SUCCESS, ZBX_JSON_TYPE_STRING); queue_stats_export(&queue_stats, "proxyid", &json); zbx_hashset_destroy(&queue_stats); break; case ZBX_GET_QUEUE_DETAILS: zbx_vector_ptr_sort(&queue, (zbx_compare_func_t)queue_compare_by_nextcheck_asc); zbx_json_addstring(&json, ZBX_PROTO_TAG_RESPONSE, ZBX_PROTO_VALUE_SUCCESS, ZBX_JSON_TYPE_STRING); zbx_json_addarray(&json, ZBX_PROTO_TAG_DATA); for (i = 0; i < queue.values_num && i <= 500; i++) { zbx_queue_item_t *item = queue.values[i]; zbx_json_addobject(&json, NULL); zbx_json_adduint64(&json, "itemid", item->itemid); zbx_json_adduint64(&json, "nextcheck", item->nextcheck); zbx_json_close(&json); } zbx_json_close(&json); break; } zabbix_log(LOG_LEVEL_DEBUG, "%s() json.buffer:'%s'", __function_name, json.buffer); zbx_tcp_send_raw(sock, json.buffer); DCfree_item_queue(&queue); zbx_vector_ptr_destroy(&queue); zbx_json_free(&json); ret = SUCCEED; out: zabbix_log(LOG_LEVEL_DEBUG, "End of %s()", __function_name); return ret; }
static int parse_response(DC_ITEM *items, AGENT_RESULT *results, int *errcodes, int num, char *response, char *error, int max_error_len) { const char *p; struct zbx_json_parse jp, jp_data, jp_row; char *value = NULL; size_t value_alloc = 0; int i, ret = GATEWAY_ERROR; if (SUCCEED == zbx_json_open(response, &jp)) { if (SUCCEED != zbx_json_value_by_name_dyn(&jp, ZBX_PROTO_TAG_RESPONSE, &value, &value_alloc)) { zbx_snprintf(error, max_error_len, "No '%s' tag in received JSON", ZBX_PROTO_TAG_RESPONSE); goto exit; } if (0 == strcmp(value, ZBX_PROTO_VALUE_SUCCESS)) { if (SUCCEED != zbx_json_brackets_by_name(&jp, ZBX_PROTO_TAG_DATA, &jp_data)) { zbx_strlcpy(error, "Cannot open data array in received JSON", max_error_len); goto exit; } p = NULL; for (i = 0; i < num; i++) { if (SUCCEED != errcodes[i]) continue; if (NULL == (p = zbx_json_next(&jp_data, p))) { zbx_strlcpy(error, "Not all values included in received JSON", max_error_len); goto exit; } if (SUCCEED != zbx_json_brackets_open(p, &jp_row)) { zbx_strlcpy(error, "Cannot open value object in received JSON", max_error_len); goto exit; } if (SUCCEED == zbx_json_value_by_name_dyn(&jp_row, ZBX_PROTO_TAG_VALUE, &value, &value_alloc)) { if (SUCCEED == set_result_type(&results[i], items[i].value_type, items[i].data_type, value)) errcodes[i] = SUCCEED; else errcodes[i] = NOTSUPPORTED; } else if (SUCCEED == zbx_json_value_by_name_dyn(&jp_row, ZBX_PROTO_TAG_ERROR, &value, &value_alloc)) { SET_MSG_RESULT(&results[i], zbx_strdup(NULL, value)); errcodes[i] = NOTSUPPORTED; } else { SET_MSG_RESULT(&results[i], zbx_strdup(NULL, "Cannot get item value or error message")); errcodes[i] = AGENT_ERROR; } } ret = SUCCEED; } else if (0 == strcmp(value, ZBX_PROTO_VALUE_FAILED)) { if (SUCCEED == zbx_json_value_by_name(&jp, ZBX_PROTO_TAG_ERROR, error, max_error_len)) ret = NETWORK_ERROR; else zbx_strlcpy(error, "Cannot get error message describing reasons for failure", max_error_len); goto exit; } else { zbx_snprintf(error, max_error_len, "Bad '%s' tag value '%s' in received JSON", ZBX_PROTO_TAG_RESPONSE, value); goto exit; } } else { zbx_strlcpy(error, "Cannot open received JSON", max_error_len); goto exit; } exit: zbx_free(value); 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_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_sock_t *sock, struct zbx_json_parse *jp) { const char *__function_name = "send_list_of_active_checks_json"; char host[HOST_HOST_LEN_MAX], *name_esc, params[MAX_STRING_LEN], pattern[MAX_STRING_LEN], tmp[32], key_severity[MAX_STRING_LEN], key_logeventid[MAX_STRING_LEN], ip[INTERFACE_IP_LEN_MAX]; DB_RESULT result; DB_ROW row; struct zbx_json json; int res = FAIL, refresh_unsupported, now; zbx_uint64_t hostid; char error[MAX_STRING_LEN], *key = NULL; DC_ITEM dc_item; unsigned short port; char **regexp = NULL; int regexp_alloc = 0; int regexp_num = 0, n; char *sql = NULL; size_t sql_alloc = 2 * ZBX_KIBIBYTE, sql_offset = 0; zabbix_log(LOG_LEVEL_DEBUG, "In %s()", __function_name); 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; } if (FAIL == zbx_json_value_by_name(jp, ZBX_PROTO_TAG_IP, ip, sizeof(ip))) strscpy(ip, get_ip_by_socket(sock)); 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(host, ip, port, &hostid, error)) goto error; DCconfig_get_config_data(&refresh_unsupported, CONFIG_REFRESH_UNSUPPORTED); now = time(NULL); sql = zbx_malloc(sql, sql_alloc); name_esc = DBdyn_escape_string(host); zbx_snprintf_alloc(&sql, &sql_alloc, &sql_offset, "select i.key_,i.delay,i.lastlogsize,i.mtime" " from items i,hosts h" " where i.hostid=h.hostid" " and h.status=%d" " and i.type=%d" " and i.flags<>%d" " and h.hostid=" ZBX_FS_UI64 " and h.proxy_hostid is null", HOST_STATUS_MONITORED, ITEM_TYPE_ZABBIX_ACTIVE, ZBX_FLAG_DISCOVERY_CHILD, hostid); zbx_free(name_esc); 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); result = DBselect("%s", sql); while (NULL != (row = DBfetch(result))) { if (FAIL == DCconfig_get_item_by_key(&dc_item, (zbx_uint64_t)0, host, row[0])) { zabbix_log(LOG_LEVEL_DEBUG, "%s() Item '%s' was not found in the server cache. Not sending now.", __function_name, row[0]); continue; } if (ITEM_STATUS_NOTSUPPORTED == dc_item.status) { if (0 == refresh_unsupported || dc_item.lastclock + refresh_unsupported > now) { DCconfig_clean_items(&dc_item, NULL, 1); continue; } } zabbix_log(LOG_LEVEL_DEBUG, "%s() Item '%s' was successfully found in the server cache. Sending.", __function_name, row[0]); ZBX_STRDUP(key, row[0]); substitute_key_macros(&key, NULL, &dc_item, NULL, MACRO_TYPE_ITEM_KEY, NULL, 0); DCconfig_clean_items(&dc_item, NULL, 1); zbx_json_addobject(&json, NULL); zbx_json_addstring(&json, ZBX_PROTO_TAG_KEY, key, ZBX_JSON_TYPE_STRING); if (0 != strcmp(key, row[0])) zbx_json_addstring(&json, ZBX_PROTO_TAG_KEY_ORIG, row[0], ZBX_JSON_TYPE_STRING); zbx_json_addstring(&json, ZBX_PROTO_TAG_DELAY, row[1], ZBX_JSON_TYPE_INT); /* The agent expects ALWAYS to have lastlogsize and mtime tags. Removing those would cause older agents to fail. */ zbx_json_addstring(&json, ZBX_PROTO_TAG_LOGLASTSIZE, row[2], ZBX_JSON_TYPE_INT); zbx_json_addstring(&json, ZBX_PROTO_TAG_MTIME, row[3], ZBX_JSON_TYPE_INT); zbx_json_close(&json); /* special processing for log[] and logrt[] items */ do { /* simple try realization */ /* log[filename,pattern,encoding,maxlinespersec] */ /* logrt[filename_format,pattern,encoding,maxlinespersec] */ if (0 != strncmp(key, "log[", 4) && 0 != strncmp(key, "logrt[", 6)) break; if (2 != parse_command(key, NULL, 0, params, sizeof(params))) break; /* dealing with `pattern' parameter */ if (0 == get_param(params, 2, pattern, sizeof(pattern)) && *pattern == '@') add_regexp_name(®exp, ®exp_alloc, ®exp_num, pattern + 1); } while (0); /* simple try realization */ /* special processing for eventlog[] items */ do { /* simple try realization */ /* eventlog[filename,pattern,severity,source,logeventid,maxlinespersec] */ if (0 != strncmp(key, "eventlog[", 9)) break; if (2 != parse_command(key, NULL, 0, params, sizeof(params))) break; /* dealing with `pattern' parameter */ if (0 == get_param(params, 2, pattern, sizeof(pattern)) && *pattern == '@') add_regexp_name(®exp, ®exp_alloc, ®exp_num, pattern + 1); /* dealing with `severity' parameter */ if (0 == get_param(params, 3, key_severity, sizeof(key_severity)) && *key_severity == '@') add_regexp_name(®exp, ®exp_alloc, ®exp_num, key_severity + 1); /* dealing with `logeventid' parameter */ if (0 == get_param(params, 5, key_logeventid, sizeof(key_logeventid)) && *key_logeventid == '@') add_regexp_name(®exp, ®exp_alloc, ®exp_num, key_logeventid + 1); } while (0); /* simple try realization */ zbx_free(key); } zbx_json_close(&json); DBfree_result(result); if (0 != regexp_num) { zbx_json_addarray(&json, ZBX_PROTO_TAG_REGEXP); sql_offset = 0; zbx_strcpy_alloc(&sql, &sql_alloc, &sql_offset, "select r.name,e.expression,e.expression_type,e.exp_delimiter,e.case_sensitive" " from regexps r,expressions e" " where r.regexpid=e.regexpid" " and r.name in ("); for (n = 0; n < regexp_num; n++) { name_esc = DBdyn_escape_string(regexp[n]); zbx_snprintf_alloc(&sql, &sql_alloc, &sql_offset, "%s'%s'", n == 0 ? "" : ",", name_esc); zbx_free(name_esc); zbx_free(regexp[n]); } zbx_chrcpy_alloc(&sql, &sql_alloc, &sql_offset, ')'); zbx_snprintf_alloc(&sql, &sql_alloc, &sql_offset, DB_NODE, DBnode_local("r.regexpid")); result = DBselect("%s", sql); while (NULL != (row = DBfetch(result))) { zbx_json_addobject(&json, NULL); zbx_json_addstring(&json, "name", row[0], ZBX_JSON_TYPE_STRING); zbx_json_addstring(&json, "expression", row[1], ZBX_JSON_TYPE_STRING); zbx_json_addstring(&json, "expression_type", row[2], ZBX_JSON_TYPE_INT); zbx_json_addstring(&json, "exp_delimiter", row[3], ZBX_JSON_TYPE_STRING); zbx_json_addstring(&json, "case_sensitive", row[4], ZBX_JSON_TYPE_INT); zbx_json_close(&json); } DBfree_result(result); } zbx_free(regexp); zabbix_log(LOG_LEVEL_DEBUG, "%s() sending [%s]", __function_name, json.buffer); alarm(CONFIG_TIMEOUT); if (SUCCEED != zbx_tcp_send(sock, json.buffer)) strscpy(error, zbx_tcp_strerror()); else res = SUCCEED; alarm(0); zbx_json_free(&json); zbx_free(sql); goto out; error: zabbix_log(LOG_LEVEL_WARNING, "cannot send list of active checks to [%s]: %s", get_ip_by_socket(sock), 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); res = zbx_tcp_send(sock, json.buffer); zbx_json_free(&json); out: zabbix_log(LOG_LEVEL_DEBUG, "End of %s():%s", __function_name, zbx_result_string(res)); return res; }
/****************************************************************************** * * * Function: node_process_command * * * * Purpose: process command received from a master node or php * * * * Parameters: * * * * Return value: SUCCEED - processed successfully * * FAIL - an error occurred * * * * Author: Alexander Vladishev * * * * Comments: * * * ******************************************************************************/ int node_process_command(zbx_sock_t *sock, const char *data, struct zbx_json_parse *jp) { char *result = NULL, *send, tmp[64]; const char *response; int nodeid, next_nodeid, ret = FAIL; zbx_uint64_t scriptid, hostid; struct zbx_json j; zabbix_log(LOG_LEVEL_DEBUG, "In node_process_command()"); if (SUCCEED != zbx_json_value_by_name(jp, ZBX_PROTO_TAG_NODEID, tmp, sizeof(tmp))) return FAIL; nodeid = atoi(tmp); if (SUCCEED != zbx_json_value_by_name(jp, ZBX_PROTO_TAG_SCRIPTID, tmp, sizeof(tmp))) return FAIL; ZBX_STR2UINT64(scriptid, tmp); if (SUCCEED != zbx_json_value_by_name(jp, ZBX_PROTO_TAG_HOSTID, tmp, sizeof(tmp))) return FAIL; ZBX_STR2UINT64(hostid, tmp); zbx_json_init(&j, 256); if (nodeid == CONFIG_NODEID) { ret = execute_script(scriptid, hostid, &result); response = (FAIL == ret) ? ZBX_PROTO_VALUE_FAILED : ZBX_PROTO_VALUE_SUCCESS; zbx_json_addstring(&j, ZBX_PROTO_TAG_RESPONSE, response, ZBX_JSON_TYPE_STRING); zbx_json_addstring(&j, ZBX_PROTO_TAG_VALUE, result, ZBX_JSON_TYPE_STRING); send = j.buffer; } else if (SUCCEED == get_next_point_to_node(CONFIG_NODEID, nodeid, &next_nodeid)) { zabbix_log(LOG_LEVEL_WARNING, "NODE %d: Sending command for Node %d to Node %d", CONFIG_NODEID, nodeid, next_nodeid); if (FAIL == (ret = send_script(next_nodeid, data, &result))) { zbx_json_addstring(&j, ZBX_PROTO_TAG_RESPONSE, ZBX_PROTO_VALUE_FAILED, ZBX_JSON_TYPE_STRING); zbx_json_addstring(&j, ZBX_PROTO_TAG_VALUE, result, ZBX_JSON_TYPE_STRING); send = j.buffer; } else send = result; } else { result = zbx_dsprintf(result, "NODE %d: Unknown Node ID [%d]", CONFIG_NODEID, nodeid); zbx_json_addstring(&j, ZBX_PROTO_TAG_RESPONSE, ZBX_PROTO_VALUE_FAILED, ZBX_JSON_TYPE_STRING); zbx_json_addstring(&j, ZBX_PROTO_TAG_VALUE, result, ZBX_JSON_TYPE_STRING); send = j.buffer; } alarm(CONFIG_TIMEOUT); if (zbx_tcp_send_raw(sock, send) != SUCCEED) { zabbix_log(LOG_LEVEL_WARNING, "NODE %d: Error sending result of command to node %d", CONFIG_NODEID, nodeid); } alarm(0); zbx_json_free(&j); zbx_free(result); return SUCCEED; }
static int process_trap(zbx_sock_t *sock, char *s, int max_len) { char *pl, *pr, *data, value_dec[MAX_BUFFER_LEN]; char lastlogsize[11], timestamp[11], source[HISTORY_LOG_SOURCE_LEN_MAX], severity[11]; int sender_nodeid, nodeid; char *answer; int ret = SUCCEED, res; size_t datalen; struct zbx_json_parse jp; char value[MAX_STRING_LEN]; AGENT_VALUE av; memset(&av, 0, sizeof(AGENT_VALUE)); zbx_rtrim(s, " \r\n"); datalen = strlen(s); zabbix_log(LOG_LEVEL_DEBUG, "Trapper got [%s] len " ZBX_FS_SIZE_T, s, (zbx_fs_size_t)datalen); if (0 == strncmp(s, "ZBX_GET_ACTIVE_CHECKS", 21)) /* Request for list of active checks */ { ret = send_list_of_active_checks(sock, s); } else if (strncmp(s, "ZBX_GET_HISTORY_LAST_ID", 23) == 0) /* Request for last ids */ { send_history_last_id(sock, s); return ret; } else /* Process information sent by zabbix_sender */ { /* Node data exchange? */ if (strncmp(s, "Data", 4) == 0) { node_sync_lock(0); res = node_sync(s, &sender_nodeid, &nodeid); if (FAIL == res) { alarm(CONFIG_TIMEOUT); send_data_to_node(sender_nodeid, sock, "FAIL"); alarm(0); } else { res = calculate_checksums(nodeid, NULL, 0); if (SUCCEED == res && NULL != (data = get_config_data(nodeid, ZBX_NODE_SLAVE))) { zabbix_log( LOG_LEVEL_WARNING, "NODE %d: Sending configuration changes" " to slave node %d for node %d datalen " ZBX_FS_SIZE_T, CONFIG_NODEID, sender_nodeid, nodeid, (zbx_fs_size_t)strlen(data)); alarm(CONFIG_TRAPPER_TIMEOUT); res = send_data_to_node(sender_nodeid, sock, data); zbx_free(data); if (SUCCEED == res) res = recv_data_from_node(sender_nodeid, sock, &answer); if (SUCCEED == res && 0 == strcmp(answer, "OK")) res = update_checksums(nodeid, ZBX_NODE_SLAVE, SUCCEED, NULL, 0, NULL); alarm(0); } } node_sync_unlock(0); return ret; } /* Slave node history ? */ if (strncmp(s, "History", 7) == 0) { const char *reply; reply = (SUCCEED == node_history(s, datalen) ? "OK" : "FAIL"); alarm(CONFIG_TIMEOUT); if (SUCCEED != zbx_tcp_send_raw(sock, reply)) { zabbix_log(LOG_LEVEL_WARNING, "Error sending %s to node", reply); zabbix_syslog("Trapper: error sending %s to node", reply); } alarm(0); return ret; } /* JSON protocol? */ else if (SUCCEED == zbx_json_open(s, &jp)) { if (SUCCEED == zbx_json_value_by_name(&jp, ZBX_PROTO_TAG_REQUEST, value, sizeof(value))) { if (0 == strcmp(value, ZBX_PROTO_VALUE_PROXY_CONFIG)) { if (0 != (daemon_type & ZBX_DAEMON_TYPE_SERVER)) send_proxyconfig(sock, &jp); else if (0 != (daemon_type & ZBX_DAEMON_TYPE_PROXY_PASSIVE)) { zabbix_log(LOG_LEVEL_WARNING, "Received configuration data from server." " Datalen " ZBX_FS_SIZE_T, (zbx_fs_size_t)datalen); recv_proxyconfig(sock, &jp); } } else if (0 == strcmp(value, ZBX_PROTO_VALUE_AGENT_DATA) || 0 == strcmp(value, ZBX_PROTO_VALUE_SENDER_DATA)) { recv_agenthistory(sock, &jp); } else if (0 == strcmp(value, ZBX_PROTO_VALUE_HISTORY_DATA)) { if (0 != (daemon_type & ZBX_DAEMON_TYPE_SERVER)) recv_proxyhistory(sock, &jp); else if (0 != (daemon_type & ZBX_DAEMON_TYPE_PROXY_PASSIVE)) send_proxyhistory(sock); } else if (0 == strcmp(value, ZBX_PROTO_VALUE_DISCOVERY_DATA)) { if (0 != (daemon_type & ZBX_DAEMON_TYPE_SERVER)) recv_discovery_data(sock, &jp); else if (0 != (daemon_type & ZBX_DAEMON_TYPE_PROXY_PASSIVE)) send_discovery_data(sock); } else if (0 == strcmp(value, ZBX_PROTO_VALUE_AUTO_REGISTRATION_DATA)) { if (0 != (daemon_type & ZBX_DAEMON_TYPE_SERVER)) recv_areg_data(sock, &jp); else if (0 != (daemon_type & ZBX_DAEMON_TYPE_PROXY_PASSIVE)) send_areg_data(sock); } else if (0 == strcmp(value, ZBX_PROTO_VALUE_PROXY_HEARTBEAT)) { if (0 != (daemon_type & ZBX_DAEMON_TYPE_SERVER)) recv_proxy_heartbeat(sock, &jp); } else if (0 == strcmp(value, ZBX_PROTO_VALUE_GET_ACTIVE_CHECKS)) { ret = send_list_of_active_checks_json(sock, &jp); } else if (0 == strcmp(value, ZBX_PROTO_VALUE_HOST_AVAILABILITY)) { if (0 != (daemon_type & ZBX_DAEMON_TYPE_SERVER)) recv_host_availability(sock, &jp); else if (0 != (daemon_type & ZBX_DAEMON_TYPE_PROXY_PASSIVE)) send_host_availability(sock); } else if (0 == strcmp(value, ZBX_PROTO_VALUE_COMMAND)) { ret = node_process_command(sock, s, &jp); } else { zabbix_log(LOG_LEVEL_WARNING, "Unknown request received [%s]", value); } } return ret; } /* XML protocol? */ else if (*s == '<') { comms_parse_response(s, av.host_name, sizeof(av.host_name), av.key, sizeof(av.key), value_dec, sizeof(value_dec), lastlogsize, sizeof(lastlogsize), timestamp, sizeof(timestamp), source, sizeof(source), severity, sizeof(severity)); av.value = value_dec; av.lastlogsize = atoi(lastlogsize); av.timestamp = atoi(timestamp); av.source = source; av.severity = atoi(severity); } else { pl = s; if (NULL == (pr = strchr(pl, ':'))) return FAIL; *pr = '\0'; zbx_strlcpy(av.host_name, pl, sizeof(av.host_name)); *pr = ':'; pl = pr + 1; if (NULL == (pr = strchr(pl, ':'))) return FAIL; *pr = '\0'; zbx_strlcpy(av.key, pl, sizeof(av.key)); *pr = ':'; av.value = pr + 1; av.severity = 0; } av.clock = time(NULL); process_mass_data(sock, 0, &av, 1, NULL); alarm(CONFIG_TIMEOUT); if (SUCCEED != zbx_tcp_send_raw(sock, SUCCEED == ret ? "OK" : "NOT OK")) { zabbix_log(LOG_LEVEL_WARNING, "Error sending result back"); zabbix_syslog("Trapper: error sending result back"); } alarm(0); } return ret; }
/****************************************************************************** * * * Function: * * * * Purpose: * * * * Parameters: * * * * Return value: * * * * Comments: * * * ******************************************************************************/ char *evaluate_jobnetrun(zbx_sock_t * sock, struct zbx_json_parse *jp, int *ret) { DB_RESULT result; DB_ROW row; struct zbx_json_parse jp_row; struct zbx_json_parse jp_row2; char *message = NULL; char value[MAX_STRING_LEN]; const char *p; const char *p2; const char *p3 = NULL; int version; int res; int i; int count; zbx_uint64_t inner_jobnet_id; static JOBARG_EXEC_REQUEST er; init_exec_request(&er); if (SUCCEED == zbx_json_value_by_name(jp, JA_PROTO_TAG_VERSION, value, sizeof(value))) { version = atoi(value); if (version != JA_PROTO_VALUE_VERSION_1) { ja_log("JATRAPPER200027", 0, NULL, 0, JA_PROTO_VALUE_VERSION_1); *ret = FAIL; return zbx_dsprintf(message, "Received message error: [version] is not correct."); } } else { ja_log("JATRAPPER200028", 0, NULL, 0); *ret = FAIL; return zbx_dsprintf(message, "Received message error: [version] not found"); } if (NULL == (p = zbx_json_pair_by_name(jp, JA_PROTO_TAG_DATA))) { ja_log("JATRAPPER200021", 0, NULL, 0); *ret = FAIL; return zbx_dsprintf(message, "Received message error: [data] not found"); } else { if (FAIL == (*ret = zbx_json_brackets_open(p, &jp_row))) { ja_log("JATRAPPER200022", 0, NULL, 0); *ret = FAIL; return zbx_dsprintf(message, "Received message error: Cannot open [data] object"); } else { if (SUCCEED == zbx_json_value_by_name(&jp_row, JA_PROTO_TAG_USERNAME, value, sizeof(value))) { er.username = strdup(value); } else { ja_log("JATRAPPER200032", 0, NULL, 0); *ret = FAIL; return zbx_dsprintf(message, "Received message error: [username] not found"); } if (SUCCEED == zbx_json_value_by_name(&jp_row, JA_PROTO_TAG_PASSWORD, value, sizeof(value))) { er.password = strdup(value); } else { ja_log("JATRAPPER200033", 0, NULL, 0); zbx_free(er.username); *ret = FAIL; return zbx_dsprintf(message, "Received message error: [password] not found"); } if (SUCCEED == zbx_json_value_by_name(&jp_row, JA_PROTO_TAG_JOBNETID, value, sizeof(value))) { er.jobnetid = strdup(value); } else { ja_log("JATRAPPER200034", 0, NULL, 0); zbx_free(er.username); zbx_free(er.password); *ret = FAIL; return zbx_dsprintf(message, "Received message error: [jobnetid] not found"); } if (SUCCEED == zbx_json_value_by_name(&jp_row, JA_PROTO_TAG_STARTTIME, value, sizeof(value))) { er.starttime = strdup(value); res = time_passed_check(er.starttime); if (res == FAIL) { zbx_free(er.username); zbx_free(er.password); zbx_free(er.jobnetid); zbx_free(er.starttime); *ret = FAIL; return zbx_dsprintf(message, "Received message error: [start_time] already passed."); } } i = 0; if (NULL != (p2 = zbx_json_pair_by_name(&jp_row, JA_PROTO_TAG_ENV))) { if (FAIL == (*ret = zbx_json_brackets_open(p2, &jp_row2))) { ja_log("JATRAPPER200051", 0, er.jobnetid, 0); zbx_free(er.username); zbx_free(er.password); zbx_free(er.jobnetid); zbx_free(er.starttime); *ret = FAIL; return zbx_dsprintf(message, "Received message error: Cannot open [env] object"); } else { while (NULL != (p3 = zbx_json_pair_next(&jp_row2, p3, value, sizeof(value)))) { er.env[i] = strdup(value); zbx_json_value_by_name(&jp_row2, er.env[i], value, sizeof(value)); er.value[i] = strdup(value); i++; } er.env[i] = '\0'; } } if (SUCCEED == zbx_json_value_by_name(&jp_row, JA_PROTO_TAG_DETERRENCE, value, sizeof(value))) { er.deterrence = atoi(value); } if (SUCCEED == (job_exec_auth(er))) { DBbegin(); /* double check start-up suppression time specified */ if (er.starttime != NULL && er.deterrence == 1) { result = DBselect("select count(*) from ja_run_jobnet_table" " where scheduled_time = %s and jobnet_id = '%s' and run_type = %d", er.starttime, er.jobnetid, JA_JOBNET_RUN_TYPE_SCHEDULED); if (NULL == (row = DBfetch(result))) { zbx_snprintf(msgwork, sizeof(msgwork), "%s %s %d", er.starttime, er.jobnetid, JA_JOBNET_RUN_TYPE_SCHEDULED); ja_log("JATRAPPER200057", 0, er.jobnetid, 0, "ja_run_jobnet_table", msgwork); DBfree_result(result); DBrollback(); clean_exec_request(&er, i); *ret = FAIL; return zbx_dsprintf(message, "ja_run_jobnet_table select error."); } count = atoi(row[0]); DBfree_result(result); if (count > 0) { DBrollback(); clean_exec_request(&er, i); *ret = FAIL; return zbx_dsprintf(message, "Received message error: Double registration detection of time starting jobnet."); } } if (SUCCEED == (register_db_table(er, &inner_jobnet_id, i))) { DBcommit(); clean_exec_request(&er, i); return zbx_dsprintf(message, "Registry number : [" ZBX_FS_UI64 "]", inner_jobnet_id); } else { DBrollback(); clean_exec_request(&er, i); *ret = FAIL; return zbx_dsprintf(message, "ja_run_jobnet_table insert error."); } } else { clean_exec_request(&er, i); *ret = FAIL; return zbx_dsprintf(message, "Authentication failure."); } } } }
/****************************************************************************** * * * Function: parse_list_of_checks * * * * Purpose: Parse list of active checks received from server * * * * Parameters: str - NULL terminated string received from server * * * * Return value: returns SUCCEED on succesfull parsing, * * FAIL on an incoorrect format of string * * * * Author: Eugene Grigorjev, Alexei Vladishev (new json protocol) * * * * Comments: * * String reprents as "ZBX_EOF" termination list * * With '\n' delimeter between elements. * * Each element represents as: * * <key>:<refresh time>:<last log size> * * * ******************************************************************************/ static int parse_list_of_checks(char *str) { const char *p; char name[MAX_STRING_LEN], key_orig[MAX_STRING_LEN], expression[MAX_STRING_LEN], tmp[MAX_STRING_LEN], exp_delimiter; int delay, lastlogsize, expression_type, case_sensitive; struct zbx_json_parse jp; struct zbx_json_parse jp_data, jp_row; zabbix_log(LOG_LEVEL_DEBUG, "In parse_list_of_checks()"); disable_all_metrics(); if (SUCCEED != zbx_json_open(str, &jp)) goto json_error; if (SUCCEED != zbx_json_value_by_name(&jp, ZBX_PROTO_TAG_RESPONSE, tmp, sizeof(tmp))) goto json_error; if (0 != strcmp(tmp, ZBX_PROTO_VALUE_SUCCESS)) { zabbix_log(LOG_LEVEL_ERR, "Unsucesfull response received from server"); return FAIL; } if (SUCCEED != zbx_json_brackets_by_name(&jp, ZBX_PROTO_TAG_DATA, &jp_data)) goto json_error; p = NULL; while (NULL != (p = zbx_json_next(&jp_data, p))) { /* {"data":[{"key":"system.cpu.num",...,...},{...},...]} * ^------------------------------^ */ if (SUCCEED != zbx_json_brackets_open(p, &jp_row)) goto json_error; if (SUCCEED != zbx_json_value_by_name(&jp_row, ZBX_PROTO_TAG_KEY, name, sizeof(name)) || *name == '\0') { zabbix_log(LOG_LEVEL_WARNING, "Unable to retrieve value of tag \"%s\"", ZBX_PROTO_TAG_KEY); continue; } if (SUCCEED != zbx_json_value_by_name(&jp_row, ZBX_PROTO_TAG_KEY_ORIG, key_orig, sizeof(key_orig)) || *key_orig == '\0') zbx_strlcpy(key_orig, name, sizeof(key_orig)); if (SUCCEED != zbx_json_value_by_name(&jp_row, ZBX_PROTO_TAG_DELAY, tmp, sizeof(tmp)) || *tmp == '\0') { zabbix_log(LOG_LEVEL_WARNING, "Unable to retrieve value of tag \"%s\"", ZBX_PROTO_TAG_DELAY); continue; } delay = atoi(tmp); if (SUCCEED != zbx_json_value_by_name(&jp_row, ZBX_PROTO_TAG_LOGLASTSIZE, tmp, sizeof(tmp)) || *tmp == '\0') { zabbix_log(LOG_LEVEL_WARNING, "Unable to retrieve value of tag \"%s\"", ZBX_PROTO_TAG_LOGLASTSIZE); continue; } lastlogsize = atoi(tmp); add_check(name, key_orig, delay, lastlogsize); } clean_regexps_ex(regexps, ®exps_num); if (SUCCEED == zbx_json_brackets_by_name(&jp, ZBX_PROTO_TAG_REGEXP, &jp_data)) { p = NULL; while (NULL != (p = zbx_json_next(&jp_data, p))) { /* {"regexp":[{"name":"regexp1",...,...},{...},...]} * ^------------------------^ */ if (SUCCEED != zbx_json_brackets_open(p, &jp_row)) goto json_error; if (SUCCEED != zbx_json_value_by_name(&jp_row, "name", name, sizeof(name))) { zabbix_log(LOG_LEVEL_WARNING, "Unable to retrieve value of tag \"%s\"", "name"); continue; } if (SUCCEED != zbx_json_value_by_name(&jp_row, "expression", expression, sizeof(expression)) || *expression == '\0') { zabbix_log(LOG_LEVEL_WARNING, "Unable to retrieve value of tag \"%s\"", "expression"); continue; } if (SUCCEED != zbx_json_value_by_name(&jp_row, "expression_type", tmp, sizeof(tmp)) || *tmp == '\0') { zabbix_log(LOG_LEVEL_WARNING, "Unable to retrieve value of tag \"%s\"", "expression_type"); continue; } expression_type = atoi(tmp); if (SUCCEED != zbx_json_value_by_name(&jp_row, "exp_delimiter", tmp, sizeof(tmp))) { zabbix_log(LOG_LEVEL_WARNING, "Unable to retrieve value of tag \"%s\"", "exp_delimiter"); continue; } exp_delimiter = tmp[0]; if (SUCCEED != zbx_json_value_by_name(&jp_row, "case_sensitive", tmp, sizeof(tmp)) || *tmp == '\0') { zabbix_log(LOG_LEVEL_WARNING, "Unable to retrieve value of tag \"%s\"", "case_sensitive"); continue; } case_sensitive = atoi(tmp); add_regexp_ex(®exps, ®exps_alloc, ®exps_num, name, expression, expression_type, exp_delimiter, case_sensitive); } } return SUCCEED; json_error: zabbix_log(LOG_LEVEL_ERR, "Can't parse list of active checks. %s", zbx_json_strerror()); return FAIL; }
/****************************************************************************** * * * Function: * * * * Purpose: * * * * Parameters: * * * * Return value: * * * * Comments: * * * ******************************************************************************/ char *evaluate_jobnetstatusrq(zbx_sock_t * sock, struct zbx_json_parse *jp, int *ret, JOBARG_JOBNET_INFO * ji) { struct zbx_json_parse jp_row; char *message = NULL; char value[MAX_STRING_LEN]; const char *p; int version; zbx_uint64_t registrynumber; static JOBARG_EXEC_REQUEST er; init_exec_request(&er); if (SUCCEED == zbx_json_value_by_name(jp, JA_PROTO_TAG_VERSION, value, sizeof(value))) { version = atoi(value); if (version != JA_PROTO_VALUE_VERSION_1) { ja_log("JATRAPPER200027", 0, NULL, 0, JA_PROTO_VALUE_VERSION_1); *ret = FAIL; return zbx_dsprintf(message, "Received message error: [version] is not correct."); } } else { ja_log("JATRAPPER200028", 0, NULL, 0); *ret = FAIL; return zbx_dsprintf(message, "Received message error: [version] not found"); } if (NULL == (p = zbx_json_pair_by_name(jp, JA_PROTO_TAG_DATA))) { ja_log("JATRAPPER200029", 0, NULL, 0); *ret = FAIL; return zbx_dsprintf(message, "Received message error: [data] not found"); } else { if (FAIL == (*ret = zbx_json_brackets_open(p, &jp_row))) { ja_log("JATRAPPER200030", 0, NULL, 0); *ret = FAIL; return zbx_dsprintf(message, "Received message error: Cannot open [data] object"); } else { if (SUCCEED == zbx_json_value_by_name(&jp_row, JA_PROTO_TAG_USERNAME, value, sizeof(value))) { er.username = strdup(value); } else { ja_log("JATRAPPER200032", 0, NULL, 0); *ret = FAIL; return zbx_dsprintf(message, "Received message error: [username] not found"); } if (SUCCEED == zbx_json_value_by_name(&jp_row, JA_PROTO_TAG_PASSWORD, value, sizeof(value))) { er.password = strdup(value); } else { ja_log("JATRAPPER200033", 0, NULL, 0); zbx_free(er.username); *ret = FAIL; return zbx_dsprintf(message, "Received message error: [password] not found"); } if (SUCCEED == zbx_json_value_by_name(&jp_row, JA_PROTO_TAG_REGISTRYNUMBER, value, sizeof(value))) { ZBX_STR2UINT64(registrynumber, value); } else { ja_log("JATRAPPER200052", 0, NULL, 0); zbx_free(er.username); zbx_free(er.password); *ret = FAIL; return zbx_dsprintf(message, "Received message error: [registrynumber] not found"); } if (SUCCEED != get_jobnet_info(registrynumber, &er, ji)) { zbx_free(er.username); zbx_free(er.password); *ret = FAIL; return zbx_dsprintf(message, "jobnet specified by the registry number is not found"); } if (SUCCEED == (job_exec_auth(er))) { zbx_free(er.username); zbx_free(er.password); *ret = SUCCEED; return zbx_dsprintf(message, "OK."); } else { zbx_free(er.username); zbx_free(er.password); *ret = FAIL; return zbx_dsprintf(message, "Authentication failure."); } } } }
/****************************************************************************** * * * 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 succesfully * * FAIL - an error occured * * * * Author: Aleksander Vladishev * * * * Comments: * * * ******************************************************************************/ int send_list_of_active_checks_json(zbx_sock_t *sock, struct zbx_json_parse *jp) { char host[HOST_HOST_LEN_MAX], *name_esc, params[MAX_STRING_LEN], pattern[MAX_STRING_LEN], tmp[32]; DB_RESULT result; DB_ROW row; DB_ITEM item; struct zbx_json json; int res = FAIL; zbx_uint64_t hostid; char error[MAX_STRING_LEN]; char **regexp = NULL; int regexp_alloc = 32; int regexp_num = 0, n; char *sql = NULL; int sql_alloc = 2048; int sql_offset; zabbix_log(LOG_LEVEL_DEBUG, "In send_list_of_active_checks_json()"); 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 out; } if (FAIL == get_hostid_by_host(host, &hostid, error)) goto out; regexp = zbx_malloc(regexp, regexp_alloc); sql = zbx_malloc(sql, sql_alloc); name_esc = DBdyn_escape_string(host); sql_offset = 0; zbx_snprintf_alloc(&sql, &sql_alloc, &sql_offset, 1024, "select %s where i.hostid=h.hostid and h.status=%d and i.type=%d and h.hostid=" ZBX_FS_UI64 " and h.proxy_hostid=0", ZBX_SQL_ITEM_SELECT, HOST_STATUS_MONITORED, ITEM_TYPE_ZABBIX_ACTIVE, hostid); if (0 != CONFIG_REFRESH_UNSUPPORTED) zbx_snprintf_alloc(&sql, &sql_alloc, &sql_offset, 256, " and (i.status=%d or (i.status=%d and i.nextcheck<=%d))", ITEM_STATUS_ACTIVE, ITEM_STATUS_NOTSUPPORTED, time(NULL)); else zbx_snprintf_alloc(&sql, &sql_alloc, &sql_offset, 256, " and i.status=%d", ITEM_STATUS_ACTIVE); zbx_free(name_esc); 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); result = DBselect("%s", sql); while (NULL != (row = DBfetch(result))) { DBget_item_from_db(&item, row); zbx_json_addobject(&json, NULL); zbx_json_addstring(&json, ZBX_PROTO_TAG_KEY, item.key, ZBX_JSON_TYPE_STRING); if (0 != strcmp(item.key, item.key_orig)) zbx_json_addstring(&json, ZBX_PROTO_TAG_KEY_ORIG, item.key_orig, ZBX_JSON_TYPE_STRING); zbx_snprintf(tmp, sizeof(tmp), "%d", item.delay); zbx_json_addstring(&json, ZBX_PROTO_TAG_DELAY, tmp, ZBX_JSON_TYPE_STRING); zbx_snprintf(tmp, sizeof(tmp), "%d", item.lastlogsize); zbx_json_addstring(&json, ZBX_PROTO_TAG_LOGLASTSIZE, tmp, ZBX_JSON_TYPE_STRING); zbx_json_close(&json); /* Special processing for log[] and eventlog[] items */ do { /* simple try realization */ if (0 != strncmp(item.key, "log[", 4) && 0 != strncmp(item.key, "eventlog[", 9)) break; if (2 != parse_command(item.key, NULL, 0, params, MAX_STRING_LEN)) break;; if (0 != get_param(params, 2, pattern, sizeof(pattern))) break; if (*pattern != '@') break; for (n = 0; n < regexp_num; n++) if (0 == strcmp(regexp[n], pattern + 1)) break; if (n != regexp_num) break; if (regexp_num == regexp_alloc) { regexp_alloc += 32; regexp = zbx_realloc(regexp, regexp_alloc); } regexp[regexp_num++] = strdup(pattern + 1); } while (0); /* simple try realization */ } zbx_json_close(&json); DBfree_result(result); if (0 != regexp_num) { zbx_json_addarray(&json, ZBX_PROTO_TAG_REGEXP); sql_offset = 0; zbx_snprintf_alloc(&sql, &sql_alloc, &sql_offset, 512, "select r.name,e.expression,e.expression_type,e.exp_delimiter,e.case_sensitive" " from regexps r,expressions e where r.regexpid=e.regexpid and r.name in ("); for (n = 0; n < regexp_num; n++) { name_esc = DBdyn_escape_string(regexp[n]); zbx_snprintf_alloc(&sql, &sql_alloc, &sql_offset, 512, "%s'%s'", n == 0 ? "" : ",", name_esc); zbx_free(name_esc); zbx_free(regexp[n]); } zbx_snprintf_alloc(&sql, &sql_alloc, &sql_offset, 8, ")"); result = DBselect("%s", sql); while (NULL != (row = DBfetch(result))) { zbx_json_addobject(&json, NULL); zbx_json_addstring(&json, "name", row[0], ZBX_JSON_TYPE_STRING); zbx_json_addstring(&json, "expression", row[1], ZBX_JSON_TYPE_STRING); zbx_json_addstring(&json, "expression_type", row[2], ZBX_JSON_TYPE_INT); zbx_json_addstring(&json, "exp_delimiter", row[3], ZBX_JSON_TYPE_STRING); zbx_json_addstring(&json, "case_sensitive", row[4], ZBX_JSON_TYPE_INT); zbx_json_close(&json); } DBfree_result(result); } zbx_free(regexp); zabbix_log(LOG_LEVEL_DEBUG, "Sending [%s]", json.buffer); if (SUCCEED != zbx_tcp_send_raw(sock, json.buffer)) zbx_snprintf(error, MAX_STRING_LEN, "%s", zbx_tcp_strerror()); else res = SUCCEED; zbx_json_free(&json); zbx_free(sql); out: if (FAIL == res) zabbix_log(LOG_LEVEL_WARNING, "Send list of active checks to [%s] failed: %s", get_ip_by_socket(sock), error); return res; }
/****************************************************************************** * * * 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_sock_t *sock, struct zbx_json_parse *jp) { char host[HOST_HOST_LEN_MAX], *name_esc, params[MAX_STRING_LEN], pattern[MAX_STRING_LEN], tmp[32], key_severity[MAX_STRING_LEN], key_logeventid[MAX_STRING_LEN]; DB_RESULT result; DB_ROW row; DB_ITEM item; struct zbx_json json; int res = FAIL; zbx_uint64_t hostid; char error[MAX_STRING_LEN]; DC_ITEM dc_item; char **regexp = NULL; int regexp_alloc = 0; int regexp_num = 0, n; char *sql = NULL; int sql_alloc = 2048; int sql_offset; zabbix_log(LOG_LEVEL_DEBUG, "In send_list_of_active_checks_json()"); 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; } if (FAIL == get_hostid_by_host(host, &hostid, error)) goto error; sql = zbx_malloc(sql, sql_alloc); name_esc = DBdyn_escape_string(host); sql_offset = 0; zbx_snprintf_alloc(&sql, &sql_alloc, &sql_offset, 1024, "select %s where i.hostid=h.hostid and h.status=%d and i.type=%d and h.hostid=" ZBX_FS_UI64 " and h.proxy_hostid=0", ZBX_SQL_ITEM_SELECT, HOST_STATUS_MONITORED, ITEM_TYPE_ZABBIX_ACTIVE, hostid); if (0 != CONFIG_REFRESH_UNSUPPORTED) zbx_snprintf_alloc(&sql, &sql_alloc, &sql_offset, 256, " and (i.status=%d or (i.status=%d and i.lastclock+%d<=%d))", ITEM_STATUS_ACTIVE, ITEM_STATUS_NOTSUPPORTED, CONFIG_REFRESH_UNSUPPORTED, time(NULL)); else zbx_snprintf_alloc(&sql, &sql_alloc, &sql_offset, 256, " and i.status=%d", ITEM_STATUS_ACTIVE); zbx_free(name_esc); 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); result = DBselect("%s", sql); while (NULL != (row = DBfetch(result))) { if (FAIL == DCconfig_get_item_by_key(&dc_item, (zbx_uint64_t)0, host, row[1])) { zabbix_log(LOG_LEVEL_DEBUG, "Item '%s' was not found in the server cache. Not sending now.", row[1]); continue; } zabbix_log(LOG_LEVEL_DEBUG, "Item '%s' was successfully found in the server cache. Sending.", row[1]); DBget_item_from_db(&item, row); zbx_json_addobject(&json, NULL); zbx_json_addstring(&json, ZBX_PROTO_TAG_KEY, item.key, ZBX_JSON_TYPE_STRING); if (0 != strcmp(item.key, item.key_orig)) zbx_json_addstring(&json, ZBX_PROTO_TAG_KEY_ORIG, item.key_orig, ZBX_JSON_TYPE_STRING); zbx_snprintf(tmp, sizeof(tmp), "%d", item.delay); zbx_json_addstring(&json, ZBX_PROTO_TAG_DELAY, tmp, ZBX_JSON_TYPE_STRING); /* The agent expects ALWAYS to have lastlogsize and mtime tags. Removing those would cause older agents to fail. */ zbx_snprintf(tmp, sizeof(tmp), "%d", item.lastlogsize); zbx_json_addstring(&json, ZBX_PROTO_TAG_LOGLASTSIZE, tmp, ZBX_JSON_TYPE_STRING); zbx_snprintf(tmp, sizeof(tmp), "%d", item.mtime); zbx_json_addstring(&json, ZBX_PROTO_TAG_MTIME, tmp, ZBX_JSON_TYPE_STRING); zbx_json_close(&json); /* Special processing for log[] and logrt[] items */ do { /* simple try realization */ /* log[filename,pattern,encoding,maxlinespersec] */ /* logrt[filename_format,pattern,encoding,maxlinespersec] */ if (0 != strncmp(item.key, "log[", 4) && 0 != strncmp(item.key, "logrt[", 6)) break; if (2 != parse_command(item.key, NULL, 0, params, MAX_STRING_LEN)) break; /*dealing with `pattern' parameter*/ if (0 == get_param(params, 2, pattern, sizeof(pattern)) && *pattern == '@') add_regexp_name(®exp, ®exp_alloc, ®exp_num, pattern + 1); } while (0); /* simple try realization */ /* Special processing for eventlog[] items */ do { /* simple try realization */ /* eventlog[filename,pattern,severity,source,logeventid,maxlinespersec] */ if (0 != strncmp(item.key, "eventlog[", 9)) break; if (2 != parse_command(item.key, NULL, 0, params, MAX_STRING_LEN)) break; /*dealing with `pattern' parameter*/ if (0 == get_param(params, 2, pattern, sizeof(pattern)) && *pattern == '@') add_regexp_name(®exp, ®exp_alloc, ®exp_num, pattern + 1); /*dealing with `severity' parameter*/ if (0 == get_param(params, 3, key_severity, sizeof(key_severity)) && *key_severity == '@') add_regexp_name(®exp, ®exp_alloc, ®exp_num, key_severity + 1); /*dealing with `logeventid' parameter*/ if (0 == get_param(params, 5, key_logeventid, sizeof(key_logeventid)) && *key_logeventid == '@') add_regexp_name(®exp, ®exp_alloc, ®exp_num, key_logeventid + 1); } while (0); /* simple try realization */ } zbx_json_close(&json); DBfree_result(result); if (0 != regexp_num) { zbx_json_addarray(&json, ZBX_PROTO_TAG_REGEXP); sql_offset = 0; zbx_snprintf_alloc(&sql, &sql_alloc, &sql_offset, 512, "select r.name,e.expression,e.expression_type,e.exp_delimiter,e.case_sensitive" " from regexps r,expressions e where r.regexpid=e.regexpid and r.name in ("); for (n = 0; n < regexp_num; n++) { name_esc = DBdyn_escape_string(regexp[n]); zbx_snprintf_alloc(&sql, &sql_alloc, &sql_offset, 512, "%s'%s'", n == 0 ? "" : ",", name_esc); zbx_free(name_esc); zbx_free(regexp[n]); } zbx_snprintf_alloc(&sql, &sql_alloc, &sql_offset, 8, ")"); result = DBselect("%s", sql); while (NULL != (row = DBfetch(result))) { zbx_json_addobject(&json, NULL); zbx_json_addstring(&json, "name", row[0], ZBX_JSON_TYPE_STRING); zbx_json_addstring(&json, "expression", row[1], ZBX_JSON_TYPE_STRING); zbx_json_addstring(&json, "expression_type", row[2], ZBX_JSON_TYPE_INT); zbx_json_addstring(&json, "exp_delimiter", row[3], ZBX_JSON_TYPE_STRING); zbx_json_addstring(&json, "case_sensitive", row[4], ZBX_JSON_TYPE_INT); zbx_json_close(&json); } DBfree_result(result); } zbx_free(regexp); zabbix_log(LOG_LEVEL_DEBUG, "Sending [%s]", json.buffer); alarm(CONFIG_TIMEOUT); if (SUCCEED != zbx_tcp_send(sock, json.buffer)) zbx_snprintf(error, MAX_STRING_LEN, "%s", zbx_tcp_strerror()); else res = SUCCEED; alarm(0); zbx_json_free(&json); zbx_free(sql); return res; error: //zabbix_log(LOG_LEVEL_WARNING, "Sending list of active checks to [%s] failed: %s", // get_ip_by_socket(sock), 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, "Sending [%s]", json.buffer); res = zbx_tcp_send(sock, json.buffer); zbx_json_free(&json); return res; }