예제 #1
0
파일: sysinfo.c 프로젝트: unix1986/zabbix
void	test_parameters()
{
	int	i;
	char	*key = NULL;
	size_t	key_alloc = 0;

	for (i = 0; NULL != commands[i].key; i++)
	{
		if (0 != strcmp(commands[i].key, "__UserPerfCounter"))
		{
			size_t	key_offset = 0;

			zbx_strcpy_alloc(&key, &key_alloc, &key_offset, commands[i].key);

			if (0 == (commands[i].flags & CF_USERPARAMETER) && NULL != commands[i].test_param)
			{
				zbx_chrcpy_alloc(&key, &key_alloc, &key_offset, '[');
				zbx_strcpy_alloc(&key, &key_alloc, &key_offset, commands[i].test_param);
				zbx_chrcpy_alloc(&key, &key_alloc, &key_offset, ']');
			}

			test_parameter(key);
		}
	}

	zbx_free(key);

	test_aliases();
}
예제 #2
0
파일: sysinfo.c 프로젝트: unix1986/zabbix
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;
}
예제 #3
0
static char	*lld_expression_expand(const char *expression, zbx_vector_ptr_t *functions)
{
	const char		*__function_name = "lld_expression_expand";

	size_t			l, r;
	int			i;
	zbx_uint64_t		index;
	zbx_lld_function_t	*function;
	char			*buffer = NULL;
	size_t			buffer_alloc = 64, buffer_offset = 0;

	zabbix_log(LOG_LEVEL_DEBUG, "In %s() expression:'%s'", __function_name, expression);

	buffer = zbx_malloc(buffer, buffer_alloc);

	*buffer = '\0';

	for (l = 0; '\0' != expression[l]; l++)
	{
		zbx_chrcpy_alloc(&buffer, &buffer_alloc, &buffer_offset, expression[l]);

		if ('{' != expression[l])
			continue;

		for (r = l + 1; '\0' != expression[r] && '}' != expression[r]; r++)
			;

		if ('}' != expression[r])
			continue;

		/* ... > 0 | {1} + ... */
		/*           l r       */

		if (SUCCEED != is_uint64_n(expression + l + 1, r - l - 1, &index))
			continue;

		for (i = 0; i < functions->values_num; i++)
		{
			function = (zbx_lld_function_t *)functions->values[i];

			if (function->index != index)
				continue;

			zbx_snprintf_alloc(&buffer, &buffer_alloc, &buffer_offset, ZBX_FS_UI64 ":%s(%s)",
					function->itemid, function->function, function->parameter);

			break;
		}

		l = r - 1;
	}

	zabbix_log(LOG_LEVEL_DEBUG, "End of %s():'%s'", __function_name, buffer);

	return buffer;
}
예제 #4
0
void	add_if_name(char **if_list, size_t *if_list_alloc, size_t *if_list_offset, const char *name)
{
	if (FAIL == str_in_list(*if_list, name, ZBX_IF_SEP))
	{
		if ('\0' != **if_list)
			zbx_chrcpy_alloc(if_list, if_list_alloc, if_list_offset, ZBX_IF_SEP);

		zbx_strcpy_alloc(if_list, if_list_alloc, if_list_offset, name);
	}
}
예제 #5
0
/******************************************************************************
 *                                                                            *
 * Function: DMget_table_data                                                 *
 *                                                                            *
 * Purpose: get configuration changes to required node for specified table    *
 *                                                                            *
 * Parameters:                                                                *
 *                                                                            *
 * Return value: SUCCESS - processed successfully                             *
 *               FAIL - an error occurred                                     *
 *                                                                            *
 * Author: Alexander Vladishev                                                *
 *                                                                            *
 * Comments:                                                                  *
 *                                                                            *
 ******************************************************************************/
static int	DMget_table_data(int nodeid, unsigned char dest_nodetype, const ZBX_TABLE *table,
		char **data, size_t *data_alloc, size_t *data_offset,
		char **ptbls, size_t *ptbls_alloc, size_t *ptbls_offset)
{
	const char	*__function_name = "DMget_table_data";

	int		f, res = SUCCEED;
	const ZBX_TABLE	*fk_table;

	zabbix_log(LOG_LEVEL_DEBUG, "In %s() [table:'%s']", __function_name, table->table);

	if (SUCCEED == str_in_list(*ptbls, table->table, ','))
		goto out;

	if (0 != *ptbls_offset)
		zbx_chrcpy_alloc(ptbls, ptbls_alloc, ptbls_offset, ',');
	zbx_strcpy_alloc(ptbls, ptbls_alloc, ptbls_offset, table->table);

	for (f = 0; NULL != table->fields[f].name; f++)
	{
		if (0 == (table->fields[f].flags & ZBX_SYNC))
			continue;

		if (NULL == table->fields[f].fk_table)
			continue;

		fk_table = DBget_table(table->fields[f].fk_table);
		DMget_table_data(nodeid, dest_nodetype, fk_table, data, data_alloc, data_offset,
				ptbls, ptbls_alloc, ptbls_offset);
	}
	DMcollect_table_data(nodeid, dest_nodetype, table, data, data_alloc, data_offset);
out:
	zabbix_log(LOG_LEVEL_DEBUG, "End of %s():%s", __function_name, zbx_result_string(res));

	return res;
}
예제 #6
0
파일: sysinfo.c 프로젝트: unix1986/zabbix
static int	zbx_check_user_parameter(const char *param, char *error, int max_error_len)
{
	const char	suppressed_chars[] = "\\'\"`*?[]{}~$!&;()<>|#@\n", *c;
	char		*buf = NULL;
	size_t		buf_alloc = 128, buf_offset = 0;

	if (0 != CONFIG_UNSAFE_USER_PARAMETERS)
		return SUCCEED;

	for (c = suppressed_chars; '\0' != *c; c++)
	{
		if (NULL == strchr(param, *c))
			continue;

		buf = zbx_malloc(buf, buf_alloc);

		for (c = suppressed_chars; '\0' != *c; c++)
		{
			if (c != suppressed_chars)
				zbx_strcpy_alloc(&buf, &buf_alloc, &buf_offset, ", ");

			if (0 != isprint(*c))
				zbx_chrcpy_alloc(&buf, &buf_alloc, &buf_offset, *c);
			else
				zbx_snprintf_alloc(&buf, &buf_alloc, &buf_offset, "0x%02x", *c);
		}

		zbx_snprintf(error, max_error_len, "special characters \"%s\" are not allowed in the parameters", buf);

		zbx_free(buf);

		return FAIL;
	}

	return SUCCEED;
}
예제 #7
0
/******************************************************************************
 *                                                                            *
 * Function: housekeeping_cleanup                                             *
 *                                                                            *
 * Purpose: remove deleted items data                                         *
 *                                                                            *
 * Return value: number of rows deleted                                       *
 *                                                                            *
 * Author: Alexei Vladishev, Dmitry Borovikov                                 *
 *                                                                            *
 * Comments: sqlite3 does not use CONFIG_MAX_HOUSEKEEPER_DELETE, deletes all  *
 *                                                                            *
 ******************************************************************************/
static int	housekeeping_cleanup()
{
    const char		*__function_name = "housekeeping_cleanup";

    DB_HOUSEKEEPER		housekeeper;
    DB_RESULT		result;
    DB_ROW			row;
    int			d, deleted = 0;
    zbx_vector_uint64_t	housekeeperids;
    char			*sql = NULL, *table_name_esc;
    size_t			sql_alloc = 0, sql_offset = 0;
    zbx_hk_cleanup_table_t *table;

    zabbix_log(LOG_LEVEL_DEBUG, "In %s()", __function_name);

    /* first handle the trivial case when history and trend housekeeping is disabled */
    if (ZBX_HK_OPTION_DISABLED == hk_config.history_mode && ZBX_HK_OPTION_DISABLED == hk_config.trends_mode)
        goto out;

    zbx_vector_uint64_create(&housekeeperids);

    zbx_strcpy_alloc(&sql, &sql_alloc, &sql_offset,
                     "select housekeeperid,tablename,field,value"
                     " from housekeeper"
                     " where tablename in (");

    /* assemble list of tables excluded from housekeeping procedure */
    for (table = hk_cleanup_tables; NULL != table->name; table++)
    {
        if (ZBX_HK_OPTION_ENABLED != *table->poption_mode)
            continue;

        table_name_esc = DBdyn_escape_string(table->name);

        zbx_chrcpy_alloc(&sql, &sql_alloc, &sql_offset, '\'');
        zbx_strcpy_alloc(&sql, &sql_alloc, &sql_offset, table_name_esc);
        zbx_strcpy_alloc(&sql, &sql_alloc, &sql_offset, "',");

        zbx_free(table_name_esc);
    }
    sql_offset--;

    /* order by tablename to effectively use DB cache */
    zbx_strcpy_alloc(&sql, &sql_alloc, &sql_offset, ") order by tablename");

    result = DBselect("%s", sql);

    while (NULL != (row = DBfetch(result)))
    {
        ZBX_STR2UINT64(housekeeper.housekeeperid, row[0]);
        housekeeper.tablename = row[1];
        housekeeper.field = row[2];
        ZBX_STR2UINT64(housekeeper.value, row[3]);

        if (0 == CONFIG_MAX_HOUSEKEEPER_DELETE)
        {
            d = DBexecute(
                    "delete from %s"
                    " where %s=" ZBX_FS_UI64,
                    housekeeper.tablename,
                    housekeeper.field,
                    housekeeper.value);
        }
        else
        {
#if defined(HAVE_IBM_DB2) || defined(HAVE_ORACLE)
            d = DBexecute(
                    "delete from %s"
                    " where %s=" ZBX_FS_UI64
                    " and rownum<=%d",
                    housekeeper.tablename,
                    housekeeper.field,
                    housekeeper.value,
                    CONFIG_MAX_HOUSEKEEPER_DELETE);
#elif defined(HAVE_MYSQL)
            d = DBexecute(
                    "delete from %s"
                    " where %s=" ZBX_FS_UI64 " limit %d",
                    housekeeper.tablename,
                    housekeeper.field,
                    housekeeper.value,
                    CONFIG_MAX_HOUSEKEEPER_DELETE);
#elif defined(HAVE_POSTGRESQL)
            d = DBexecute(
                    "delete from %s"
                    " where ctid = any(array(select ctid from %s"
                    " where %s=" ZBX_FS_UI64 " limit %d))",
                    housekeeper.tablename,
                    housekeeper.tablename,
                    housekeeper.field,
                    housekeeper.value,
                    CONFIG_MAX_HOUSEKEEPER_DELETE);
#elif defined(HAVE_SQLITE3)
            d = 0;
#endif
        }

        if (ZBX_DB_OK <= d)
        {
            if (0 == CONFIG_MAX_HOUSEKEEPER_DELETE || CONFIG_MAX_HOUSEKEEPER_DELETE > d)
                zbx_vector_uint64_append(&housekeeperids, housekeeper.housekeeperid);

            deleted += d;
        }
    }
    DBfree_result(result);

    if (0 != housekeeperids.values_num)
    {
        zbx_vector_uint64_sort(&housekeeperids, ZBX_DEFAULT_UINT64_COMPARE_FUNC);

        sql_offset = 0;
        zbx_strcpy_alloc(&sql, &sql_alloc, &sql_offset, "delete from housekeeper where");
        DBadd_condition_alloc(&sql, &sql_alloc, &sql_offset, "housekeeperid",
                              housekeeperids.values, housekeeperids.values_num);

        DBexecute("%s", sql);
    }

    zbx_free(sql);

    zbx_vector_uint64_destroy(&housekeeperids);
out:
    zabbix_log(LOG_LEVEL_DEBUG, "End of %s():%d", __function_name, deleted);

    return deleted;
}
예제 #8
0
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);
}
예제 #9
0
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, &params))
		{
			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;
}
예제 #10
0
/******************************************************************************
 *                                                                            *
 * Function: process_record                                                   *
 *                                                                            *
 * Purpose: process record update                                             *
 *                                                                            *
 * Parameters:                                                                *
 *                                                                            *
 * Return value:  SUCCEED - processed successfully                            *
 *                FAIL - an error occurred                                    *
 *                                                                            *
 * Author: Alexei Vladishev                                                   *
 *                                                                            *
 * Comments:                                                                  *
 *                                                                            *
 ******************************************************************************/
static int	process_record(char **sql, size_t *sql_alloc, size_t *sql_offset, int sender_nodeid, int nodeid,
		const ZBX_TABLE *table, const char *record, int lastrecord, int acknowledges,
		zbx_vector_uint64_t *ack_eventids)
{
	const char	*r;
	int		f, res = FAIL;
	char		*value_esc;

	zabbix_log(LOG_LEVEL_DEBUG, "In process_record()");

	if (0 == *sql_offset)
	{
		DBbegin_multiple_update(sql, sql_alloc, sql_offset);
#ifdef HAVE_MULTIROW_INSERT
		begin_history_sql(sql, sql_alloc, sql_offset, table);
#endif
	}

#if !defined(HAVE_MULTIROW_INSERT)
	begin_history_sql(sql, sql_alloc, sql_offset, table);
#endif

	zbx_chrcpy_alloc(sql, sql_alloc, sql_offset, '(');
	if (0 != (table->flags & ZBX_HISTORY_SYNC))
		zbx_snprintf_alloc(sql, sql_alloc, sql_offset, "%d,", nodeid);

	for (r = record, f = 0; table->fields[f].name != 0; f++)
	{
		if (0 != (table->flags & ZBX_HISTORY_SYNC) && 0 == (table->fields[f].flags & ZBX_HISTORY_SYNC))
			continue;

		if (NULL == r)
			goto error;

		zbx_get_next_field(&r, &buffer, &buffer_alloc, ZBX_DM_DELIMITER);

		if (0 != acknowledges && 0 == strcmp(table->fields[f].name, "eventid"))
		{
			zbx_uint64_t	eventid;

			ZBX_STR2UINT64(eventid, buffer);
			zbx_vector_uint64_append(ack_eventids, eventid);
		}

		if (table->fields[f].type == ZBX_TYPE_INT ||
				table->fields[f].type == ZBX_TYPE_UINT ||
				table->fields[f].type == ZBX_TYPE_ID ||
				table->fields[f].type == ZBX_TYPE_FLOAT)
		{
			zbx_snprintf_alloc(sql, sql_alloc, sql_offset, "%s,", buffer);
		}
		else if (table->fields[f].type == ZBX_TYPE_BLOB)
		{
			if ('\0' == *buffer)
				zbx_strcpy_alloc(sql, sql_alloc, sql_offset, "'',");
			else
			{
#ifdef HAVE_POSTGRESQL
				size_t	len;

				len = zbx_hex2binary(buffer);
				zbx_pg_escape_bytea((u_char *)buffer, len, &tmp, &tmp_alloc);
				zbx_snprintf_alloc(sql, sql_alloc, sql_offset, "'%s',", tmp);
#else
				zbx_snprintf_alloc(sql, sql_alloc, sql_offset, "0x%s,", buffer);
#endif
			}
		}
		else	/* ZBX_TYPE_TEXT, ZBX_TYPE_CHAR */
		{
			zbx_hex2binary(buffer);
			value_esc = DBdyn_escape_string(buffer);

			zbx_snprintf_alloc(sql, sql_alloc, sql_offset, "'%s',", value_esc);

			zbx_free(value_esc);
		}
	}

	(*sql_offset)--;

#ifdef HAVE_MULTIROW_INSERT
	zbx_strcpy_alloc(sql, sql_alloc, sql_offset, "),");
#else
	zbx_strcpy_alloc(sql, sql_alloc, sql_offset, ");\n");
#endif

	if (0 != lastrecord || *sql_offset > ZBX_MAX_SQL_SIZE)
	{
#ifdef HAVE_MULTIROW_INSERT
		(*sql_offset)--;
		zbx_strcpy_alloc(sql, sql_alloc, sql_offset, ";\n");
#endif
		DBend_multiple_update(sql, sql_alloc, sql_offset);

		if (ZBX_DB_OK <= DBexecute("%s", *sql))
			res = SUCCEED;
		*sql_offset = 0;

		if (SUCCEED == res && 0 != lastrecord && 0 != acknowledges && 0 != ack_eventids->values_num)
		{
			zbx_vector_uint64_sort(ack_eventids, ZBX_DEFAULT_UINT64_COMPARE_FUNC);
			zbx_vector_uint64_uniq(ack_eventids, ZBX_DEFAULT_UINT64_COMPARE_FUNC);

			zbx_strcpy_alloc(sql, sql_alloc, sql_offset,
					"update events"
					" set acknowledged=1"
					" where");
			DBadd_condition_alloc(sql, sql_alloc, sql_offset,
					"eventid", ack_eventids->values, ack_eventids->values_num);

			if (ZBX_DB_OK > DBexecute("%s", *sql))
				res = FAIL;
			*sql_offset = 0;
		}
	}
	else
		res = SUCCEED;

	return res;
error:
	zabbix_log(LOG_LEVEL_ERR, "NODE %d: Received invalid record from node %d for node %d [%s]",
			CONFIG_NODEID, sender_nodeid, nodeid, record);

	return FAIL;
}
예제 #11
0
static int	DBpatch_2030094(void)
{
	DB_RESULT	result;
	DB_ROW		row;
	int		ret = SUCCEED;
	char		*p, *expr = NULL, *expr_esc;
	size_t		expr_alloc = 0, expr_offset;

	result = DBselect("select triggerid,expression from triggers");

	while (SUCCEED == ret && NULL != (row = DBfetch(result)))
	{
		expr_offset = 0;

		for (p = row[1]; '\0' != *p; p++)
		{
			if (NULL == strchr("#&|", *p))
			{
				if (' ' != *p || (0 != expr_offset && ' ' != expr[expr_offset - 1]))
					zbx_chrcpy_alloc(&expr, &expr_alloc, &expr_offset, *p);

				continue;
			}

			if ('#' == *p && 0 != expr_offset && '{' == expr[expr_offset - 1])
			{
				zbx_chrcpy_alloc(&expr, &expr_alloc, &expr_offset, *p);
				continue;
			}

			if (('&' == *p || '|' == *p) && 0 != expr_offset && ' ' != expr[expr_offset - 1])
				zbx_chrcpy_alloc(&expr, &expr_alloc, &expr_offset, ' ');

			switch (*p)
			{
				case '#':
					zbx_strcpy_alloc(&expr, &expr_alloc, &expr_offset, "<>");
					break;
				case '&':
					zbx_strcpy_alloc(&expr, &expr_alloc, &expr_offset, "and");
					break;
				case '|':
					zbx_strcpy_alloc(&expr, &expr_alloc, &expr_offset, "or");
					break;
			}

			if (('&' == *p || '|' == *p) && ' ' != *(p + 1))
				zbx_chrcpy_alloc(&expr, &expr_alloc, &expr_offset, ' ');
		}

		if (2048 < expr_offset && 2048 /* TRIGGER_EXPRESSION_LEN */ < zbx_strlen_utf8(expr))
		{
			zabbix_log(LOG_LEVEL_WARNING, "cannot convert trigger expression \"%s\":"
					" resulting expression is too long", row[1]);
		}
		else if (0 != strcmp(row[1], expr))
		{
			expr_esc = DBdyn_escape_string(expr);

			if (ZBX_DB_OK > DBexecute("update triggers set expression='%s' where triggerid=%s",
					expr_esc, row[0]))
			{
				ret = FAIL;
			}

			zbx_free(expr_esc);
		}
	}
	DBfree_result(result);

	zbx_free(expr);

	return ret;
}
예제 #12
0
/******************************************************************************
 *                                                                            *
 * 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(&regexp, &regexp_alloc, &regexp_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(&regexp, &regexp_alloc, &regexp_num, pattern + 1);

			/* dealing with `severity' parameter */
			if (0 == get_param(params, 3, key_severity, sizeof(key_severity)) &&
				*key_severity == '@')
					add_regexp_name(&regexp, &regexp_alloc, &regexp_num, key_severity + 1);

			/* dealing with `logeventid' parameter */
			if (0 == get_param(params, 5, key_logeventid, sizeof(key_logeventid)) &&
				*key_logeventid == '@')
					add_regexp_name(&regexp, &regexp_alloc, &regexp_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;
}
예제 #13
0
/******************************************************************************
 *                                                                            *
 * Function: process_checksum                                                 *
 *                                                                            *
 * Author: Alexander Vladishev                                                *
 *                                                                            *
 ******************************************************************************/
static void	process_checksum(int nodeid, char *data, unsigned char sender_nodetype)
{
	const char	*__function_name = "process_checksum";
	char		*r, *lf;
	size_t		tmp_offset;
	const ZBX_TABLE	*table = NULL;
	zbx_uint64_t	recid;

	zabbix_log(LOG_LEVEL_DEBUG, "In %s()", __function_name);

	for (r = data; '\0' != *r;)
	{
		if (NULL != (lf = strchr(r, '\n')))
			*lf = '\0';

		zbx_get_next_field((const char **)&r, &buf, &buf_alloc, ZBX_DM_DELIMITER);	/* table name */

		if (NULL == table || 0 != strcmp(table->table, buf))
		{
			if (NULL == (table = DBget_table(buf)))
			{
				zabbix_log(LOG_LEVEL_DEBUG, "%s(): cannot find table [%s]", __function_name, buf);
				goto next;
			}
		}

		zbx_get_next_field((const char **)&r, &buf, &buf_alloc, ZBX_DM_DELIMITER);	/* record id */
		ZBX_STR2UINT64(recid, buf);

		zbx_get_next_field((const char **)&r, &buf, &buf_alloc, ZBX_DM_DELIMITER);	/* operation type */

		if ('0' == *buf)	/* NODE_CONFIGLOG_OP_UPDATE */
		{
			*tmp = '\0';
			tmp_offset = 0;

			while (NULL != r)
			{
				/* field name */
				zbx_get_next_field((const char **)&r, &buf, &buf_alloc, ZBX_DM_DELIMITER);
				if (0 != tmp_offset)
					zbx_chrcpy_alloc(&tmp, &tmp_alloc, &tmp_offset, ',');
				zbx_strcpy_alloc(&tmp, &tmp_alloc, &tmp_offset, buf);
				/* field type */
				zbx_get_next_field((const char **)&r, &buf, &buf_alloc, ZBX_DM_DELIMITER);
				/* value */
				zbx_get_next_field((const char **)&r, &buf, &buf_alloc, ZBX_DM_DELIMITER);
			}

			if (SUCCEED == calculate_checksums(nodeid, table->table, recid))
				update_checksums(nodeid, sender_nodetype, SUCCEED, table->table, recid, tmp);
		}
next:
		if (NULL != lf)
		{
			*lf++ = '\n';
			r = lf;
		}
		else
			break;
	}

	zabbix_log(LOG_LEVEL_DEBUG, "End of %s()", __function_name);
}
예제 #14
0
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(&params, &params_alloc, &params_offset, *p);
				}

				continue;
			}

			if (NULL != strchr("#&|", *p))
			{
				if ('#' == *p && 0 != params_offset && '{' == params[params_offset - 1])
				{
					zbx_chrcpy_alloc(&params, &params_alloc, &params_offset, *p);
					continue;
				}

				if (('&' == *p || '|' == *p) && 0 != params_offset &&
						NULL == strchr(ZBX_WHITESPACE, params[params_offset - 1]))
				{
					zbx_chrcpy_alloc(&params, &params_alloc, &params_offset, ' ');
				}

				switch (*p)
				{
					case '#':
						zbx_strcpy_alloc(&params, &params_alloc, &params_offset, "<>");
						break;
					case '&':
						zbx_strcpy_alloc(&params, &params_alloc, &params_offset, "and");
						break;
					case '|':
						zbx_strcpy_alloc(&params, &params_alloc, &params_offset, "or");
						break;
				}

				if (('&' == *p || '|' == *p) && NULL == strchr(ZBX_WHITESPACE, *(p + 1)))
					zbx_chrcpy_alloc(&params, &params_alloc, &params_offset, ' ');

				continue;
			}

			q = p;

			if (SUCCEED == parse_function(&q, NULL, NULL))
			{
				zbx_strncpy_alloc(&params, &params_alloc, &params_offset, p, q - p);
				p = q - 1;
				continue;
			}

			zbx_chrcpy_alloc(&params, &params_alloc, &params_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;
}
예제 #15
0
/******************************************************************************
 *                                                                            *
 * Function: calculate_checksums                                              *
 *                                                                            *
 * Purpose: calculate checksums of configuration data                         *
 *                                                                            *
 * Parameters:                                                                *
 *                                                                            *
 * Return value: SUCCESS - calculated successfully                            *
 *               FAIL - an error occurred                                     *
 *                                                                            *
 * Author: Alexei Vladishev                                                   *
 *                                                                            *
 * Comments:                                                                  *
 *                                                                            *
 ******************************************************************************/
int	calculate_checksums(int nodeid, const char *tablename, const zbx_uint64_t recordid)
{
	const char	*__function_name = "calculate_checksums";

	char		*sql = NULL;
	size_t		sql_alloc = 2 * ZBX_KIBIBYTE, sql_offset = 0;
	int		t, f, res = SUCCEED;

	zabbix_log(LOG_LEVEL_DEBUG, "In %s()", __function_name);

	sql = zbx_malloc(sql, sql_alloc);

	zbx_snprintf_alloc(&sql, &sql_alloc, &sql_offset,
			"delete from node_cksum"
			" where nodeid=%d"
				" and cksumtype=%d",
			nodeid, NODE_CKSUM_TYPE_NEW);

	if (NULL != tablename)
		zbx_snprintf_alloc(&sql, &sql_alloc, &sql_offset, " and tablename='%s'", tablename);

	if (0 != recordid)
		zbx_snprintf_alloc(&sql, &sql_alloc, &sql_offset, " and recordid=" ZBX_FS_UI64, recordid);

	if (ZBX_DB_OK > DBexecute("%s", sql))
		res = FAIL;

	for (t = 0; NULL != tables[t].table; t++)
	{
		if (0 == (tables[t].flags & ZBX_SYNC))
			continue;

		if (NULL != tablename && 0 != strcmp(tablename, tables[t].table))
			continue;

		sql_offset = 0;
		zbx_snprintf_alloc(&sql, &sql_alloc, &sql_offset,
				"insert into node_cksum (nodeid,tablename,recordid,cksumtype,cksum)"
				" select %d,'%s',%s,%d,",
				nodeid, tables[t].table, tables[t].recid, NODE_CKSUM_TYPE_NEW);
#ifdef HAVE_MYSQL
		zbx_strcpy_alloc(&sql, &sql_alloc, &sql_offset, "concat_ws(',',");
#endif

		for (f = 0; NULL != tables[t].fields[f].name; f++)
		{
			const ZBX_FIELD	*field = &tables[t].fields[f];

			if (0 == (field->flags & ZBX_SYNC))
				continue;

			if (field->flags & ZBX_NOTNULL)
			{
				switch (field->type)
				{
					case ZBX_TYPE_ID:
					case ZBX_TYPE_INT:
					case ZBX_TYPE_UINT:
						zbx_strcpy_alloc(&sql, &sql_alloc, &sql_offset, field->name);
						break;
					case ZBX_TYPE_FLOAT:
						zbx_snprintf_alloc(&sql, &sql_alloc, &sql_offset,
								"md5(cast(%s as char))", field->name);
						break;
					default:
						zbx_snprintf_alloc(&sql, &sql_alloc, &sql_offset,
								"md5(%s)", field->name);
						break;
				}
			}
			else
			{
				zbx_snprintf_alloc(&sql, &sql_alloc, &sql_offset,
						"case when %s is null then 'NULL'", field->name);

				switch (field->type)
				{
					case ZBX_TYPE_ID:
					case ZBX_TYPE_INT:
					case ZBX_TYPE_UINT:
						zbx_snprintf_alloc(&sql, &sql_alloc, &sql_offset,
								" else cast(%s as char) end", field->name);
						break;
					case ZBX_TYPE_FLOAT:
						zbx_snprintf_alloc(&sql, &sql_alloc, &sql_offset,
								" else md5(cast(%s as char)) end", field->name);
						break;
					default:
						zbx_snprintf_alloc(&sql, &sql_alloc, &sql_offset,
								" else md5(%s) end", field->name);
						break;
				}
			}
#ifdef HAVE_MYSQL
			zbx_chrcpy_alloc(&sql, &sql_alloc, &sql_offset, ',');
#else
			zbx_strcpy_alloc(&sql, &sql_alloc, &sql_offset, "||','||");
#endif
		}

		/* remove last delimiter */
		if (f > 0)
		{
#ifdef HAVE_MYSQL
			sql_offset--;
			zbx_chrcpy_alloc(&sql, &sql_alloc, &sql_offset, ')');
#else
			sql_offset -= 7;
#endif
		}

		zbx_snprintf_alloc(&sql, &sql_alloc, &sql_offset, " from %s", tables[t].table);

		if (0 != recordid)
		{
			zbx_snprintf_alloc(&sql, &sql_alloc, &sql_offset, " where %s=" ZBX_FS_UI64,
					tables[t].recid, recordid);
		}
		else
		{
			zbx_snprintf_alloc(&sql, &sql_alloc, &sql_offset, " where 1=1" DB_NODE,
					DBnode(tables[t].recid, nodeid));
		}

		if (ZBX_DB_OK > DBexecute("%s", sql))
		{
			res = FAIL;
			break;
		}
	}
	zbx_free(sql);

	zabbix_log(LOG_LEVEL_DEBUG, "End of %s():%s", __function_name, zbx_result_string(res));

	return res;
}
/******************************************************************************
 *                                                                            *
 * Function: aggregate_get_items                                              *
 *                                                                            *
 * Purpose: get array of items specified by key for selected groups           *
 *                                                                            *
 * Parameters: itemids - [OUT] list of item ids                               *
 *             groups  - [IN] list of comma-separated host groups             *
 *             itemkey - [IN] item key to aggregate                           *
 *                                                                            *
 ******************************************************************************/
static void	aggregate_get_items(zbx_vector_uint64_t *itemids, const char *groups, const char *itemkey)
{
    const char	*__function_name = "aggregate_get_items";

    char		*group, *esc;
    DB_RESULT	result;
    DB_ROW		row;
    zbx_uint64_t	itemid;
    char		*sql = NULL;
    size_t		sql_alloc = ZBX_KIBIBYTE, sql_offset = 0;
    int		num, n;

    zabbix_log(LOG_LEVEL_DEBUG, "In %s() groups:'%s' itemkey:'%s'", __function_name, groups, itemkey);

    sql = zbx_malloc(sql, sql_alloc);

    esc = DBdyn_escape_string(itemkey);

    zbx_snprintf_alloc(&sql, &sql_alloc, &sql_offset,
                       "select distinct i.itemid"
                       " from items i,hosts h,hosts_groups hg,groups g"
                       " where i.hostid=h.hostid"
                       " and h.hostid=hg.hostid"
                       " and hg.groupid=g.groupid"
                       " and i.key_='%s'"
                       " and i.status=%d"
                       " and h.status=%d",
                       esc, ITEM_STATUS_ACTIVE, HOST_STATUS_MONITORED);

    zbx_free(esc);

    num = num_param(groups);

    zbx_strcpy_alloc(&sql, &sql_alloc, &sql_offset, " and g.name in (");

    for (n = 1; n <= num; n++)
    {
        if (NULL == (group = get_param_dyn(groups, n)))
            continue;

        esc = DBdyn_escape_string(group);

        zbx_snprintf_alloc(&sql, &sql_alloc, &sql_offset, "'%s'", esc);

        if (n != num)
            zbx_chrcpy_alloc(&sql, &sql_alloc, &sql_offset, ',');

        zbx_free(esc);
        zbx_free(group);
    }

    zbx_snprintf_alloc(&sql, &sql_alloc, &sql_offset, ")" DB_NODE, DBnode_local("h.hostid"));

    result = DBselect("%s", sql);

    zbx_free(sql);

    while (NULL != (row = DBfetch(result)))
    {
        ZBX_STR2UINT64(itemid, row[0]);
        zbx_vector_uint64_append(itemids, itemid);
    }
    DBfree_result(result);

    zbx_vector_uint64_sort(itemids, ZBX_DEFAULT_UINT64_COMPARE_FUNC);

    zabbix_log(LOG_LEVEL_DEBUG, "End of %s()", __function_name);
}
예제 #17
0
/******************************************************************************
 *                                                                            *
 * Function: aggregate_get_items                                              *
 *                                                                            *
 * Purpose: get array of items specified by key for selected groups           *
 *                                                                            *
 * Parameters: ids - result, list of items                                    *
 *             groups - list of comma-separated host groups                   *
 *             itemkey - item key to aggregate                                *
 *                                                                            *
 ******************************************************************************/
static void	aggregate_get_items(zbx_uint64_t **ids, int *ids_alloc, int *ids_num, const char *groups,
		const char *itemkey)
{
	char		*group, *esc;
	DB_RESULT	result;
	DB_ROW		row;
	zbx_uint64_t	itemid;
	char		*sql = NULL;
	size_t		sql_alloc = ZBX_KIBIBYTE, sql_offset = 0;
	int		num, n;

	sql = zbx_malloc(sql, sql_alloc);

	esc = DBdyn_escape_string(itemkey);

	zbx_snprintf_alloc(&sql, &sql_alloc, &sql_offset,
			"select i.itemid"
			" from items i,hosts_groups hg,hosts h,groups g"
			" where hg.groupid=g.groupid"
				" and i.hostid=h.hostid"
				" and hg.hostid=h.hostid"
				" and i.key_='%s'"
				" and i.status=%d"
				" and h.status=%d",
			esc,
			ITEM_STATUS_ACTIVE,
			HOST_STATUS_MONITORED);

	zbx_free(esc);

	num = num_param(groups);

	zbx_strcpy_alloc(&sql, &sql_alloc, &sql_offset, " and g.name in (");

	for (n = 1; n <= num; n++)
	{
		if (NULL == (group = get_param_dyn(groups, n)))
			continue;

		esc = DBdyn_escape_string(group);

		zbx_snprintf_alloc(&sql, &sql_alloc, &sql_offset, "'%s'", esc);

		if (n != num)
			zbx_chrcpy_alloc(&sql, &sql_alloc, &sql_offset, ',');

		zbx_free(esc);
		zbx_free(group);
	}

	zbx_snprintf_alloc(&sql, &sql_alloc, &sql_offset, ")" DB_NODE, DBnode_local("h.hostid"));

	result = DBselect("%s", sql);

	zbx_free(sql);

	while (NULL != (row = DBfetch(result)))
	{
		ZBX_STR2UINT64(itemid, row[0]);
		uint64_array_add(ids, ids_alloc, ids_num, itemid, 64);
	}
	DBfree_result(result);
}