static int variant_to_ui64(zbx_variant_t *value) { zbx_uint64_t value_ui64; char buffer[MAX_STRING_LEN]; switch (value->type) { case ZBX_VARIANT_UI64: return SUCCEED; case ZBX_VARIANT_DBL: if (0 > value->data.dbl) return FAIL; zbx_variant_set_ui64(value, value->data.dbl); return SUCCEED; case ZBX_VARIANT_STR: zbx_strlcpy(buffer, value->data.str, sizeof(buffer)); break; default: return FAIL; } zbx_rtrim(buffer, "\n\r"); /* trim newline for historical reasons / backwards compatibility */ zbx_trim_integer(buffer); del_zeros(buffer); if (SUCCEED != is_uint64(buffer, &value_ui64)) return FAIL; zbx_variant_clear(value); zbx_variant_set_ui64(value, value_ui64); return SUCCEED; }
int zbx_variant_set_numeric(zbx_variant_t *value, const char *text) { zbx_uint64_t value_ui64; char buffer[MAX_STRING_LEN]; zbx_strlcpy(buffer, text, sizeof(buffer)); zbx_rtrim(buffer, "\n\r"); /* trim newline for historical reasons / backwards compatibility */ zbx_trim_integer(buffer); del_zeros(buffer); if ('+' == buffer[0]) { /* zbx_trim_integer() stripped one '+' sign, so there's more than one '+' sign in the 'text' argument */ return FAIL; } if (SUCCEED == is_uint64(buffer, &value_ui64)) { zbx_variant_set_ui64(value, value_ui64); return SUCCEED; } if (SUCCEED == is_double(buffer)) { zbx_variant_set_dbl(value, atof(buffer)); return SUCCEED; } return FAIL; }
int WEB_PAGE_GET(const char *cmd, const char *param, unsigned flags, AGENT_RESULT *result) { char hostname[MAX_STRING_LEN]; char path[MAX_STRING_LEN]; char port_str[8]; char buffer[MAX_BUFFER_LEN]; if (num_param(param) > 3) return SYSINFO_RET_FAIL; if (0 != get_param(param, 1, hostname, sizeof(hostname))) return SYSINFO_RET_FAIL; if (0 != get_param(param, 2, path, sizeof(path))) *path = '\0'; if (0 != get_param(param, 3, port_str, sizeof(port_str)) || '\0' == *port_str) zbx_snprintf(port_str, sizeof(port_str), "%d", ZBX_DEFAULT_HTTP_PORT); else if (FAIL == is_uint(port_str)) return SYSINFO_RET_FAIL; if (SYSINFO_RET_OK == get_http_page(hostname, path, (unsigned short)atoi(port_str), buffer, sizeof(buffer))) { zbx_rtrim(buffer, "\r\n"); SET_TEXT_RESULT(result, strdup(buffer)); } else SET_TEXT_RESULT(result, strdup("EOF")); return SYSINFO_RET_OK; }
static int variant_to_dbl(zbx_variant_t *value) { char buffer[MAX_STRING_LEN]; double value_dbl; switch (value->type) { case ZBX_VARIANT_DBL: return SUCCEED; case ZBX_VARIANT_UI64: zbx_variant_set_dbl(value, (double)value->data.ui64); return SUCCEED; case ZBX_VARIANT_STR: zbx_strlcpy(buffer, value->data.str, sizeof(buffer)); break; default: return FAIL; } zbx_rtrim(buffer, "\n\r"); /* trim newline for historical reasons / backwards compatibility */ zbx_trim_float(buffer); if (SUCCEED != is_double(buffer)) return FAIL; value_dbl = atof(buffer); zbx_variant_clear(value); zbx_variant_set_dbl(value, value_dbl); return SUCCEED; }
int EXECUTE_STR(const char *command, AGENT_RESULT *result) { int ret = SYSINFO_RET_FAIL; char *cmd_result = NULL, error[MAX_STRING_LEN]; assert(result); init_result(result); if (SUCCEED != zbx_execute(command, &cmd_result, error, sizeof(error), CONFIG_TIMEOUT)) { SET_MSG_RESULT(result, zbx_strdup(NULL, error)); goto lbl_exit; } zbx_rtrim(cmd_result, ZBX_WHITESPACE); zabbix_log(LOG_LEVEL_DEBUG, "Run remote command [%s] Result [%d] [%.20s]...", command, strlen(cmd_result), cmd_result); if ('\0' == *cmd_result) /* we got whitespace only */ goto lbl_exit; SET_TEXT_RESULT(result, zbx_strdup(NULL, cmd_result)); ret = SYSINFO_RET_OK; lbl_exit: zbx_free(cmd_result); return ret; }
static void process_listener(zbx_sock_t *s) { AGENT_RESULT result; char *command; char **value = NULL; int ret; if (SUCCEED == (ret = zbx_tcp_recv_to(s, &command, CONFIG_TIMEOUT))) { zbx_rtrim(command, "\r\n"); zabbix_log(LOG_LEVEL_DEBUG, "Requested [%s]", command); init_result(&result); process(command, 0, &result); if (NULL == (value = GET_TEXT_RESULT(&result))) value = GET_MSG_RESULT(&result); if (NULL != value) { zabbix_log(LOG_LEVEL_DEBUG, "Sending back [%s]", *value); ret = zbx_tcp_send_to(s, *value, CONFIG_TIMEOUT); } free_result(&result); } if (FAIL == ret) zabbix_log(LOG_LEVEL_DEBUG, "Process listener error: %s", zbx_tcp_strerror()); }
int SYSTEM_SW_OS(const char *cmd, const char *param, unsigned flags, AGENT_RESULT *result) { char type[8], line[MAX_STRING_LEN]; int ret = SYSINFO_RET_FAIL; FILE *f = NULL; if (1 < num_param(param)) return ret; if (0 != get_param(param, 1, type, sizeof(type))) *type = '\0'; if ('\0' == *type || 0 == strcmp(type, "full")) f = fopen(SW_OS_FULL, "r"); else if (0 == strcmp(type, "short")) f = fopen(SW_OS_SHORT, "r"); else if (0 == strcmp(type, "name")) f = fopen(SW_OS_NAME, "r"); if (NULL == f) return ret; if (NULL != fgets(line, sizeof(line), f)) { ret = SYSINFO_RET_OK; zbx_rtrim(line, ZBX_WHITESPACE); SET_STR_RESULT(result, zbx_strdup(NULL, line)); } zbx_fclose(f); 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; }
static void process_listener(zbx_socket_t *s) { AGENT_RESULT result; char **value = NULL; int ret; if (SUCCEED == (ret = zbx_tcp_recv_to(s, CONFIG_TIMEOUT))) { zbx_rtrim(s->buffer, "\r\n"); zabbix_log(LOG_LEVEL_DEBUG, "Requested [%s]", s->buffer); init_result(&result); if (SUCCEED == process(s->buffer, PROCESS_WITH_ALIAS, &result)) { if (NULL != (value = GET_TEXT_RESULT(&result))) { zabbix_log(LOG_LEVEL_DEBUG, "Sending back [%s]", *value); ret = zbx_tcp_send_to(s, *value, CONFIG_TIMEOUT); } } else { value = GET_MSG_RESULT(&result); if (NULL != value) { static char *buffer = NULL; static size_t buffer_alloc = 256; size_t buffer_offset = 0; zabbix_log(LOG_LEVEL_DEBUG, "Sending back [" ZBX_NOTSUPPORTED ": %s]", *value); if (NULL == buffer) buffer = (char *)zbx_malloc(buffer, buffer_alloc); zbx_strncpy_alloc(&buffer, &buffer_alloc, &buffer_offset, ZBX_NOTSUPPORTED, ZBX_CONST_STRLEN(ZBX_NOTSUPPORTED)); buffer_offset++; zbx_strcpy_alloc(&buffer, &buffer_alloc, &buffer_offset, *value); ret = zbx_tcp_send_bytes_to(s, buffer, buffer_offset, CONFIG_TIMEOUT); } else { zabbix_log(LOG_LEVEL_DEBUG, "Sending back [" ZBX_NOTSUPPORTED "]"); ret = zbx_tcp_send_to(s, ZBX_NOTSUPPORTED, CONFIG_TIMEOUT); } } free_result(&result); } if (FAIL == ret) zabbix_log(LOG_LEVEL_DEBUG, "Process listener error: %s", zbx_socket_strerror()); }
static zbx_uint64_t *get_result_ui64_value(AGENT_RESULT *result) { zbx_uint64_t value; assert(result); if (0 != ISSET_UI64(result)) { /* nothing to do */ } else if (0 != ISSET_DBL(result)) { SET_UI64_RESULT(result, result->dbl); } else if (0 != ISSET_STR(result)) { zbx_rtrim(result->str, " \""); zbx_ltrim(result->str, " \"+"); del_zeroes(result->str); if (SUCCEED != is_uint64(result->str, &value)) return NULL; SET_UI64_RESULT(result, value); } else if (0 != ISSET_TEXT(result)) { zbx_rtrim(result->text, " \""); zbx_ltrim(result->text, " \"+"); del_zeroes(result->text); if (SUCCEED != is_uint64(result->text, &value)) return NULL; SET_UI64_RESULT(result, value); } /* skip AR_MESSAGE - it is information field */ if (0 != ISSET_UI64(result)) return &result->ui64; return NULL; }
static double *get_result_dbl_value(AGENT_RESULT *result) { double value; assert(result); if (0 != ISSET_DBL(result)) { /* nothing to do */ } else if (0 != ISSET_UI64(result)) { SET_DBL_RESULT(result, result->ui64); } else if (0 != ISSET_STR(result)) { zbx_rtrim(result->str, " \""); zbx_ltrim(result->str, " \"+"); if (SUCCEED != is_double(result->str)) return NULL; value = atof(result->str); SET_DBL_RESULT(result, value); } else if (0 != ISSET_TEXT(result)) { zbx_rtrim(result->text, " \""); zbx_ltrim(result->text, " \"+"); if (SUCCEED != is_double(result->text)) return NULL; value = atof(result->text); SET_DBL_RESULT(result, value); } /* skip AR_MESSAGE - it is information field */ if (0 != ISSET_DBL(result)) return &result->dbl; return NULL; }
/****************************************************************************** * * * Function: process_log * * * * Purpose: Get message from logfile WITHOUT rotation * * * * Parameters: filename - logfile name * * lastlogsize - offset for message * * value - pointer for logged message * * * * Return value: returns SUCCEED on successful reading, * * FAIL on other cases * * * * Author: Eugene Grigorjev * * * * Comments: * * This function allocates memory for 'value', because use zbx_free. * * Return SUCCEED and NULL value if end of file received. * * * ******************************************************************************/ int process_log(char *filename, long *lastlogsize, char **value, const char *encoding) { int f; struct stat buf; int nbytes, ret = FAIL; char buffer[MAX_BUFFER_LEN]; assert(filename); assert(lastlogsize); assert(value); assert(encoding); zabbix_log(LOG_LEVEL_DEBUG, "In process_log() filename:'%s' lastlogsize:%li", filename, *lastlogsize); /* handling of file shrinking */ if (0 != zbx_stat(filename, &buf)) { zabbix_log(LOG_LEVEL_WARNING, "cannot stat [%s]: %s", filename, zbx_strerror(errno)); return ret; } if (buf.st_size < *lastlogsize) *lastlogsize = 0; if (-1 == (f = zbx_open(filename, O_RDONLY))) { zabbix_log(LOG_LEVEL_WARNING, "cannot open [%s]: %s", filename, zbx_strerror(errno)); return ret; } if ((off_t)-1 != lseek(f, (off_t)*lastlogsize, SEEK_SET)) { if (-1 != (nbytes = zbx_read(f, buffer, sizeof(buffer), encoding))) { if (0 != nbytes) { *lastlogsize += nbytes; *value = convert_to_utf8(buffer, nbytes, encoding); zbx_rtrim(*value, "\r\n "); } ret = SUCCEED; } else zabbix_log(LOG_LEVEL_WARNING, "cannot read from [%s]: %s", filename, zbx_strerror(errno)); } else zabbix_log(LOG_LEVEL_WARNING, "cannot set position to [%li] for [%s]: %s", *lastlogsize, filename, zbx_strerror(errno)); close(f); return ret; }
int zbx_module_unifi_proxy(AGENT_REQUEST *request, AGENT_RESULT *result) { int ret; int i, p, np; zbx_sock_t s; char send_buf[MAX_STRING_LEN]; *send_buf='\0'; np = request->nparam; if (9 < request->nparam) { /* set optional error message */ SET_MSG_RESULT(result, strdup("So much parameters given.")); return SYSINFO_RET_FAIL; } // make request string by concatenate all params for (i=0; i < np; i++) { strcat(send_buf, get_rparam(request, i)); p=strlen(send_buf); send_buf[p]=(i < (np-1)) ? ',' : '\n'; send_buf[p+1]='\0'; } // Connect to UniFi Proxy // item_timeout or (item_timeout-1) ? if (SUCCEED == (ret = zbx_tcp_connect(&s, CONFIG_SOURCE_IP, UNIFI_PROXY_SERVER, UNIFI_PROXY_PORT, CONFIG_TIMEOUT))) { // Send request if (SUCCEED == (ret = zbx_tcp_send_raw(&s, send_buf))) { // Recive answer from UniFi Proxy if (SUCCEED == (ret = zbx_tcp_recv(&s))) { zbx_rtrim(s.buffer, "\r\n"); SET_STR_RESULT(result, strdup(s.buffer)); } } zbx_tcp_close(&s); } if (FAIL == ret) { zabbix_log(LOG_LEVEL_DEBUG, "%s: communication error: %s", ZBX_MODULE_NAME, zbx_tcp_strerror()); SET_MSG_RESULT(result, strdup(zbx_tcp_strerror())); return SYSINFO_RET_FAIL; } return SYSINFO_RET_OK; }
static char *snmp_get_octet_string(struct variable_list *vars) { const char *__function_name = "snmp_get_octet_string"; static char buf[MAX_STRING_LEN]; const char *hint; char *strval_dyn = NULL, is_hex = 0; size_t offset = 0; struct tree *subtree; zabbix_log(LOG_LEVEL_DEBUG, "In %s()", __function_name); /* find the subtree to get display hint */ subtree = get_tree(vars->name, vars->name_length, get_tree_head()); hint = subtree ? subtree->hint : NULL; /* we will decide if we want the value from vars->val or what snprint_value() returned later */ if (-1 == snprint_value(buf, sizeof(buf), vars->name, vars->name_length, vars)) goto end; zabbix_log(LOG_LEVEL_DEBUG, "%s() full value:'%s'", __function_name, buf); /* decide if it's Hex, offset will be possibly needed later */ if (0 == strncmp(buf, "Hex-STRING: ", 12)) { is_hex = 1; offset = 12; } /* in case of no hex and no display hint take the value from */ /* vars->val, it contains unquoted and unescaped string */ if (0 == is_hex && NULL == hint) { strval_dyn = zbx_malloc(strval_dyn, vars->val_len + 1); memcpy(strval_dyn, vars->val.string, vars->val_len); strval_dyn[vars->val_len] = '\0'; } else { if (0 == is_hex && 0 == strncmp(buf, "STRING: ", 8)) offset = 8; strval_dyn = zbx_strdup(strval_dyn, buf + offset); } zbx_rtrim(strval_dyn, ZBX_WHITESPACE); zbx_ltrim(strval_dyn, ZBX_WHITESPACE); end: zabbix_log(LOG_LEVEL_DEBUG, "End of %s():'%s'", __function_name, strval_dyn ? strval_dyn : "(null)"); return strval_dyn; }
/****************************************************************************** * * * Function: * * * * Purpose: * * * * Parameters: * * * * Return value: * * * * Comments: * * * ******************************************************************************/ int ja_tcp_recv_to(zbx_sock_t * s, ja_job_object * job, int timeout) { int ret, cnt=0; char *data; const char *__function_name = "ja_tcp_recv_to"; zabbix_log(LOG_LEVEL_DEBUG, "In %s()", __function_name); // 2016/01/07 Park.iggy ADD /* ORG ret = zbx_tcp_recv_to(s, &data, timeout); if (ret == FAIL) { zbx_snprintf(job->message, sizeof(job->message), "%s", zbx_tcp_strerror()); goto error; } */ while((ret = zbx_tcp_recv_to(s, &data, timeout+15)) == FAIL){ if(cnt >= 1) break; cnt++; } if (ret == FAIL) { zbx_snprintf(job->message, sizeof(job->message), "%s", zbx_tcp_strerror()); goto error; } //Park.iggy END zabbix_log(LOG_LEVEL_DEBUG, "In %s() %s", __function_name, data); if (strlen(data) == 0) { zbx_snprintf(job->message, sizeof(job->message), "received data is null"); goto error; } zbx_rtrim(data, "\r\n"); ret = ja_telegram_from(data, job); error: if (ret == FAIL) { zabbix_log(LOG_LEVEL_ERR, "In %s() message: %s", __function_name, job->message); } return ret; }
ZBX_ODBC_ROW odbc_DBfetch(ZBX_ODBC_RESULT pdbh) { const char *__function_name = "odbc_DBfetch"; SQLRETURN retcode; SQLSMALLINT i; ZBX_ODBC_ROW result_row = NULL; zabbix_log(LOG_LEVEL_DEBUG, "In %s()", __function_name); clean_odbc_strerror(); if (NULL == pdbh) { set_last_odbc_strerror("cannot fetch row on an empty connection handle"); goto end; } if (SQL_NO_DATA == (retcode = SQLFetch(pdbh->hstmt))) { /* end of rows */ goto end; } if (SQL_SUCCESS != retcode && 0 == odbc_Diag(SQL_HANDLE_STMT, pdbh->hstmt, retcode, "cannot fetch row")) goto end; for (i = 0; i < pdbh->col_num; i++) { /* set NULL column value where appropriate */ if (SQL_NULL_DATA == pdbh->data_len[i]) zbx_free(pdbh->row_data[i]); else zbx_rtrim(pdbh->row_data[i], " "); zabbix_log(LOG_LEVEL_DEBUG, "%s() fetched [%i col]: '%s'", __function_name, i, NULL == pdbh->row_data[i] ? "NULL" : pdbh->row_data[i]); } result_row = pdbh->row_data; end: zabbix_log(LOG_LEVEL_DEBUG, "End of %s()", __function_name); return result_row; }
static int cmp_status(FILE *f_stat, const char *procname) { char tmp[MAX_STRING_LEN]; rewind(f_stat); while (NULL != fgets(tmp, sizeof(tmp), f_stat)) { if (0 != strncmp(tmp, "Name:\t", 6)) continue; zbx_rtrim(tmp + 6, "\n"); if (0 == strcmp(tmp + 6, procname)) return SUCCEED; break; } return FAIL; }
static int get_procname(FILE *f_stat, char **line) { char tmp[MAX_STRING_LEN]; rewind(f_stat); while (NULL != fgets(tmp, sizeof(tmp), f_stat)) { if (0 != strncmp(tmp, "Name:\t", 6)) continue; zbx_rtrim(tmp + 6, "\n"); *line = zbx_strdup(*line, tmp + 6); return SUCCEED; } return FAIL; }
/****************************************************************************** * * * Function: zbx_format_message * * * * Purpose: extracts the specified message from a message file * * * * Parameters: hLib - [IN] the message file handle * * dwMessageId - [IN] the message identifier * * pInsertStrings - [IN] a list of insert strings, optional * * * * Return value: The formatted message converted to utf8 or NULL * * * * Comments: This function allocates memory for the returned message, which * * must be freed by the caller later. * * * ******************************************************************************/ static char *zbx_format_message(HINSTANCE hLib, DWORD dwMessageId, wchar_t **pInsertStrings) { wchar_t *pMsgBuf = NULL; char *message; if (0 == FormatMessage(FORMAT_MESSAGE_FROM_HMODULE | FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_ARGUMENT_ARRAY | FORMAT_MESSAGE_MAX_WIDTH_MASK, hLib, dwMessageId, MAKELANGID(LANG_NEUTRAL, SUBLANG_ENGLISH_US), (wchar_t *)&pMsgBuf, 0, (va_list *)pInsertStrings)) { return NULL; } message = zbx_unicode_to_utf8(pMsgBuf); zbx_rtrim(message, "\r\n "); LocalFree((HLOCAL)pMsgBuf); return message; }
static const char *zbx_oci_error(sword status) { static char errbuf[512]; sb4 errcode = 0; errbuf[0] = '\0'; switch (status) { case OCI_SUCCESS_WITH_INFO: OCIErrorGet((dvoid *)oracle.errhp, (ub4)1, (text *)NULL, &errcode, (text *)errbuf, (ub4)sizeof(errbuf), OCI_HTYPE_ERROR); break; case OCI_NEED_DATA: zbx_snprintf(errbuf, sizeof(errbuf), "%s", "OCI_NEED_DATA"); break; case OCI_NO_DATA: zbx_snprintf(errbuf, sizeof(errbuf), "%s", "OCI_NODATA"); break; case OCI_ERROR: OCIErrorGet((dvoid *)oracle.errhp, (ub4)1, (text *)NULL, &errcode, (text *)errbuf, (ub4)sizeof(errbuf), OCI_HTYPE_ERROR); break; case OCI_INVALID_HANDLE: zbx_snprintf(errbuf, sizeof(errbuf), "%s", "OCI_INVALID_HANDLE"); break; case OCI_STILL_EXECUTING: zbx_snprintf(errbuf, sizeof(errbuf), "%s", "OCI_STILL_EXECUTING"); break; case OCI_CONTINUE: zbx_snprintf(errbuf, sizeof(errbuf), "%s", "OCI_CONTINUE"); break; } zbx_rtrim(errbuf, ZBX_WHITESPACE); return errbuf; }
/****************************************************************************** * * * Function: read_traps * * * * Purpose: read the traps and then parse them with parse_traps() * * * * Author: Rudolfs Kreicbergs * * * ******************************************************************************/ static void read_traps() { const char *__function_name = "read_traps"; int nbytes; char buffer[MAX_BUFFER_LEN]; zabbix_log(LOG_LEVEL_DEBUG, "In %s() lastsize:%d", __function_name, trap_lastsize); *buffer = '\0'; if ((off_t)-1 == lseek(trap_fd, (off_t)trap_lastsize, SEEK_SET)) { zabbix_log(LOG_LEVEL_WARNING, "cannot set position to [%d] for [%s]: %s", trap_lastsize, CONFIG_SNMPTRAP_FILE, zbx_strerror(errno)); goto exit; } if (-1 == (nbytes = read(trap_fd, buffer, sizeof(buffer) - 1))) { zabbix_log(LOG_LEVEL_WARNING, "cannot read from [%s]: %s", CONFIG_SNMPTRAP_FILE, zbx_strerror(errno)); goto exit; } if (0 < nbytes) { buffer[nbytes] = '\0'; zbx_rtrim(buffer + MAX(nbytes - 3, 0), " \r\n"); trap_lastsize += nbytes; DBupdate_lastsize(); parse_traps(buffer); } exit: zabbix_log(LOG_LEVEL_DEBUG, "End of %s()", __function_name); }
static int process_ping(ZBX_FPING_HOST *hosts, int hosts_count, int count, int interval, int size, int timeout, char *error, int max_error_len) { const char *__function_name = "process_ping"; FILE *f; char *c, *c2, params[64]; char filename[MAX_STRING_LEN], tmp[MAX_STRING_LEN]; int i; ZBX_FPING_HOST *host; double sec; int ret = NOTSUPPORTED; #ifdef HAVE_IPV6 int family; char params6[64]; char fping_existence = 0; #define FPING_EXISTS 0x1 #define FPING6_EXISTS 0x2 #endif /* HAVE_IPV6 */ assert(hosts); zabbix_log(LOG_LEVEL_DEBUG, "In %s() hosts_count:%d", __function_name, hosts_count); if (-1 == access(CONFIG_FPING_LOCATION, F_OK | X_OK)) { #if !defined(HAVE_IPV6) zbx_snprintf(error, max_error_len, "%s: %s", CONFIG_FPING_LOCATION, zbx_strerror(errno)); return ret; #endif } else { #ifdef HAVE_IPV6 fping_existence |= FPING_EXISTS; #else if (NULL != CONFIG_SOURCE_IP) { if (FAIL == is_ip4(CONFIG_SOURCE_IP)) /* we do not have IPv4 family address in CONFIG_SOURCE_IP */ { zbx_snprintf(error, max_error_len, "You should enable IPv6 support to use IPv6 family address for SourceIP '%s'.", CONFIG_SOURCE_IP); return ret; } } #endif } #ifdef HAVE_IPV6 if (-1 == access(CONFIG_FPING6_LOCATION, F_OK | X_OK)) { if (0 == (fping_existence & FPING_EXISTS)) { zbx_snprintf(error, max_error_len, "At least one of '%s', '%s' must exist. Both are missing in the system.", CONFIG_FPING_LOCATION, CONFIG_FPING6_LOCATION); return ret; } } else fping_existence |= FPING6_EXISTS; #endif /* HAVE_IPV6 */ i = zbx_snprintf(params, sizeof(params), "-q -C%d", count); if (0 != interval) i += zbx_snprintf(params + i, sizeof(params) - i, " -p%d", interval); if (0 != size) i += zbx_snprintf(params + i, sizeof(params) - i, " -b%d", size); if (0 != timeout) i += zbx_snprintf(params + i, sizeof(params) - i, " -t%d", timeout); #ifdef HAVE_IPV6 strscpy(params6, params); #endif /* HAVE_IPV6 */ if (NULL != CONFIG_SOURCE_IP) { #ifdef HAVE_IPV6 if (0 != (fping_existence & FPING_EXISTS)) { if (0 == source_ip_checked) get_source_ip_option(CONFIG_FPING_LOCATION, &source_ip_option, &source_ip_checked); if (NULL != source_ip_option) zbx_snprintf(params + i, sizeof(params) - i, " %s%s", source_ip_option, CONFIG_SOURCE_IP); } if (0 != (fping_existence & FPING6_EXISTS)) { if (0 == source_ip6_checked) get_source_ip_option(CONFIG_FPING6_LOCATION, &source_ip6_option, &source_ip6_checked); if (NULL != source_ip6_option) zbx_snprintf(params6 + i, sizeof(params6) - i, " %s%s", source_ip6_option, CONFIG_SOURCE_IP); } #else if (0 == source_ip_checked) get_source_ip_option(CONFIG_FPING_LOCATION, &source_ip_option, &source_ip_checked); if (NULL != source_ip_option) zbx_snprintf(params + i, sizeof(params) - i, " %s%s", source_ip_option, CONFIG_SOURCE_IP); #endif /* HAVE_IPV6 */ } zbx_snprintf(filename, sizeof(filename), "%s/%s_%li.pinger", CONFIG_TMPDIR, progname, zbx_get_thread_id()); #ifdef HAVE_IPV6 if (NULL != CONFIG_SOURCE_IP) { if (SUCCEED != get_address_family(CONFIG_SOURCE_IP, &family, error, max_error_len)) return ret; if (family == PF_INET) { if (0 == (fping_existence & FPING_EXISTS)) { zbx_snprintf(error, max_error_len, "File '%s' cannot be found in the system.", CONFIG_FPING_LOCATION); return ret; } zbx_snprintf(tmp, sizeof(tmp), "%s %s 2>&1 <%s", CONFIG_FPING_LOCATION, params, filename); } else { if (0 == (fping_existence & FPING6_EXISTS)) { zbx_snprintf(error, max_error_len, "File '%s' cannot be found in the system.", CONFIG_FPING6_LOCATION); return ret; } zbx_snprintf(tmp, sizeof(tmp), "%s %s 2>&1 <%s", CONFIG_FPING6_LOCATION, params6, filename); } } else { i = 0; if (0 != (fping_existence & FPING_EXISTS)) i += zbx_snprintf(tmp + i, sizeof(tmp) - i, "%s %s 2>&1 <%s;", CONFIG_FPING_LOCATION, params, filename); if (0 != (fping_existence & FPING6_EXISTS)) i += zbx_snprintf(tmp + i, sizeof(tmp) - i, "%s %s 2>&1 <%s;", CONFIG_FPING6_LOCATION, params6, filename); } #else zbx_snprintf(tmp, sizeof(tmp), "%s %s 2>&1 <%s", CONFIG_FPING_LOCATION, params, filename); #endif /* HAVE_IPV6 */ if (NULL == (f = fopen(filename, "w"))) { zbx_snprintf(error, max_error_len, "%s: %s", filename, zbx_strerror(errno)); return ret; } zabbix_log(LOG_LEVEL_DEBUG, "%s", filename); for (i = 0; i < hosts_count; i++) { zabbix_log(LOG_LEVEL_DEBUG, "%s", hosts[i].addr); fprintf(f, "%s\n", hosts[i].addr); } fclose(f); zabbix_log(LOG_LEVEL_DEBUG, "%s", tmp); if (NULL == (f = popen(tmp, "r"))) { zbx_snprintf(error, max_error_len, "%s: %s", tmp, zbx_strerror(errno)); unlink(filename); return ret; } if (NULL == fgets(tmp, sizeof(tmp), f)) { ret = SUCCEED; /* fping does not output anything for DNS names that fail to resolve */ } else { do { zbx_rtrim(tmp, "\n"); zabbix_log(LOG_LEVEL_DEBUG, "read line [%s]", tmp); host = NULL; if (NULL != (c = strchr(tmp, ' '))) { *c = '\0'; for (i = 0; i < hosts_count; i++) if (0 == strcmp(tmp, hosts[i].addr)) { host = &hosts[i]; break; } *c = ' '; } if (NULL == host) continue; if (NULL == (c = strstr(tmp, " : "))) continue; /* when NIC bonding is used, there are also lines like */ /* 192.168.1.2 : duplicate for [0], 96 bytes, 0.19 ms */ if (NULL != strstr(tmp, "duplicate for")) continue; c += 3; do { if (NULL != (c2 = strchr(c, ' '))) *c2 = '\0'; if (0 != strcmp(c, "-")) { sec = atof(c) / 1000; /* convert ms to seconds */ if (host->rcv == 0 || host->min > sec) host->min = sec; if (host->rcv == 0 || host->max < sec) host->max = sec; host->avg = (host->avg * host->rcv + sec) / (host->rcv + 1); host->rcv++; } host->cnt++; if (NULL != c2) *c2++ = ' '; } while (NULL != (c = c2)); ret = SUCCEED; } while (NULL != fgets(tmp, sizeof(tmp), f)); } pclose(f); unlink(filename); if (NOTSUPPORTED == ret) zbx_snprintf(error, max_error_len, "fping failed: \"%s\"", tmp); zabbix_log(LOG_LEVEL_DEBUG, "End of %s()", __function_name); return ret; }
static int process_ping(ZBX_FPING_HOST *hosts, int hosts_count, char *error, int max_error_len) { FILE *f; char filename[MAX_STRING_LEN], tmp[MAX_STRING_LEN], *c, source_ip[64]; int i; ZBX_FPING_HOST *host; #ifdef HAVE_IPV6 char *fping; int family; #endif assert(hosts); zabbix_log(LOG_LEVEL_DEBUG, "In process_ping()"); if (NULL != CONFIG_SOURCE_IP) zbx_snprintf(source_ip, sizeof(source_ip), "-S%s ", CONFIG_SOURCE_IP); else *source_ip = '\0'; if (access(CONFIG_FPING_LOCATION, F_OK|X_OK) == -1) { zbx_snprintf(error, max_error_len, "%s: [%d] %s", CONFIG_FPING_LOCATION, errno, strerror(errno)); return NOTSUPPORTED; } zbx_snprintf(filename, sizeof(filename), "%s/zabbix_server_%li.pinger", CONFIG_TMPDIR, zbx_get_thread_id()); #ifdef HAVE_IPV6 if (access(CONFIG_FPING6_LOCATION, F_OK|X_OK) == -1) { zbx_snprintf(error, max_error_len, "%s: [%d] %s", CONFIG_FPING6_LOCATION, errno, strerror(errno)); return NOTSUPPORTED; } if (NULL != CONFIG_SOURCE_IP) { if (NOTSUPPORTED == get_address_family(CONFIG_SOURCE_IP, &family, error, max_error_len)) return NOTSUPPORTED; if (family == PF_INET) fping = CONFIG_FPING_LOCATION; else fping = CONFIG_FPING6_LOCATION; zbx_snprintf(tmp, sizeof(tmp), "%s %s-c3 2>/dev/null <%s", fping, source_ip, filename); } else zbx_snprintf(tmp, sizeof(tmp), "%s -c3 2>/dev/null <%s;%s -c3 2>/dev/null <%s", CONFIG_FPING_LOCATION, filename, CONFIG_FPING6_LOCATION, filename); #else /* HAVE_IPV6 */ zbx_snprintf(tmp, sizeof(tmp), "%s %s-c3 2>/dev/null <%s", CONFIG_FPING_LOCATION, source_ip, filename); #endif /* HAVE_IPV6 */ if (NULL == (f = fopen(filename, "w"))) { zbx_snprintf(error, max_error_len, "%s: [%d] %s", filename, errno, strerror(errno)); return NOTSUPPORTED; } zabbix_log(LOG_LEVEL_DEBUG, "%s", filename); for (i = 0; i < hosts_count; i++) { zabbix_log(LOG_LEVEL_DEBUG, "%s", hosts[i].addr); fprintf(f, "%s\n", hosts[i].addr); } fclose(f); zabbix_log(LOG_LEVEL_DEBUG, "%s", tmp); if (0 == (f = popen(tmp, "r"))) { zbx_snprintf(error, max_error_len, "%s: [%d] %s", tmp, errno, strerror(errno)); unlink(filename); return NOTSUPPORTED; } while (NULL != fgets(tmp, sizeof(tmp), f)) { zbx_rtrim(tmp, "\n"); zabbix_log(LOG_LEVEL_DEBUG, "Update IP [%s]", tmp); /* 12fc::21 : [0], 76 bytes, 0.39 ms (0.39 avg, 0% loss) */ host = NULL; if (NULL != (c = strchr(tmp, ' '))) { *c = '\0'; for (i = 0; i < hosts_count; i++) if (0 == strcmp(tmp, hosts[i].addr)) { host = &hosts[i]; break; } } if (NULL != host) { c++; if (NULL != (c = strchr(c, '('))) { c++; host->alive = 1; host->sec = atof(c)/1000; } } } pclose(f); unlink(filename); zabbix_log(LOG_LEVEL_DEBUG, "End of process_ping()"); return SUCCEED; }
int main(int argc, char **argv) { FILE *in; char in_line[MAX_BUFFER_LEN], hostname[MAX_STRING_LEN], key[MAX_STRING_LEN], key_value[MAX_BUFFER_LEN], clock[32]; int total_count = 0, succeed_count = 0, buffer_count = 0, read_more = 0, ret = SUCCEED; double last_send = 0; const char *p; zbx_thread_args_t thread_args; ZBX_THREAD_SENDVAL_ARGS sentdval_args; progname = get_program_name(argv[0]); parse_commandline(argc, argv); zbx_load_config(CONFIG_FILE); zabbix_open_log(LOG_TYPE_UNDEFINED, CONFIG_LOG_LEVEL, NULL); if (NULL == ZABBIX_SERVER) { zabbix_log(LOG_LEVEL_WARNING, "'Server' parameter required"); goto exit; } if (0 == ZABBIX_SERVER_PORT) ZABBIX_SERVER_PORT = ZBX_DEFAULT_SERVER_PORT; if (MIN_ZABBIX_PORT > ZABBIX_SERVER_PORT) { zabbix_log(LOG_LEVEL_WARNING, "Incorrect port number [%d]. Allowed [%d:%d]", (int)ZABBIX_SERVER_PORT, (int)MIN_ZABBIX_PORT, (int)MAX_ZABBIX_PORT); goto exit; } thread_args.thread_num = 0; thread_args.args = &sentdval_args; sentdval_args.server = ZABBIX_SERVER; sentdval_args.port = ZABBIX_SERVER_PORT; zbx_json_init(&sentdval_args.json, ZBX_JSON_STAT_BUF_LEN); zbx_json_addstring(&sentdval_args.json, ZBX_PROTO_TAG_REQUEST, ZBX_PROTO_VALUE_SENDER_DATA, ZBX_JSON_TYPE_STRING); zbx_json_addarray(&sentdval_args.json, ZBX_PROTO_TAG_DATA); if (INPUT_FILE) { if (0 == strcmp(INPUT_FILE, "-")) { in = stdin; if (1 == REAL_TIME) { /* set line buffering on stdin */ setvbuf(stdin, (char *)NULL, _IOLBF, 0); } } else if (NULL == (in = fopen(INPUT_FILE, "r")) ) { zabbix_log(LOG_LEVEL_WARNING, "cannot open [%s]: %s", INPUT_FILE, zbx_strerror(errno)); ret = FAIL; goto exit; } while (NULL != fgets(in_line, sizeof(in_line), in) && SUCCEED == ret) /* <hostname> <key> [<timestamp>] <value> */ { total_count++; /* also used as inputline */ zbx_rtrim(in_line, "\r\n"); p = in_line; if ('\0' == *p || NULL == (p = get_string(p, hostname, sizeof(hostname))) || '\0' == *hostname) { zabbix_log(LOG_LEVEL_WARNING, "[line %d] 'Hostname' required", total_count); continue; } if (0 == strcmp(hostname, "-")) { if (NULL == ZABBIX_HOSTNAME) { zabbix_log(LOG_LEVEL_WARNING, "[line %d] '-' encountered as 'Hostname', " "but no default hostname was specified", total_count); continue; } else zbx_strlcpy(hostname, ZABBIX_HOSTNAME, sizeof(hostname)); } if ('\0' == *p || NULL == (p = get_string(p, key, sizeof(key))) || '\0' == *key) { zabbix_log(LOG_LEVEL_WARNING, "[line %d] 'Key' required", total_count); continue; } if (1 == WITH_TIMESTAMPS) { if ('\0' == *p || NULL == (p = get_string(p, clock, sizeof(clock))) || '\0' == *clock) { zabbix_log(LOG_LEVEL_WARNING, "[line %d] 'Timestamp' required", total_count); continue; } } if ('\0' != *p && '"' != *p) zbx_strlcpy(key_value, p, sizeof(key_value)); else if ('\0' == *p || NULL == (p = get_string(p, key_value, sizeof(key_value))) || '\0' == *key_value) { zabbix_log(LOG_LEVEL_WARNING, "[line %d] 'Key value' required", total_count); continue; } zbx_rtrim(key_value, "\r\n"); zbx_json_addobject(&sentdval_args.json, NULL); zbx_json_addstring(&sentdval_args.json, ZBX_PROTO_TAG_HOST, hostname, ZBX_JSON_TYPE_STRING); zbx_json_addstring(&sentdval_args.json, ZBX_PROTO_TAG_KEY, key, ZBX_JSON_TYPE_STRING); zbx_json_addstring(&sentdval_args.json, ZBX_PROTO_TAG_VALUE, key_value, ZBX_JSON_TYPE_STRING); if (1 == WITH_TIMESTAMPS) zbx_json_adduint64(&sentdval_args.json, ZBX_PROTO_TAG_CLOCK, atoi(clock)); zbx_json_close(&sentdval_args.json); succeed_count++; buffer_count++; if (stdin == in && 1 == REAL_TIME) { /* if there is nothing on standard input after 1/5 seconds, we send what we have */ /* otherwise, we keep reading, but we should send data at least once per second */ struct timeval tv; fd_set read_set; tv.tv_sec = 0; tv.tv_usec = 200000; FD_ZERO(&read_set); FD_SET(0, &read_set); /* stdin is file descriptor 0 */ if (-1 == (read_more = select(1, &read_set, NULL, NULL, &tv))) { zabbix_log(LOG_LEVEL_WARNING, "select() failed: %s", zbx_strerror(errno)); } else if (1 <= read_more) { if (0 == last_send) last_send = zbx_time(); else if (zbx_time() - last_send >= 1) read_more = 0; } } if (VALUES_MAX == buffer_count || (stdin == in && 1 == REAL_TIME && 0 >= read_more)) { zbx_json_close(&sentdval_args.json); if (1 == WITH_TIMESTAMPS) zbx_json_adduint64(&sentdval_args.json, ZBX_PROTO_TAG_CLOCK, (int)time(NULL)); last_send = zbx_time(); ret = zbx_thread_wait(zbx_thread_start(send_value, &thread_args)); buffer_count = 0; zbx_json_clean(&sentdval_args.json); zbx_json_addstring(&sentdval_args.json, ZBX_PROTO_TAG_REQUEST, ZBX_PROTO_VALUE_SENDER_DATA, ZBX_JSON_TYPE_STRING); zbx_json_addarray(&sentdval_args.json, ZBX_PROTO_TAG_DATA); } } zbx_json_close(&sentdval_args.json); if (0 != buffer_count) { if (1 == WITH_TIMESTAMPS) zbx_json_adduint64(&sentdval_args.json, ZBX_PROTO_TAG_CLOCK, (int)time(NULL)); ret = zbx_thread_wait(zbx_thread_start(send_value, &thread_args)); } if (in != stdin) fclose(in); } else { total_count++; do /* try block simulation */ { if (NULL == ZABBIX_HOSTNAME) { zabbix_log(LOG_LEVEL_WARNING, "'Hostname' parameter required"); break; } if (NULL == ZABBIX_KEY) { zabbix_log(LOG_LEVEL_WARNING, "Key required"); break; } if (NULL == ZABBIX_KEY_VALUE) { zabbix_log(LOG_LEVEL_WARNING, "Key value required"); break; } zbx_json_addobject(&sentdval_args.json, NULL); zbx_json_addstring(&sentdval_args.json, ZBX_PROTO_TAG_HOST, ZABBIX_HOSTNAME, ZBX_JSON_TYPE_STRING); zbx_json_addstring(&sentdval_args.json, ZBX_PROTO_TAG_KEY, ZABBIX_KEY, ZBX_JSON_TYPE_STRING); zbx_json_addstring(&sentdval_args.json, ZBX_PROTO_TAG_VALUE, ZABBIX_KEY_VALUE, ZBX_JSON_TYPE_STRING); zbx_json_close(&sentdval_args.json); succeed_count++; ret = zbx_thread_wait(zbx_thread_start(send_value, &thread_args)); } while(0); /* try block simulation */ } zbx_json_free(&sentdval_args.json); if (SUCCEED == ret) printf("sent: %d; skipped: %d; total: %d\n", succeed_count, (total_count - succeed_count), total_count); else printf("Sending failed. Use option -vv for more detailed output.\n"); exit: zabbix_close_log(); return ret; }
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; }
static int process_ping(ZBX_FPING_HOST *hosts, int hosts_count, int count, int interval, int size, int timeout, char *error, int max_error_len) { const char *__function_name = "process_ping"; FILE *f; char *c, params[64]; char filename[MAX_STRING_LEN], tmp[MAX_STRING_LEN]; size_t offset; ZBX_FPING_HOST *host; double sec; int i, ret = NOTSUPPORTED, index; #ifdef HAVE_IPV6 int family; char params6[64]; char fping_existence = 0; #define FPING_EXISTS 0x1 #define FPING6_EXISTS 0x2 #endif /* HAVE_IPV6 */ assert(hosts); zabbix_log(LOG_LEVEL_DEBUG, "In %s() hosts_count:%d", __function_name, hosts_count); if (-1 == access(CONFIG_FPING_LOCATION, X_OK)) { #if !defined(HAVE_IPV6) zbx_snprintf(error, max_error_len, "%s: %s", CONFIG_FPING_LOCATION, zbx_strerror(errno)); return ret; #endif } else { #ifdef HAVE_IPV6 fping_existence |= FPING_EXISTS; #else if (NULL != CONFIG_SOURCE_IP) { if (FAIL == is_ip4(CONFIG_SOURCE_IP)) /* we do not have IPv4 family address in CONFIG_SOURCE_IP */ { zbx_snprintf(error, max_error_len, "You should enable IPv6 support to use IPv6 family address for SourceIP '%s'.", CONFIG_SOURCE_IP); return ret; } } #endif } #ifdef HAVE_IPV6 if (-1 == access(CONFIG_FPING6_LOCATION, X_OK)) { if (0 == (fping_existence & FPING_EXISTS)) { zbx_snprintf(error, max_error_len, "At least one of '%s', '%s' must exist. Both are missing in the system.", CONFIG_FPING_LOCATION, CONFIG_FPING6_LOCATION); return ret; } } else fping_existence |= FPING6_EXISTS; #endif /* HAVE_IPV6 */ offset = zbx_snprintf(params, sizeof(params), "-C%d", count); if (0 != interval) offset += zbx_snprintf(params + offset, sizeof(params) - offset, " -p%d", interval); if (0 != size) offset += zbx_snprintf(params + offset, sizeof(params) - offset, " -b%d", size); if (0 != timeout) offset += zbx_snprintf(params + offset, sizeof(params) - offset, " -t%d", timeout); #ifdef HAVE_IPV6 strscpy(params6, params); #endif /* HAVE_IPV6 */ if (NULL != CONFIG_SOURCE_IP) { #ifdef HAVE_IPV6 if (0 != (fping_existence & FPING_EXISTS)) { if (0 == source_ip_checked) get_source_ip_option(CONFIG_FPING_LOCATION, &source_ip_option, &source_ip_checked); if (NULL != source_ip_option) zbx_snprintf(params + offset, sizeof(params) - offset, " %s%s", source_ip_option, CONFIG_SOURCE_IP); } if (0 != (fping_existence & FPING6_EXISTS)) { if (0 == source_ip6_checked) get_source_ip_option(CONFIG_FPING6_LOCATION, &source_ip6_option, &source_ip6_checked); if (NULL != source_ip6_option) zbx_snprintf(params6 + offset, sizeof(params6) - offset, " %s%s", source_ip6_option, CONFIG_SOURCE_IP); } #else if (0 == source_ip_checked) get_source_ip_option(CONFIG_FPING_LOCATION, &source_ip_option, &source_ip_checked); if (NULL != source_ip_option) zbx_snprintf(params + offset, sizeof(params) - offset, " %s%s", source_ip_option, CONFIG_SOURCE_IP); #endif /* HAVE_IPV6 */ } zbx_snprintf(filename, sizeof(filename), "%s/%s_%li.pinger", CONFIG_TMPDIR, progname, zbx_get_thread_id()); #ifdef HAVE_IPV6 if (NULL != CONFIG_SOURCE_IP) { if (SUCCEED != get_address_family(CONFIG_SOURCE_IP, &family, error, max_error_len)) return ret; if (family == PF_INET) { if (0 == (fping_existence & FPING_EXISTS)) { zbx_snprintf(error, max_error_len, "File '%s' cannot be found in the system.", CONFIG_FPING_LOCATION); return ret; } zbx_snprintf(tmp, sizeof(tmp), "%s %s 2>&1 <%s", CONFIG_FPING_LOCATION, params, filename); } else { if (0 == (fping_existence & FPING6_EXISTS)) { zbx_snprintf(error, max_error_len, "File '%s' cannot be found in the system.", CONFIG_FPING6_LOCATION); return ret; } zbx_snprintf(tmp, sizeof(tmp), "%s %s 2>&1 <%s", CONFIG_FPING6_LOCATION, params6, filename); } } else { offset = 0; if (0 != (fping_existence & FPING_EXISTS)) offset += zbx_snprintf(tmp + offset, sizeof(tmp) - offset, "%s %s 2>&1 <%s;", CONFIG_FPING_LOCATION, params, filename); if (0 != (fping_existence & FPING6_EXISTS)) zbx_snprintf(tmp + offset, sizeof(tmp) - offset, "%s %s 2>&1 <%s;", CONFIG_FPING6_LOCATION, params6, filename); } #else zbx_snprintf(tmp, sizeof(tmp), "%s %s 2>&1 <%s", CONFIG_FPING_LOCATION, params, filename); #endif /* HAVE_IPV6 */ if (NULL == (f = fopen(filename, "w"))) { zbx_snprintf(error, max_error_len, "%s: %s", filename, zbx_strerror(errno)); return ret; } zabbix_log(LOG_LEVEL_DEBUG, "%s", filename); for (i = 0; i < hosts_count; i++) { zabbix_log(LOG_LEVEL_DEBUG, " %s", hosts[i].addr); fprintf(f, "%s\n", hosts[i].addr); } fclose(f); zabbix_log(LOG_LEVEL_DEBUG, "%s", tmp); if (NULL == (f = popen(tmp, "r"))) { zbx_snprintf(error, max_error_len, "%s: %s", tmp, zbx_strerror(errno)); unlink(filename); return ret; } if (NULL == fgets(tmp, sizeof(tmp), f)) { ret = SUCCEED; /* fping does not output anything for DNS names that fail to resolve */ } else { for (i = 0; i < hosts_count; i++) { hosts[i].status = zbx_malloc(NULL, count); memset(hosts[i].status, 0, count); } do { zbx_rtrim(tmp, "\n"); zabbix_log(LOG_LEVEL_DEBUG, "read line [%s]", tmp); host = NULL; if (NULL != (c = strchr(tmp, ' '))) { *c = '\0'; for (i = 0; i < hosts_count; i++) if (0 == strcmp(tmp, hosts[i].addr)) { host = &hosts[i]; break; } *c = ' '; } if (NULL == host) continue; if (NULL == (c = strstr(tmp, " : "))) continue; /* when NIC bonding is used, there are also lines like */ /* 192.168.1.2 : duplicate for [0], 96 bytes, 0.19 ms */ if (NULL != strstr(tmp, "duplicate for")) continue; c += 3; /* The were two issues with processing only the fping's final status line: */ /* 1) pinging broadcast addresses could have resulted in responses from */ /* different hosts, which were counted as the target host responses; */ /* 2) there is a bug in fping (v3.8 at least) where pinging broadcast */ /* address will result in no individual responses, but the final */ /* status line might contain a bogus value. */ /* Because of the above issues we must monitor the individual responses */ /* and mark the valid ones. */ if ('[' == *c) { /* Fping appends response source address in format '[<- 10.3.0.10]' */ /* if it does not match the target address. Ignore such responses. */ if (NULL != strstr(c + 1, "[<-")) continue; /* get the index of individual ping response */ index = atoi(c + 1); if (0 > index || index >= count) continue; host->status[index] = 1; continue; } /* process status line for a host */ index = 0; do { if (1 == host->status[index]) { sec = atof(c) / 1000; /* convert ms to seconds */ if (0 == host->rcv || host->min > sec) host->min = sec; if (0 == host->rcv || host->max < sec) host->max = sec; host->avg = (host->avg * host->rcv + sec) / (host->rcv + 1); host->rcv++; } } while (++index < count && NULL != (c = strchr(c + 1, ' '))); host->cnt = count; ret = SUCCEED; } while (NULL != fgets(tmp, sizeof(tmp), f)); for (i = 0; i < hosts_count; i++) zbx_free(hosts[i].status); } pclose(f); unlink(filename); if (NOTSUPPORTED == ret) zbx_snprintf(error, max_error_len, "fping failed: \"%s\"", tmp); zabbix_log(LOG_LEVEL_DEBUG, "End of %s()", __function_name); 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; }
int EXECUTE_STR(const char *cmd, const char *param, unsigned flags, AGENT_RESULT *result) { #if defined(_WINDOWS) STARTUPINFO si = {0}; PROCESS_INFORMATION pi = {0}; SECURITY_ATTRIBUTES sa; HANDLE hWrite=NULL, hRead=NULL; #else /* not _WINDOWS */ FILE *hRead = NULL; #endif /* _WINDOWS */ int ret = SYSINFO_RET_FAIL; char stat_buf[128]; char *cmd_result=NULL; char *command=NULL; int len; assert(result); init_result(result); cmd_result = zbx_dsprintf(cmd_result,""); memset(stat_buf, 0, sizeof(stat_buf)); #if defined(_WINDOWS) /* Set the bInheritHandle flag so pipe handles are inherited */ sa.nLength = sizeof(SECURITY_ATTRIBUTES); sa.bInheritHandle = TRUE; sa.lpSecurityDescriptor = NULL; /* Create a pipe for the child process's STDOUT */ if (! CreatePipe(&hRead, &hWrite, &sa, sizeof(cmd_result))) { zabbix_log(LOG_LEVEL_DEBUG, "Unable to create pipe [%s]", strerror_from_system(GetLastError())); ret = SYSINFO_RET_FAIL; goto lbl_exit; } /* Fill in process startup info structure */ memset(&si,0,sizeof(STARTUPINFO)); si.cb = sizeof(STARTUPINFO); si.dwFlags = STARTF_USESTDHANDLES; si.hStdInput = GetStdHandle(STD_INPUT_HANDLE); si.hStdOutput = hWrite; si.hStdError = hWrite; command = zbx_dsprintf(command, "cmd /C \"%s\"", param); /* Create new process */ if (!CreateProcess(NULL,command,NULL,NULL,TRUE,0,NULL,NULL,&si,&pi)) { zabbix_log(LOG_LEVEL_DEBUG, "Unable to create process: '%s' [%s]", command, strerror_from_system(GetLastError())); ret = SYSINFO_RET_FAIL; goto lbl_exit; } CloseHandle(hWrite); hWrite = NULL; /* Read process output */ while( ReadFile(hRead, stat_buf, sizeof(stat_buf)-1, &len, NULL) && len > 0 ) { cmd_result = zbx_strdcat(cmd_result, stat_buf); memset(stat_buf, 0, sizeof(stat_buf)); } /* Don't wait child process exiting. */ /* WaitForSingleObject( pi.hProcess, INFINITE ); */ /* Terminate child process */ /* TerminateProcess(pi.hProcess, 0); */ CloseHandle(pi.hProcess); CloseHandle(pi.hThread); CloseHandle(hRead); hRead = NULL; #else /* not _WINDOWS */ command = zbx_dsprintf(command, "%s", param); if(0 == (hRead = popen(command,"r"))) { switch (errno) { case EINTR: ret = SYSINFO_RET_TIMEOUT; break; default: ret = SYSINFO_RET_FAIL; break; } goto lbl_exit; } ; /* Read process output */ while( (len = fread(stat_buf, 1, sizeof(stat_buf)-1, hRead)) > 0 ) { cmd_result = zbx_strdcat(cmd_result, stat_buf); memset(stat_buf, 0, sizeof(stat_buf)); } if(0 != ferror(hRead)) { switch (errno) { case EINTR: ret = SYSINFO_RET_TIMEOUT; break; default: ret = SYSINFO_RET_FAIL; break; } goto lbl_exit; } if(pclose(hRead) == -1) { switch (errno) { case EINTR: ret = SYSINFO_RET_TIMEOUT; break; default: ret = SYSINFO_RET_FAIL; break; } goto lbl_exit; } hRead = NULL; #endif /* _WINDOWS */ zabbix_log(LOG_LEVEL_DEBUG, "Before"); zbx_rtrim(cmd_result,"\n\r\0"); /* We got EOL only */ if(cmd_result[0] == '\0') { ret = SYSINFO_RET_FAIL; goto lbl_exit; } zabbix_log(LOG_LEVEL_DEBUG, "Run remote command [%s] Result [%d] [%.20s]...", command, strlen(cmd_result), cmd_result); SET_TEXT_RESULT(result, strdup(cmd_result)); ret = SYSINFO_RET_OK; lbl_exit: #if defined(_WINDOWS) if ( hWrite ) { CloseHandle(hWrite); hWrite = NULL; } if ( hRead) { CloseHandle(hRead); hRead = NULL; } #else /* not _WINDOWS */ if ( hRead ) { pclose(hRead); hRead = NULL; } #endif /* _WINDOWS */ zbx_free(command) zbx_free(cmd_result); return ret; }
/****************************************************************************** * * * Function: get_value_agent * * * * Purpose: retrieve data from Zabbix agent * * * * Parameters: item - item we are interested in * * * * Return value: SUCCEED - data successfully retrieved and stored in result * * and result_str (as string) * * NETWORK_ERROR - network related error occurred * * NOTSUPPORTED - item not supported by the agent * * AGENT_ERROR - uncritical error on agent side occurred * * FAIL - otherwise * * * * Author: Alexei Vladishev * * * * Comments: error will contain error message * * * ******************************************************************************/ int get_value_agent(DC_ITEM *item, AGENT_RESULT *result) { const char *__function_name = "get_value_agent"; zbx_socket_t s; char buffer[MAX_STRING_LEN]; int ret = SUCCEED; ssize_t received_len; zabbix_log(LOG_LEVEL_DEBUG, "In %s() host:'%s' addr:'%s' key:'%s'", __function_name, item->host.host, item->interface.addr, item->key); if (SUCCEED == (ret = zbx_tcp_connect(&s, CONFIG_SOURCE_IP, item->interface.addr, item->interface.port, 0))) { zbx_snprintf(buffer, sizeof(buffer), "%s\n", item->key); zabbix_log(LOG_LEVEL_DEBUG, "Sending [%s]", buffer); /* send requests using old protocol */ if (SUCCEED != zbx_tcp_send_raw(&s, buffer)) ret = NETWORK_ERROR; else if (FAIL != (received_len = zbx_tcp_recv_ext(&s, ZBX_TCP_READ_UNTIL_CLOSE, 0))) ret = SUCCEED; else ret = TIMEOUT_ERROR; } else ret = NETWORK_ERROR; if (SUCCEED == ret) { zbx_rtrim(s.buffer, " \r\n"); zbx_ltrim(s.buffer, " "); zabbix_log(LOG_LEVEL_DEBUG, "get value from agent result: '%s'", s.buffer); if (0 == strcmp(s.buffer, ZBX_NOTSUPPORTED)) { /* 'ZBX_NOTSUPPORTED\0<error message>' */ if (sizeof(ZBX_NOTSUPPORTED) < s.read_bytes) zbx_snprintf(buffer, sizeof(buffer), "%s", s.buffer + sizeof(ZBX_NOTSUPPORTED)); else zbx_snprintf(buffer, sizeof(buffer), "Not supported by Zabbix Agent"); SET_MSG_RESULT(result, strdup(buffer)); ret = NOTSUPPORTED; } else if (0 == strcmp(s.buffer, ZBX_ERROR)) { zbx_snprintf(buffer, sizeof(buffer), "Zabbix Agent non-critical error"); SET_MSG_RESULT(result, strdup(buffer)); ret = AGENT_ERROR; } else if (0 == received_len) { zbx_snprintf(buffer, sizeof(buffer), "Received empty response from Zabbix Agent at [%s]." " Assuming that agent dropped connection because of access permissions.", item->interface.addr); SET_MSG_RESULT(result, strdup(buffer)); ret = NETWORK_ERROR; } else if (SUCCEED != set_result_type(result, item->value_type, item->data_type, s.buffer)) ret = NOTSUPPORTED; } else { zbx_snprintf(buffer, sizeof(buffer), "Get value from agent failed: %s", zbx_socket_strerror()); SET_MSG_RESULT(result, strdup(buffer)); } zbx_tcp_close(&s); zabbix_log(LOG_LEVEL_DEBUG, "End of %s():%s", __function_name, zbx_result_string(ret)); return ret; }
int set_result_type(AGENT_RESULT *result, int value_type, int data_type, char *c) { int ret = FAIL; zbx_uint64_t value_uint64; double value_double; assert(result); switch (value_type) { case ITEM_VALUE_TYPE_UINT64: zbx_rtrim(c, " \""); zbx_ltrim(c, " \"+"); del_zeroes(c); switch (data_type) { case ITEM_DATA_TYPE_BOOLEAN: if (SUCCEED == is_boolean(c, &value_uint64)) { SET_UI64_RESULT(result, value_uint64); ret = SUCCEED; } break; case ITEM_DATA_TYPE_OCTAL: if (SUCCEED == is_uoct(c)) { ZBX_OCT2UINT64(value_uint64, c); SET_UI64_RESULT(result, value_uint64); ret = SUCCEED; } break; case ITEM_DATA_TYPE_DECIMAL: if (SUCCEED == is_uint64(c, &value_uint64)) { SET_UI64_RESULT(result, value_uint64); ret = SUCCEED; } break; case ITEM_DATA_TYPE_HEXADECIMAL: if (SUCCEED == is_uhex(c)) { ZBX_HEX2UINT64(value_uint64, c); SET_UI64_RESULT(result, value_uint64); ret = SUCCEED; } else if (SUCCEED == is_hex_string(c)) { zbx_remove_whitespace(c); ZBX_HEX2UINT64(value_uint64, c); SET_UI64_RESULT(result, value_uint64); ret = SUCCEED; } break; default: THIS_SHOULD_NEVER_HAPPEN; break; } break; case ITEM_VALUE_TYPE_FLOAT: zbx_rtrim(c, " \""); zbx_ltrim(c, " \"+"); if (SUCCEED != is_double(c)) break; value_double = atof(c); SET_DBL_RESULT(result, value_double); ret = SUCCEED; break; case ITEM_VALUE_TYPE_STR: zbx_replace_invalid_utf8(c); SET_STR_RESULT(result, zbx_strdup(NULL, c)); ret = SUCCEED; break; case ITEM_VALUE_TYPE_TEXT: zbx_replace_invalid_utf8(c); SET_TEXT_RESULT(result, zbx_strdup(NULL, c)); ret = SUCCEED; break; case ITEM_VALUE_TYPE_LOG: zbx_replace_invalid_utf8(c); add_log_result(result, c); ret = SUCCEED; break; } if (SUCCEED != ret) { char *error = NULL; zbx_remove_chars(c, "\r\n"); zbx_replace_invalid_utf8(c); if (ITEM_VALUE_TYPE_UINT64 == value_type) error = zbx_dsprintf(error, "Received value [%s] is not suitable for value type [%s] and data type [%s]", c, zbx_item_value_type_string(value_type), zbx_item_data_type_string(data_type)); else error = zbx_dsprintf(error, "Received value [%s] is not suitable for value type [%s]", c, zbx_item_value_type_string(value_type)); SET_MSG_RESULT(result, error); } return ret; }