/****************************************************************************** * * * Function: parse_command_dyn * * * * Purpose: parses item key and splits it into command and parameters * * * * Return value: ZBX_COMMAND_ERROR - error * * ZBX_COMMAND_WITHOUT_PARAMS - command without parameters * * ZBX_COMMAND_WITH_PARAMS - command with parameters * * * ******************************************************************************/ static int parse_command_dyn(const char *command, char **cmd, char **param) { const char *pl, *pr; size_t cmd_alloc = 0, param_alloc = 0, cmd_offset = 0, param_offset = 0; for (pl = command; SUCCEED == is_key_char(*pl); pl++) ; if (pl == command) return ZBX_COMMAND_ERROR; zbx_strncpy_alloc(cmd, &cmd_alloc, &cmd_offset, command, pl - command); if ('\0' == *pl) /* no parameters specified */ { zbx_strncpy_alloc(param, ¶m_alloc, ¶m_offset, "", 0); return ZBX_COMMAND_WITHOUT_PARAMS; } if ('[' != *pl) /* unsupported character */ return ZBX_COMMAND_ERROR; for (pr = ++pl; '\0' != *pr; pr++) ; if (']' != *--pr) return ZBX_COMMAND_ERROR; zbx_strncpy_alloc(param, ¶m_alloc, ¶m_offset, pl, pr - pl); return ZBX_COMMAND_WITH_PARAMS; }
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 int web_curl_set_url(struct web *opt) { const char *__function_name = "web_curl_set_url"; char *url = NULL; char *curl_err_str = NULL; int curl_err; size_t alloc; size_t offset; if (opt->is_https) url = zbx_strdup(url, "https://"); else url = zbx_strdup(url, "http://"); offset = strlen(url); alloc = sizeof(char) * offset + 1; if (opt->is_ip_hostname) { zbx_strncpy_alloc(&url, &alloc, &offset, opt->host, strlen(opt->host)); } else { if (opt->is_ipv6) { zbx_strncpy_alloc(&url, &alloc, &offset, "[", 1); zbx_strncpy_alloc(&url, &alloc, &offset, opt->ip, strlen(opt->ip)); zbx_strncpy_alloc(&url, &alloc, &offset, "]", 1); } else { zbx_strncpy_alloc(&url, &alloc, &offset, opt->ip, strlen(opt->ip)); } } zbx_strncpy_alloc(&url, &alloc, &offset, ":", 1); zbx_strncpy_alloc(&url, &alloc, &offset, opt->port, strlen(opt->port)); if (*opt->uri != '/') zbx_strncpy_alloc(&url, &alloc, &offset, "/", 1); zbx_strncpy_alloc(&url, &alloc, &offset, opt->uri, strlen(opt->uri)); if ((curl_err = curl_easy_setopt(opt->curl->handler, CURLOPT_URL, url))) { curl_err_str = zbx_strdup(curl_err_str, curl_easy_strerror(curl_err)); zabbix_log(LOG_LEVEL_ERR, "%s(): Could not set cURL option [%d]: %s for key %s", __function_name, CURLOPT_URL, curl_err_str, opt->item->key); zbx_free(curl_err_str); zbx_free(url); return FAIL; } zbx_free(url); return SUCCEED; }
static int web_curl_set_header(struct web *opt) { const char *__function_name = "web_curl_set_header"; char *host = NULL; char *curl_err_str = NULL; int curl_err; int i; size_t offset; size_t alloc; if (opt->host) { host = zbx_strdup(host, "Host: "); offset = strlen(host); alloc = sizeof(char) * offset + 1; zbx_strncpy_alloc(&host, &alloc, &offset, opt->host, strlen(opt->host)); if (!(opt->curl->header_lst = curl_slist_append(opt->curl->header_lst, host))) { zabbix_log(LOG_LEVEL_ERR, "%s(): Could not append to curl header list for key %s", __function_name, opt->item->key); goto failed; } } for (i = 0; i < opt->header_count; i++) { if (!(opt->curl->header_lst = curl_slist_append(opt->curl->header_lst, opt->header[i]))) { zabbix_log(LOG_LEVEL_ERR, "%s(): Could not append to curl header list for key %s", __function_name, opt->item->key); goto failed; } } if (opt->curl->header_lst) { if ((curl_err = curl_easy_setopt(opt->curl->handler, CURLOPT_HTTPHEADER, opt->curl->header_lst))) { curl_err_str = zbx_strdup(curl_err_str, curl_easy_strerror(curl_err)); zabbix_log(LOG_LEVEL_ERR, "%s(): Could not set cURL option [%d]: %s for key %s", __function_name, CURLOPT_HTTPHEADER, curl_err_str, opt->item->key); goto failed; } } zbx_free(host); return SUCCEED; failed: zbx_free(host); zbx_free(curl_err_str); return FAIL; }
static size_t web_curl_write(void *contents, size_t size, size_t nmemb, void *userp) { struct web_storage *page = (struct web_storage *)userp; size_t read_size = size * nmemb; if (!page->buff) { page->alloc = MAX(8096, read_size); page->offset = 0; page->buff = zbx_calloc(page->buff, 1, page->alloc); } zbx_strncpy_alloc(&page->buff, &page->alloc, &page->offset, contents, read_size); return read_size; }
static size_t WRITEFUNCTION2(void *ptr, size_t size, size_t nmemb, void *userdata) { size_t r_size = size * nmemb; /* first piece of data */ if (NULL == page.data) { page.allocated = MAX(8096, r_size); page.offset = 0; page.data = zbx_malloc(page.data, page.allocated); } zbx_strncpy_alloc(&page.data, &page.allocated, &page.offset, ptr, r_size); return r_size; }
static int replace_param(const char *cmd, AGENT_REQUEST *request, char **out, char *error, int max_error_len) { const char *pl = cmd, *pr, *tmp; size_t out_alloc = 0, out_offset = 0; int num, ret = SUCCEED; while (NULL != (pr = strchr(pl, '$'))) { zbx_strncpy_alloc(out, &out_alloc, &out_offset, pl, pr - pl); pr++; if ('0' == *pr) { zbx_strcpy_alloc(out, &out_alloc, &out_offset, cmd); } else if ('1' <= *pr && *pr <= '9') { num = (int)(*pr - '0'); if (request->nparam >= num) { tmp = get_rparam(request, num - 1); if (SUCCEED != (ret = zbx_check_user_parameter(tmp, error, max_error_len))) break; zbx_strcpy_alloc(out, &out_alloc, &out_offset, tmp); } } else { if ('$' != *pr) zbx_chrcpy_alloc(out, &out_alloc, &out_offset, '$'); zbx_chrcpy_alloc(out, &out_alloc, &out_offset, *pr); } pl = pr + 1; } if (SUCCEED == ret) zbx_strcpy_alloc(out, &out_alloc, &out_offset, pl); return ret; }
static int http_get_macro_value(const char *macros, const char *macro, char **replace_to, size_t *replace_to_alloc) { size_t sz_macro, replace_to_offset = 0; const char *pm, *pv, *p; int res = FAIL; sz_macro = strlen(macro); for (pm = macros; NULL != (pm = strstr(pm, macro)); pm += sz_macro) { if (pm != macros && '\r' != *(pm - 1) && '\n' != *(pm - 1)) continue; pv = pm + sz_macro; /* skip white spaces */ while (' ' == *pv || '\t' == *pv) pv++; if ('=' != *pv++) continue; /* skip white spaces */ while (' ' == *pv || '\t' == *pv) pv++; for (p = pv; '\0' != *p && '\r' != *p && '\n' != *p; p++) ; /* trim white spaces */ while (p > pv && (' ' == *(p - 1) || '\t' == *(p - 1))) p--; zbx_strncpy_alloc(replace_to, replace_to_alloc, &replace_to_offset, pv, p - pv); res = SUCCEED; break; } return res; }
/****************************************************************************** * * * Function: zbx_tcp_recv_ext * * * * Purpose: receive data * * * * Return value: number of bytes received - success, * * FAIL - an error occurred * * * * Author: Eugene Grigorjev * * * ******************************************************************************/ ssize_t zbx_tcp_recv_ext(zbx_sock_t *s, char **data, unsigned char flags, int timeout) { #define ZBX_BUF_LEN (ZBX_STAT_BUF_LEN * 8) ssize_t nbytes, left, total_bytes; size_t allocated, offset, read_bytes; zbx_uint64_t expected_len; ZBX_TCP_START(); if (0 != timeout) zbx_tcp_timeout_set(s, timeout); zbx_free(s->buf_dyn); total_bytes = 0; read_bytes = 0; s->buf_type = ZBX_BUF_TYPE_STAT; *data = s->buf_stat; left = ZBX_TCP_HEADER_LEN; if (ZBX_TCP_ERROR == (nbytes = ZBX_TCP_READ(s->socket, s->buf_stat, left))) goto out; if (ZBX_TCP_HEADER_LEN == nbytes && 0 == strncmp(s->buf_stat, ZBX_TCP_HEADER, ZBX_TCP_HEADER_LEN)) { total_bytes += nbytes; left = sizeof(zbx_uint64_t); if (left != (nbytes = ZBX_TCP_READ(s->socket, (void *)&expected_len, left))) { total_bytes = FAIL; goto out; } expected_len = zbx_letoh_uint64(expected_len); if (ZBX_MAX_RECV_DATA_SIZE < expected_len) { zabbix_log(LOG_LEVEL_WARNING, "Message size " ZBX_FS_UI64 " from %s" " exceeds the maximum size " ZBX_FS_UI64 " bytes. Message ignored.", expected_len, get_ip_by_socket(s), (zbx_uint64_t)ZBX_MAX_RECV_DATA_SIZE); total_bytes = FAIL; goto cleanup; } flags |= ZBX_TCP_READ_UNTIL_CLOSE; } else { read_bytes = nbytes; expected_len = 16 * ZBX_MEBIBYTE; } s->buf_stat[read_bytes] = '\0'; if (0 != (flags & ZBX_TCP_READ_UNTIL_CLOSE)) { if (0 == nbytes) goto cleanup; } else { if (nbytes < left) goto cleanup; } left = sizeof(s->buf_stat) - read_bytes - 1; /* check for an empty socket if exactly ZBX_TCP_HEADER_LEN bytes (without a header) were sent */ if (0 == read_bytes || '\n' != s->buf_stat[read_bytes - 1]) /* requests to passive agents end with '\n' */ { /* fill static buffer */ while (read_bytes < expected_len && 0 < left && ZBX_TCP_ERROR != (nbytes = ZBX_TCP_READ(s->socket, s->buf_stat + read_bytes, left))) { read_bytes += nbytes; if (0 != (flags & ZBX_TCP_READ_UNTIL_CLOSE)) { if (0 == nbytes) break; } else { if (nbytes < left) /* should we stop reading? */ { /* XML protocol? */ if (0 == strncmp(s->buf_stat, "<req>", sizeof("<req>") - 1)) { /* closing tag received in the last 10 bytes? */ s->buf_stat[read_bytes] = '\0'; if (NULL != strstr(s->buf_stat + read_bytes - (10 > read_bytes ? read_bytes : 10), "</req>")) break; } else break; } } left -= nbytes; } } s->buf_stat[read_bytes] = '\0'; if (sizeof(s->buf_stat) - 1 == read_bytes) /* static buffer is full */ { allocated = ZBX_BUF_LEN; s->buf_type = ZBX_BUF_TYPE_DYN; s->buf_dyn = zbx_malloc(s->buf_dyn, allocated); memcpy(s->buf_dyn, s->buf_stat, sizeof(s->buf_stat)); offset = read_bytes; /* fill dynamic buffer */ while (read_bytes < expected_len && ZBX_TCP_ERROR != (nbytes = ZBX_TCP_READ(s->socket, s->buf_stat, sizeof(s->buf_stat)))) { zbx_strncpy_alloc(&s->buf_dyn, &allocated, &offset, s->buf_stat, nbytes); read_bytes += nbytes; if (0 != (flags & ZBX_TCP_READ_UNTIL_CLOSE)) { if (0 == nbytes) break; } else { if ((size_t)nbytes < sizeof(s->buf_stat) - 1) /* should we stop reading? */ { /* XML protocol? */ if (0 == strncmp(s->buf_dyn, "<req>", sizeof("<req>") - 1)) { /* closing tag received in the last 10 bytes? */ if (NULL != strstr(s->buf_dyn + read_bytes - 10, "</req>")) break; } else break; } } } *data = s->buf_dyn; } out: if (ZBX_TCP_ERROR == nbytes) { zbx_set_tcp_strerror("ZBX_TCP_READ() failed: %s", strerror_from_system(zbx_sock_last_error())); total_bytes = FAIL; } cleanup: if (0 != timeout) zbx_tcp_timeout_cleanup(s); if (FAIL != total_bytes) total_bytes += read_bytes; return total_bytes; }
static void print_backtrace(CONTEXT *pctx) { SymGetLineFromAddrW64_func_t zbx_SymGetLineFromAddrW64 = NULL; SymFromAddr_func_t zbx_SymFromAddr = NULL; CONTEXT ctx, ctxcount; STACKFRAME64 s, scount; PSYMBOL_INFO pSym = NULL; HMODULE hModule; HANDLE hProcess, hThread; DWORD64 offset; wchar_t szProcessName[MAX_PATH]; char *process_name = NULL, *process_path = NULL, *frame = NULL; size_t frame_alloc = 0, frame_offset; int nframes = 0; ctx = *pctx; zabbix_log(LOG_LEVEL_CRIT, "=== Backtrace: ==="); memset(&s, 0, sizeof(s)); s.AddrPC.Mode = AddrModeFlat; s.AddrFrame.Mode = AddrModeFlat; s.AddrStack.Mode = AddrModeFlat; #ifdef _M_X64 s.AddrPC.Offset = ctx.Rip; s.AddrFrame.Offset = ctx.Rbp; s.AddrStack.Offset = ctx.Rsp; #else s.AddrPC.Offset = ctx.Eip; s.AddrFrame.Offset = ctx.Ebp; s.AddrStack.Offset = ctx.Esp; #endif hProcess = GetCurrentProcess(); hThread = GetCurrentThread(); if (0 != GetModuleFileNameEx(hProcess, NULL, szProcessName, ARRSIZE(szProcessName))) { char *ptr; int path_alloc = 0, path_offset = 0; process_name = zbx_unicode_to_utf8(szProcessName); if (NULL != (ptr = strstr(process_name, progname))) zbx_strncpy_alloc(&process_path, &path_alloc, &path_offset, process_name, ptr - process_name); } if (NULL != (hModule = GetModuleHandle(TEXT("DbgHelp.DLL")))) { zbx_SymGetLineFromAddrW64 = (SymGetLineFromAddrW64_func_t)GetProcAddress(hModule, "SymGetLineFromAddr64"); zbx_SymFromAddr = (SymFromAddr_func_t)GetProcAddress(hModule, "SymFromAddr"); } if (NULL != zbx_SymFromAddr || NULL != zbx_SymGetLineFromAddrW64) { SymSetOptions(SymGetOptions() | SYMOPT_LOAD_LINES); if (FALSE != SymInitialize(hProcess, process_path, TRUE)) { pSym = (PSYMBOL_INFO) zbx_malloc(NULL, sizeof(SYMBOL_INFO) + MAX_SYM_NAME); memset(pSym, 0, sizeof(SYMBOL_INFO) + MAX_SYM_NAME); pSym->SizeOfStruct = sizeof(SYMBOL_INFO); pSym->MaxNameLen = MAX_SYM_NAME; } } scount = s; ctxcount = ctx; /* get number of frames, ctxcount may be modified during StackWalk64() calls */ while (TRUE == StackWalk64(ZBX_IMAGE_FILE_MACHINE, hProcess, hThread, &scount, &ctxcount, NULL, NULL, NULL, NULL)) { if (0 == scount.AddrReturn.Offset) break; nframes++; } while (TRUE == StackWalk64(ZBX_IMAGE_FILE_MACHINE, hProcess, hThread, &s, &ctx, NULL, NULL, NULL, NULL)) { frame_offset = 0; zbx_snprintf_alloc(&frame, &frame_alloc, &frame_offset, "%d: %s", nframes--, NULL == process_name ? "(unknown)" : process_name); if (NULL != pSym) { DWORD dwDisplacement; IMAGEHLP_LINE64 line = {sizeof(IMAGEHLP_LINE64)}; zbx_chrcpy_alloc(&frame, &frame_alloc, &frame_offset, '('); if (NULL != zbx_SymFromAddr && TRUE == zbx_SymFromAddr(hProcess, s.AddrPC.Offset, &offset, pSym)) { zbx_snprintf_alloc(&frame, &frame_alloc, &frame_offset, "%s+0x%lx", pSym->Name, offset); } if (NULL != zbx_SymGetLineFromAddrW64 && TRUE == zbx_SymGetLineFromAddrW64(hProcess, s.AddrPC.Offset, &dwDisplacement, &line)) { zbx_snprintf_alloc(&frame, &frame_alloc, &frame_offset, " %s:%d", line.FileName, line.LineNumber); } zbx_chrcpy_alloc(&frame, &frame_alloc, &frame_offset, ')'); } zabbix_log(LOG_LEVEL_CRIT, "%s [0x%lx]", frame, s.AddrPC.Offset); if (0 == s.AddrReturn.Offset) break; } SymCleanup(hProcess); zbx_free(frame); zbx_free(process_path); zbx_free(process_name); zbx_free(pSym); }
static int calcitem_parse_expression(DC_ITEM *dc_item, expression_t *exp, char *error, int max_error_len) { const char *__function_name = "calcitem_parse_expression"; char *e, *f, *func = NULL, *params = NULL; size_t exp_alloc = 128, exp_offset = 0, len; int functionid, ret; zabbix_log(LOG_LEVEL_DEBUG, "In %s() expression:'%s'", __function_name, dc_item->params); assert(dc_item); assert(exp); exp->exp = zbx_malloc(exp->exp, exp_alloc); for (e = dc_item->params; '\0' != *e; e++) { if (SUCCEED != is_function_char(*e)) { zbx_chrcpy_alloc(&exp->exp, &exp_alloc, &exp_offset, *e); continue; } if ((0 == strncmp("and", e, len = 3) || 0 == strncmp("not", e, 3) || 0 == strncmp("or", e, len = 2)) && NULL != strchr("()" ZBX_WHITESPACE, e[len])) { zbx_strncpy_alloc(&exp->exp, &exp_alloc, &exp_offset, e, len); e += len - 1; continue; } f = e; if (SUCCEED != parse_function(&e, &func, ¶ms)) { e = f; zbx_chrcpy_alloc(&exp->exp, &exp_alloc, &exp_offset, *f); continue; } else e--; functionid = calcitem_add_function(exp, func, params); zabbix_log(LOG_LEVEL_DEBUG, "%s() functionid:%d function:'%s(%s)'", __function_name, functionid, func, params); func = NULL; params = NULL; zbx_snprintf_alloc(&exp->exp, &exp_alloc, &exp_offset, "{%d}", functionid); } zabbix_log(LOG_LEVEL_DEBUG, "%s() expression:'%s'", __function_name, exp->exp); if (FAIL == (ret = substitute_simple_macros(NULL, NULL, NULL, NULL, NULL, &dc_item->host, NULL, NULL, &exp->exp, MACRO_TYPE_ITEM_EXPRESSION, error, max_error_len))) ret = NOTSUPPORTED; zabbix_log(LOG_LEVEL_DEBUG, "End of %s():%s", __function_name, zbx_result_string(ret)); return ret; }
/****************************************************************************** * * * Function: httpmacro_append_pair * * * * Purpose: appends key/value pair to the http test macro cache. * * If the value format is 'regex:<pattern>', then regular expression * * match is performed against the supplied data value and specified * * pattern. The first captured group is assigned to the macro value. * * * * Parameters: httptest - [IN/OUT] the http test data * * pkey - [IN] a pointer to the macro name (key) data * * nkey - [IN] the macro name (key) size * * pvalue - [IN] a pointer to the macro value data * * nvalue - [IN] the value size * * data - [IN] the data for regexp matching (optional) * * err_str - [OUT] the error message (optional) * * * * Return value: SUCCEDED - the key/value pair was added successfully * * FAIL - key/value pair adding to cache failed. * * The failure reason can be either empty key/value, * * wrong key format or failed regular expression * * match. * * * * Author: Andris Zeila * * * ******************************************************************************/ static int httpmacro_append_pair(zbx_httptest_t *httptest, const char *pkey, size_t nkey, const char *pvalue, size_t nvalue, const char *data, char **err_str) { const char *__function_name = "httpmacro_append_pair"; char *value_str = NULL; size_t key_size = 0, key_offset = 0, value_size = 0, value_offset = 0; zbx_ptr_pair_t pair = {NULL, NULL}; int index, ret = FAIL; zabbix_log(LOG_LEVEL_DEBUG, "In %s() pkey:'%.*s' pvalue:'%.*s'", __function_name, (int)nkey, pkey, (int)nvalue, pvalue); if (NULL == data) { /* Ignore regex variables when no input data is specified. For example, */ /* scenario level regex variables don't have input data before the first */ /* web scenario step is processed. */ ret = SUCCEED; goto out; } if (0 == nkey || 0 == nvalue) { if (0 == nkey && 0 != nvalue) { zabbix_log(LOG_LEVEL_DEBUG, "%s() missing variable name (only value provided): \"%.*s\"", __function_name, (int)nvalue, pvalue); if (NULL != err_str && NULL == *err_str) { *err_str = zbx_dsprintf(*err_str, "missing variable name (only value provided):" " \"%.*s\"", (int)nvalue, pvalue); } } else if (0 == nvalue && 0 != nkey) { zabbix_log(LOG_LEVEL_DEBUG, "%s() missing variable value (only name provided): \"%.*s\"", __function_name, (int)nkey, pkey); if (NULL != err_str && NULL == *err_str) { *err_str = zbx_dsprintf(*err_str, "missing variable value (only name provided):" " \"%.*s\"", (int)nkey, pkey); } } goto out; } if ('{' != pkey[0] || '}' != pkey[nkey - 1]) { zabbix_log(LOG_LEVEL_DEBUG, "%s() \"%.*s\" not enclosed in {}", __function_name, (int)nkey, pkey); if (NULL != err_str && NULL == *err_str) *err_str = zbx_dsprintf(*err_str, "\"%.*s\" not enclosed in {}", (int)nkey, pkey); goto out; } /* get macro value */ zbx_strncpy_alloc(&value_str, &value_size, &value_offset, pvalue, nvalue); if (0 == strncmp(REGEXP_PREFIX, value_str, REGEXP_PREFIX_SIZE)) { int rc; /* The value contains regexp pattern, retrieve the first captured group or fail. */ /* The \@ sequence is a special construct to fail if the pattern matches but does */ /* not contain groups to capture. */ rc = zbx_mregexp_sub(data, value_str + REGEXP_PREFIX_SIZE, "\\@", (char **)&pair.second); zbx_free(value_str); if (SUCCEED != rc || NULL == pair.second) { zabbix_log(LOG_LEVEL_DEBUG, "%s() cannot extract the value of \"%.*s\" from response", __function_name, (int)nkey, pkey); if (NULL != err_str && NULL == *err_str) { *err_str = zbx_dsprintf(*err_str, "cannot extract the value of \"%.*s\"" " from response", (int)nkey, pkey); } goto out; } } else pair.second = value_str; /* get macro name */ zbx_strncpy_alloc((char**)&pair.first, &key_size, &key_offset, pkey, nkey); /* remove existing macro if necessary */ index = zbx_vector_ptr_pair_search(&httptest->macros, pair, httpmacro_cmp_func); if (FAIL != index) { zbx_ptr_pair_t *ppair = &httptest->macros.values[index]; zbx_free(ppair->first); zbx_free(ppair->second); zbx_vector_ptr_pair_remove_noorder(&httptest->macros, index); } zbx_vector_ptr_pair_append(&httptest->macros, pair); ret = SUCCEED; out: zabbix_log(LOG_LEVEL_DEBUG, "End of %s():%s macro:'%s'='%s'", __function_name, zbx_result_string(ret), (char*)pair.first, (char*)pair.second); return ret; }
/********************************************************************************* * * * Function: regexp_sub_replace * * * * Purpose: Constructs a string from the specified template and regexp match. * * * * Parameters: text - [IN] the input string. * * output_template - [IN] the output string template. The output * * string is constructed from template by * * replacing \<n> sequences with the captured * * regexp group. * * If the output template is NULL or contains * * empty string then a copy of the whole * * input string is returned. * * match - [IN] the captured group data * * nmatch - [IN] the number of items in captured group data * * * * Return value: Allocated string containing output value * * * *********************************************************************************/ static char *regexp_sub_replace(const char *text, const char *output_template, regmatch_t *match, size_t nmatch) { char *ptr = NULL; const char *pstart = output_template, *pgroup; size_t size = 0, offset = 0, group_index; if (NULL == output_template || '\0' == *output_template) return zbx_strdup(NULL, text); while (NULL != (pgroup = strchr(pstart, '\\'))) { switch (*(++pgroup)) { case '\\': zbx_strncpy_alloc(&ptr, &size, &offset, pstart, pgroup - pstart); pstart = pgroup + 1; continue; case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': zbx_strncpy_alloc(&ptr, &size, &offset, pstart, pgroup - pstart - 1); group_index = *pgroup - '0'; if (group_index < nmatch && -1 != match[group_index].rm_so) { zbx_strncpy_alloc(&ptr, &size, &offset, text + match[group_index].rm_so, match[group_index].rm_eo - match[group_index].rm_so); } pstart = pgroup + 1; continue; case '@': /* artificial construct to replace the first captured group or fail */ /* if the regular expression pattern contains no groups */ if (-1 == match[1].rm_so) { zbx_free(ptr); goto out; } zbx_strncpy_alloc(&ptr, &size, &offset, text + match[1].rm_so, match[1].rm_eo - match[1].rm_so); pstart = pgroup + 1; continue; default: zbx_strncpy_alloc(&ptr, &size, &offset, pstart, pgroup - pstart); pstart = pgroup; } } if ('\0' != *pstart) zbx_strcpy_alloc(&ptr, &size, &offset, pstart); out: return ptr; }
static int DBpatch_2010101(void) { DB_RESULT result; DB_ROW row; int ret = SUCCEED; char *key = NULL; size_t key_alloc = 0, key_offset; result = DBselect( "select i.itemid,i.key_,i.params,h.name" " from items i,hosts h" " where i.hostid=h.hostid" " and i.type=%d", ITEM_TYPE_DB_MONITOR); while (NULL != (row = DBfetch(result)) && SUCCEED == ret) { char *user = NULL, *password = NULL, *dsn = NULL, *sql = NULL, *error_message = NULL; zbx_uint64_t itemid; size_t key_len; key_len = strlen(row[1]); parse_db_monitor_item_params(row[2], &dsn, &user, &password, &sql); if (0 != strncmp(row[1], "db.odbc.select[", 15) || ']' != row[1][key_len - 1]) error_message = zbx_dsprintf(error_message, "key \"%s\" is invalid", row[1]); else if (ITEM_USERNAME_LEN < strlen(user)) error_message = zbx_dsprintf(error_message, "ODBC username \"%s\" is too long", user); else if (ITEM_PASSWORD_LEN < strlen(password)) error_message = zbx_dsprintf(error_message, "ODBC password \"%s\" is too long", password); else { char *param = NULL; size_t param_alloc = 0, param_offset = 0; int nparam; zbx_strncpy_alloc(¶m, ¶m_alloc, ¶m_offset, row[1] + 15, key_len - 16); if (1 != (nparam = num_param(param))) quote_key_param(¶m, 0); quote_key_param(&dsn, 0); key_offset = 0; zbx_snprintf_alloc(&key, &key_alloc, &key_offset, "db.odbc.select[%s,%s]", param, dsn); zbx_free(param); if (255 /* ITEM_KEY_LEN */ < zbx_strlen_utf8(key)) error_message = zbx_dsprintf(error_message, "key \"%s\" is too long", row[1]); } if (NULL == error_message) { char *username_esc, *password_esc, *params_esc, *key_esc; ZBX_STR2UINT64(itemid, row[0]); username_esc = DBdyn_escape_string(user); password_esc = DBdyn_escape_string(password); params_esc = DBdyn_escape_string(sql); key_esc = DBdyn_escape_string(key); if (ZBX_DB_OK > DBexecute("update items set username='******',password='******',key_='%s',params='%s'" " where itemid=" ZBX_FS_UI64, username_esc, password_esc, key_esc, params_esc, itemid)) { ret = FAIL; } zbx_free(username_esc); zbx_free(password_esc); zbx_free(params_esc); zbx_free(key_esc); } else { zabbix_log(LOG_LEVEL_WARNING, "Failed to convert host \"%s\" db monitoring item because" " %s. See upgrade notes for manual database monitor item conversion.", row[3], error_message); } zbx_free(error_message); zbx_free(user); zbx_free(password); zbx_free(dsn); zbx_free(sql); } DBfree_result(result); zbx_free(key); return ret; }
static int DBpatch_2030095(void) { DB_RESULT result; DB_ROW row; int ret = SUCCEED; char *p, *q, *params = NULL, *params_esc; size_t params_alloc = 0, params_offset; result = DBselect("select itemid,params from items where type=%d", 15 /* ITEM_TYPE_CALCULATED */); while (SUCCEED == ret && NULL != (row = DBfetch(result))) { params_offset = 0; for (p = row[1]; '\0' != *p; p++) { if (NULL != strchr(ZBX_WHITESPACE, *p)) { if (' ' != *p || (0 != params_offset && NULL == strchr(ZBX_WHITESPACE, params[params_offset - 1]))) { zbx_chrcpy_alloc(¶ms, ¶ms_alloc, ¶ms_offset, *p); } continue; } if (NULL != strchr("#&|", *p)) { if ('#' == *p && 0 != params_offset && '{' == params[params_offset - 1]) { zbx_chrcpy_alloc(¶ms, ¶ms_alloc, ¶ms_offset, *p); continue; } if (('&' == *p || '|' == *p) && 0 != params_offset && NULL == strchr(ZBX_WHITESPACE, params[params_offset - 1])) { zbx_chrcpy_alloc(¶ms, ¶ms_alloc, ¶ms_offset, ' '); } switch (*p) { case '#': zbx_strcpy_alloc(¶ms, ¶ms_alloc, ¶ms_offset, "<>"); break; case '&': zbx_strcpy_alloc(¶ms, ¶ms_alloc, ¶ms_offset, "and"); break; case '|': zbx_strcpy_alloc(¶ms, ¶ms_alloc, ¶ms_offset, "or"); break; } if (('&' == *p || '|' == *p) && NULL == strchr(ZBX_WHITESPACE, *(p + 1))) zbx_chrcpy_alloc(¶ms, ¶ms_alloc, ¶ms_offset, ' '); continue; } q = p; if (SUCCEED == parse_function(&q, NULL, NULL)) { zbx_strncpy_alloc(¶ms, ¶ms_alloc, ¶ms_offset, p, q - p); p = q - 1; continue; } zbx_chrcpy_alloc(¶ms, ¶ms_alloc, ¶ms_offset, *p); } #if defined(HAVE_IBM_DB2) || defined(HAVE_ORACLE) if (2048 < params_offset && 2048 /* ITEM_PARAM_LEN */ < zbx_strlen_utf8(params)) #else if (65535 < params_offset && 65535 /* ITEM_PARAM_LEN */ < zbx_strlen_utf8(params)) #endif { zabbix_log(LOG_LEVEL_WARNING, "cannot convert calculated item expression \"%s\":" " resulting expression is too long", row[1]); } else if (0 != strcmp(row[1], params)) { params_esc = DBdyn_escape_string(params); if (ZBX_DB_OK > DBexecute("update items set params='%s' where itemid=%s", params_esc, row[0])) ret = FAIL; zbx_free(params_esc); } } DBfree_result(result); zbx_free(params); return ret; }