コード例 #1
0
static void	get_52_version(char **os, size_t *os_alloc, size_t *os_offset, OSVERSIONINFOEX *vi, SYSTEM_INFO *si)
{
	zbx_strcpy_alloc(os, os_alloc, os_offset, " Microsoft Windows");

	if (0 != GetSystemMetrics(89))			/* SM_SERVERR2 */
		zbx_strcpy_alloc(os, os_alloc, os_offset, " Server 2003 R2");
	else if (0 != (vi->wSuiteMask & 0x8000))	/* VER_SUITE_WH_SERVER */
		zbx_strcpy_alloc(os, os_alloc, os_offset, " Home Server");
	else if (VER_NT_WORKSTATION == vi->wProductType && PROCESSOR_ARCHITECTURE_AMD64 == si->wProcessorArchitecture)
		zbx_strcpy_alloc(os, os_alloc, os_offset, " XP Professional");
	else
		zbx_strcpy_alloc(os, os_alloc, os_offset, " Server 2003");

	if (VER_NT_WORKSTATION != vi->wProductType)
	{
		if (vi->wSuiteMask & VER_SUITE_COMPUTE_SERVER)
			zbx_strcpy_alloc(os, os_alloc, os_offset, " Compute Cluster Edition");
		else if (vi->wSuiteMask & VER_SUITE_DATACENTER)
			zbx_strcpy_alloc(os, os_alloc, os_offset, " Datacenter Edition");
		else if (vi->wSuiteMask & VER_SUITE_ENTERPRISE)
			zbx_strcpy_alloc(os, os_alloc, os_offset, " Enterprise Edition");
		else if (vi->wSuiteMask & VER_SUITE_BLADE)
			zbx_strcpy_alloc(os, os_alloc, os_offset, " Web Edition");
		else
			zbx_strcpy_alloc(os, os_alloc, os_offset, " Standard Edition");
	}
}
コード例 #2
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();
}
コード例 #3
0
ファイル: dbupgrade.c プロジェクト: HupuInc/zabbix
static void	DBcreate_index_sql(char **sql, size_t *sql_alloc, size_t *sql_offset,
		const char *table_name, const char *index_name, const char *fields, int unique)
{
	zbx_strcpy_alloc(sql, sql_alloc, sql_offset, "create");
	if (0 != unique)
		zbx_strcpy_alloc(sql, sql_alloc, sql_offset, " unique");
	zbx_snprintf_alloc(sql, sql_alloc, sql_offset, " index %s on %s (%s)", index_name, table_name, fields);
}
コード例 #4
0
ファイル: dbupgrade.c プロジェクト: HupuInc/zabbix
static void	DBrename_index_sql(char **sql, size_t *sql_alloc, size_t *sql_offset, const char *table_name,
		const char *old_name, const char *new_name, const char *fields, int unique)
{
#if defined(HAVE_IBM_DB2)
	zbx_snprintf_alloc(sql, sql_alloc, sql_offset, "rename index %s to %s", old_name, new_name);
#elif defined(HAVE_MYSQL)
	DBcreate_index_sql(sql, sql_alloc, sql_offset, table_name, new_name, fields, unique);
	zbx_strcpy_alloc(sql, sql_alloc, sql_offset, ";\n");
	DBdrop_index_sql(sql, sql_alloc, sql_offset, table_name, old_name);
	zbx_strcpy_alloc(sql, sql_alloc, sql_offset, ";\n");
#elif defined(HAVE_ORACLE) || defined(HAVE_POSTGRESQL)
	zbx_snprintf_alloc(sql, sql_alloc, sql_offset, "alter index %s rename to %s", old_name, new_name);
#endif
}
コード例 #5
0
static void	get_cpu_type(char **os, size_t *os_alloc, size_t *os_offset, SYSTEM_INFO *si)
{
	switch (si->wProcessorArchitecture)
	{
		case PROCESSOR_ARCHITECTURE_INTEL:
			zbx_strcpy_alloc(os, os_alloc, os_offset, " x86");
			break;
		case PROCESSOR_ARCHITECTURE_AMD64:
			zbx_strcpy_alloc(os, os_alloc, os_offset, " x64");
			break;
		case PROCESSOR_ARCHITECTURE_IA64:
			zbx_strcpy_alloc(os, os_alloc, os_offset, " Intel Itanium-based");
			break;
	}
}
コード例 #6
0
void	alias_expand_dyn(const char *orig, char **expanded, size_t *expanded_alloc)
{
	ALIAS	*alias;
	size_t	expanded_offset = 0;

	for (alias = aliasList; NULL != alias; alias = alias->next)
	{
		if (0 == strcmp(alias->name, orig))
		{
			zbx_strcpy_alloc(expanded, expanded_alloc, &expanded_offset, alias->value);
			return;
		}
	}

	zbx_strcpy_alloc(expanded, expanded_alloc, &expanded_offset, orig);
}
コード例 #7
0
ファイル: dbupgrade.c プロジェクト: HupuInc/zabbix
static void	DBfield_definition_string(char **sql, size_t *sql_alloc, size_t *sql_offset, const ZBX_FIELD *field)
{
	zbx_snprintf_alloc(sql, sql_alloc, sql_offset, "%s ", field->name);
	DBfield_type_string(sql, sql_alloc, sql_offset, field);
	if (NULL != field->default_value)
	{
		char	*default_value_esc;

#if defined(HAVE_MYSQL)
		switch (field->type)
		{
			case ZBX_TYPE_BLOB:
			case ZBX_TYPE_TEXT:
			case ZBX_TYPE_SHORTTEXT:
			case ZBX_TYPE_LONGTEXT:
				/* MySQL: BLOB and TEXT columns cannot be assigned a default value */
				break;
			default:
#endif
				default_value_esc = DBdyn_escape_string(field->default_value);
				zbx_snprintf_alloc(sql, sql_alloc, sql_offset, " default '%s'", default_value_esc);
				zbx_free(default_value_esc);
#if defined(HAVE_MYSQL)
		}
#endif
	}

	if (0 != (field->flags & ZBX_NOTNULL))
	{
#if defined(HAVE_ORACLE)
		switch (field->type)
		{
			case ZBX_TYPE_INT:
			case ZBX_TYPE_FLOAT:
			case ZBX_TYPE_BLOB:
			case ZBX_TYPE_UINT:
			case ZBX_TYPE_ID:
				zbx_strcpy_alloc(sql, sql_alloc, sql_offset, " not null");
				break;
			default:	/* ZBX_TYPE_CHAR, ZBX_TYPE_TEXT, ZBX_TYPE_SHORTTEXT or ZBX_TYPE_LONGTEXT */
				/* nothing to do */;
		}
#else
		zbx_strcpy_alloc(sql, sql_alloc, sql_offset, " not null");
#endif
	}
}
コード例 #8
0
ファイル: timer.c プロジェクト: zabbix/zabbix
/******************************************************************************
 *                                                                            *
 * Function: db_get_query_tags                                                *
 *                                                                            *
 * Purpose: get event query tags from database                                *
 *                                                                            *
 ******************************************************************************/
static void	db_get_query_tags(zbx_vector_ptr_t *event_queries)
{
	DB_ROW				row;
	DB_RESULT			result;
	int				i;
	char				*sql = NULL;
	size_t				sql_alloc = 0, sql_offset = 0;
	zbx_event_suppress_query_t	*query;
	zbx_vector_uint64_t		eventids;
	zbx_uint64_t			eventid;
	zbx_tag_t			*tag;

	zbx_vector_uint64_create(&eventids);

	for (i = 0; i < event_queries->values_num; i++)
	{
		query = (zbx_event_suppress_query_t *)event_queries->values[i];
		zbx_vector_uint64_append(&eventids, query->eventid);
	}

	zbx_strcpy_alloc(&sql, &sql_alloc, &sql_offset, "select eventid,tag,value from problem_tag where");
	DBadd_condition_alloc(&sql, &sql_alloc, &sql_offset, "eventid", eventids.values, eventids.values_num);
	zbx_strcpy_alloc(&sql, &sql_alloc, &sql_offset, " order by eventid");

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

	i = 0;
	query = (zbx_event_suppress_query_t *)event_queries->values[0];

	while (NULL != (row = DBfetch(result)))
	{
		ZBX_STR2UINT64(eventid, row[0]);

		while (query->eventid != eventid)
			query = (zbx_event_suppress_query_t *)event_queries->values[++i];

		tag = (zbx_tag_t *)zbx_malloc(NULL, sizeof(zbx_tag_t));
		tag->tag = zbx_strdup(NULL, row[1]);
		tag->value = zbx_strdup(NULL, row[2]);
		zbx_vector_ptr_append(&query->tags, tag);
	}
	DBfree_result(result);

	zbx_vector_uint64_destroy(&eventids);
}
コード例 #9
0
static void	get_50_version(char **os, size_t *os_alloc, size_t *os_offset, OSVERSIONINFOEX *vi)
{
	zbx_strcpy_alloc(os, os_alloc, os_offset, " Microsoft Windows 2000");

	if (VER_NT_WORKSTATION != vi->wProductType)
	{
		if (0 != (vi->wSuiteMask & VER_SUITE_DATACENTER))
			zbx_strcpy_alloc(os, os_alloc, os_offset, " Datacenter Server");
		else if (0 != (vi->wSuiteMask & VER_SUITE_ENTERPRISE))
			zbx_strcpy_alloc(os, os_alloc, os_offset, " Advanced Server");
		else
			zbx_strcpy_alloc(os, os_alloc, os_offset, " Server");
	}
	else
		zbx_strcpy_alloc(os, os_alloc, os_offset, " Professional");

}
コード例 #10
0
ファイル: dbupgrade.c プロジェクト: HupuInc/zabbix
static void	DBcreate_table_sql(char **sql, size_t *sql_alloc, size_t *sql_offset, const ZBX_TABLE *table)
{
	int	i;

	zbx_snprintf_alloc(sql, sql_alloc, sql_offset, "create table %s (\n", table->table);

	for (i = 0; NULL != table->fields[i].name; i++)
	{
		if (0 != i)
			zbx_strcpy_alloc(sql, sql_alloc, sql_offset, ",\n");
		DBfield_definition_string(sql, sql_alloc, sql_offset, &table->fields[i]);
	}
	if ('\0' != *table->recid)
		zbx_snprintf_alloc(sql, sql_alloc, sql_offset, ",\nprimary key (%s)", table->recid);

	zbx_strcpy_alloc(sql, sql_alloc, sql_offset, "\n)" ZBX_DB_TABLE_OPTIONS);
}
コード例 #11
0
ファイル: listener.c プロジェクト: zabbix/zabbix
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());
}
コード例 #12
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;
}
コード例 #13
0
ファイル: dbupgrade.c プロジェクト: HupuInc/zabbix
static void	DBadd_foreign_key_sql(char **sql, size_t *sql_alloc, size_t *sql_offset,
		const char *table_name, int id, const ZBX_FIELD *field)
{
	zbx_snprintf_alloc(sql, sql_alloc, sql_offset,
			"alter table %s add constraint c_%s_%d foreign key (%s) references %s (%s)",
			table_name, table_name, id, field->name, field->fk_table, field->fk_field);
	if (0 != (field->fk_flags & ZBX_FK_CASCADE_DELETE))
		zbx_strcpy_alloc(sql, sql_alloc, sql_offset, " on delete cascade");
}
コード例 #14
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);
	}
}
コード例 #15
0
static void	begin_history_sql(char **sql, size_t *sql_alloc, size_t *sql_offset, const ZBX_TABLE *table)
{
	int	f;

	zbx_snprintf_alloc(sql, sql_alloc, sql_offset, "insert into %s (", table->table);

	if (0 != (table->flags & ZBX_HISTORY_SYNC))
		zbx_strcpy_alloc(sql, sql_alloc, sql_offset, "nodeid,");

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

		zbx_snprintf_alloc(sql, sql_alloc, sql_offset, "%s,", table->fields[f].name);
	}

	(*sql_offset)--;
	zbx_strcpy_alloc(sql, sql_alloc, sql_offset, ") values ");
}
コード例 #16
0
ファイル: dbupgrade.c プロジェクト: HupuInc/zabbix
static void	DBfield_type_string(char **sql, size_t *sql_alloc, size_t *sql_offset, const ZBX_FIELD *field)
{
	switch (field->type)
	{
		case ZBX_TYPE_ID:
			zbx_strcpy_alloc(sql, sql_alloc, sql_offset, ZBX_TYPE_ID_STR);
			break;
		case ZBX_TYPE_INT:
			zbx_strcpy_alloc(sql, sql_alloc, sql_offset, ZBX_TYPE_INT_STR);
			break;
		case ZBX_TYPE_CHAR:
			zbx_snprintf_alloc(sql, sql_alloc, sql_offset, "%s(%hu)", ZBX_TYPE_CHAR_STR, field->length);
			break;
		case ZBX_TYPE_FLOAT:
			zbx_strcpy_alloc(sql, sql_alloc, sql_offset, ZBX_TYPE_FLOAT_STR);
			break;
		case ZBX_TYPE_UINT:
			zbx_strcpy_alloc(sql, sql_alloc, sql_offset, ZBX_TYPE_UINT_STR);
			break;
		case ZBX_TYPE_SHORTTEXT:
			zbx_strcpy_alloc(sql, sql_alloc, sql_offset, ZBX_TYPE_SHORTTEXT_STR);
			break;
		case ZBX_TYPE_TEXT:
			zbx_strcpy_alloc(sql, sql_alloc, sql_offset, ZBX_TYPE_TEXT_STR);
			break;
		default:
			assert(0);
	}
}
コード例 #17
0
ファイル: email.c プロジェクト: dreamsxin/zabbix
/******************************************************************************
 *                                                                            *
 * Function: str_base64_encode_rfc2047                                        *
 *                                                                            *
 * Purpose: Encode a string into a base64 string as required by rfc2047.      *
 *          Used for encoding e-mail headers.                                 *
 *                                                                            *
 * Parameters: src      - [IN] a null-terminated UTF-8 string to encode       *
 *             p_base64 - [OUT] a pointer to the encoded string               *
 *                                                                            *
 * Comments: Based on the patch submitted by                                  *
 *           Jairo Eduardo Lopez Fuentes Nacarino                             *
 *                                                                            *
 ******************************************************************************/
static void	str_base64_encode_rfc2047(const char *src, char **p_base64)
{
	const char	*p0;			/* pointer in src to start encoding from */
	const char	*p1;			/* pointer in src: 1st byte of UTF-8 character */
	size_t		c_len;			/* length of UTF-8 character sequence */
	size_t		p_base64_alloc;		/* allocated memory size for subject */
	size_t		p_base64_offset = 0;	/* offset for writing into subject */

	assert(src);
	assert(NULL == *p_base64);		/* do not accept already allocated memory */

	p_base64_alloc = ZBX_EMAIL_B64_MAXWORD_RFC2047 + sizeof(ZBX_EMAIL_ENCODED_WORD_SEPARATOR);
	*p_base64 = zbx_malloc(NULL, p_base64_alloc);
	**p_base64 = '\0';

	for (p0 = src; '\0' != *p0; p0 = p1)
	{
		/* Max length of line is 76 characters (without line separator). */
		/* Max length of "encoded-word" is 75 characters (without word separator). */
		/* 3 characters are taken by word separator "<CR><LF><Space>" which also includes the line separator. */
		/* 12 characters are taken by header "=?UTF-8?B?" and trailer "?=". */
		/* So, one "encoded-word" can hold up to 63 characters of Base64-encoded string. */
		/* Encoding 45 bytes produces a 61 byte long Base64-encoded string which meets the limit. */
		/* Encoding 46 bytes produces a 65 byte long Base64-encoded string which exceeds the limit. */
		for (p1 = p0, c_len = 0; '\0' != *p1; p1 += c_len)
		{
			/* an invalid UTF-8 character or length of a string more than 45 bytes */
			if (0 == (c_len = zbx_utf8_char_len(p1)) || 45 < p1 - p0 + c_len)
				break;
		}

		if (0 < p1 - p0)
		{
			/* 12 characters are taken by header "=?UTF-8?B?" and trailer "?=" plus '\0' */
			char	b64_buf[ZBX_EMAIL_B64_MAXWORD_RFC2047 - 12 + 1];

			str_base64_encode(p0, b64_buf, p1 - p0);

			if (0 != p_base64_offset)	/* not the first "encoded-word" ? */
			{
				zbx_strcpy_alloc(p_base64, &p_base64_alloc, &p_base64_offset,
						ZBX_EMAIL_ENCODED_WORD_SEPARATOR);
			}

			zbx_snprintf_alloc(p_base64, &p_base64_alloc, &p_base64_offset, "=?UTF-8?B?%s?=", b64_buf);
		}
		else
			break;
	}
}
コード例 #18
0
ファイル: events.c プロジェクト: Metalaria/Zabbix_
/******************************************************************************
 *                                                                            *
 * Function: save_events                                                      *
 *                                                                            *
 * Purpose: flushes the events into a database                                *
 *                                                                            *
 ******************************************************************************/
static void	save_events()
{
	char		*sql = NULL;
	size_t		sql_alloc = 2 * ZBX_KIBIBYTE, sql_offset = 0, i;
	const char	*ins_event_sql = "insert into events (eventid,source,object,objectid,clock,ns,value) values ";

	sql = zbx_malloc(sql, sql_alloc);

	DBbegin_multiple_update(&sql, &sql_alloc, &sql_offset);

#ifdef HAVE_MULTIROW_INSERT
	zbx_strcpy_alloc(&sql, &sql_alloc, &sql_offset, ins_event_sql);
#endif

	for (i = 0; i < events_num; i++)
	{
		if (0 == events[i].eventid)
			events[i].eventid = DBget_maxid("events");
#ifndef HAVE_MULTIROW_INSERT
		zbx_strcpy_alloc(&sql, &sql_alloc, &sql_offset, ins_event_sql);
#endif
		zbx_snprintf_alloc(&sql, &sql_alloc, &sql_offset,
			"(" ZBX_FS_UI64 ",%d,%d," ZBX_FS_UI64 ",%d,%d,%d)" ZBX_ROW_DL,
			events[i].eventid, events[i].source, events[i].object, events[i].objectid, events[i].clock,
			events[i].ns, events[i].value);
	}

#ifdef HAVE_MULTIROW_INSERT
	sql_offset--;
	zbx_strcpy_alloc(&sql, &sql_alloc, &sql_offset, ";\n");
#endif
	DBend_multiple_update(&sql, &sql_alloc, &sql_offset);

	DBexecute("%s", sql);

	zbx_free(sql);
}
コード例 #19
0
ファイル: taskmanager.c プロジェクト: zabbix/zabbix
/******************************************************************************
 *                                                                            *
 * Function: tm_process_check_now                                             *
 *                                                                            *
 * Purpose: process check now tasks for item rescheduling                     *
 *                                                                            *
 * Return value: The number of successfully processed tasks                   *
 *                                                                            *
 ******************************************************************************/
static int	tm_process_check_now(zbx_vector_uint64_t *taskids)
{
	DB_ROW			row;
	DB_RESULT		result;
	int			processed_num;
	char			*sql = NULL;
	size_t			sql_alloc = 0, sql_offset = 0;
	zbx_vector_uint64_t	itemids;
	zbx_uint64_t		itemid;

	zabbix_log(LOG_LEVEL_DEBUG, "In %s() tasks_num:%d", __func__, taskids->values_num);

	zbx_vector_uint64_create(&itemids);

	zbx_strcpy_alloc(&sql, &sql_alloc, &sql_offset, "select itemid from task_check_now where");
	DBadd_condition_alloc(&sql, &sql_alloc, &sql_offset, "taskid", taskids->values, taskids->values_num);
	result = DBselect("%s", sql);

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

	if (0 != (processed_num = itemids.values_num))
		zbx_dc_reschedule_items(&itemids, time(NULL), NULL);

	if (0 != taskids->values_num)
	{
		sql_offset = 0;
		zbx_snprintf_alloc(&sql, &sql_alloc, &sql_offset, "update task set status=%d where",
				ZBX_TM_STATUS_DONE);
		DBadd_condition_alloc(&sql, &sql_alloc, &sql_offset, "taskid", taskids->values, taskids->values_num);

		DBexecute("%s", sql);
	}

	zbx_free(sql);
	zbx_vector_uint64_destroy(&itemids);

	zabbix_log(LOG_LEVEL_DEBUG, "End of %s() processed:%d", __func__, processed_num);

	return processed_num;
}
コード例 #20
0
ファイル: execute.c プロジェクト: cloud-zhao/zabbix_self
/******************************************************************************
 *                                                                            *
 * Function: zbx_read_from_pipe                                               *
 *                                                                            *
 * Purpose: read data from pipe                                               *
 *                                                                            *
 * Parameters: hRead         - [IN] a handle to the device                    *
 *             buf           - [IN/OUT] a pointer to the buffer               *
 *             buf_size      - [IN] buffer size                               *
 *             offset        - [IN/OUT] current position in the buffer        *
 *             timeout_ms    - [IN] timeout in milliseconds                   *
 *                                                                            *
 * Return value: SUCCEED, FAIL or TIMEOUT_ERROR if timeout reached            *
 *                                                                            *
 * Author: Alexander Vladishev                                                *
 *                                                                            *
 ******************************************************************************/
static int	zbx_read_from_pipe(HANDLE hRead, char **buf, size_t *buf_size, size_t *offset, int timeout_ms)
{
	DWORD		in_buf_size, read_bytes;
	struct _timeb	start_time, current_time;
	char 		tmp_buf[PIPE_BUFFER_SIZE];

	_ftime(&start_time);

	while (0 != PeekNamedPipe(hRead, NULL, 0, NULL, &in_buf_size, NULL))
	{
		_ftime(&current_time);
		if (zbx_get_timediff_ms(&start_time, &current_time) >= timeout_ms)
			return TIMEOUT_ERROR;

		if (MAX_EXECUTE_OUTPUT_LEN <= *offset + in_buf_size)
		{
			zabbix_log(LOG_LEVEL_ERR, "command output exceeded limit of %d KB",
					MAX_EXECUTE_OUTPUT_LEN / ZBX_KIBIBYTE);
			return FAIL;
		}

		if (0 != in_buf_size)
		{
			if (0 == ReadFile(hRead, tmp_buf, sizeof(tmp_buf) - 1, &read_bytes, NULL))
			{
				zabbix_log(LOG_LEVEL_ERR, "cannot read command output: %s",
						strerror_from_system(GetLastError()));
				return FAIL;
			}

			if (NULL != buf)
			{
				tmp_buf[read_bytes] = '\0';
				zbx_strcpy_alloc(buf, buf_size, offset, tmp_buf);
			}

			in_buf_size = 0;
			continue;
		}

		Sleep(20);	/* milliseconds */
	}

	return SUCCEED;
}
コード例 #21
0
ファイル: nodesync.c プロジェクト: gheja/zabbix-ext
static void	make_delete_sql(char **sql, size_t *sql_alloc, size_t *sql_offset,
		const ZBX_TABLE *table, zbx_uint64_t *ids, int *ids_num)
{
	if (NULL == table)
		return;

	if (0 == *ids_num)
		return;

	zbx_snprintf_alloc(sql, sql_alloc, sql_offset, "delete from %s where", table->table);

	DBadd_condition_alloc(sql, sql_alloc, sql_offset, table->recid, ids, *ids_num);

	zbx_strcpy_alloc(sql, sql_alloc, sql_offset, ";\n");

	DBexecute_overflowed_sql(sql, sql_alloc, sql_offset);

	*ids_num = 0;
}
コード例 #22
0
static void	get_51_version(char **os, size_t *os_alloc, size_t *os_offset, OSVERSIONINFOEX *vi)
{
	zbx_strcpy_alloc(os, os_alloc, os_offset, " Microsoft Windows XP");

	if (0 != GetSystemMetrics(87))		/* SM_MEDIACENTER */
		zbx_strcpy_alloc(os, os_alloc, os_offset, " Media Center Edition");
	else if (0 != GetSystemMetrics(88))	/* SM_STARTER */
		zbx_strcpy_alloc(os, os_alloc, os_offset, " Starter Edition");
	else if (0 != GetSystemMetrics(86))	/* SM_TABLETPC */
		zbx_strcpy_alloc(os, os_alloc, os_offset, " Tablet PC Edition");
	else if (0 != (vi->wSuiteMask & VER_SUITE_PERSONAL))
		zbx_strcpy_alloc(os, os_alloc, os_offset, " Home Edition");
	else
		zbx_strcpy_alloc(os, os_alloc, os_offset, " Professional");
}
コード例 #23
0
ファイル: timer.c プロジェクト: zabbix/zabbix
/******************************************************************************
 *                                                                            *
 * Function: log_host_maintenance_update                                      *
 *                                                                            *
 * Purpose: log host maintenance changes                                      *
 *                                                                            *
 ******************************************************************************/
static void	log_host_maintenance_update(const zbx_host_maintenance_diff_t* diff)
{
	char	*msg = NULL;
	size_t	msg_alloc = 0, msg_offset = 0;
	int	maintenance_off = 0;

	if (0 != (diff->flags & ZBX_FLAG_HOST_MAINTENANCE_UPDATE_MAINTENANCE_STATUS))
	{
		if (HOST_MAINTENANCE_STATUS_ON == diff->maintenance_status)
		{
			zbx_snprintf_alloc(&msg, &msg_alloc, &msg_offset, "putting host (" ZBX_FS_UI64 ") into",
					diff->hostid);
		}
		else
		{
			maintenance_off = 1;
			zbx_snprintf_alloc(&msg, &msg_alloc, &msg_offset, "taking host (" ZBX_FS_UI64 ") out of",
				diff->hostid);
		}
	}
	else
		zbx_snprintf_alloc(&msg, &msg_alloc, &msg_offset, "changing host (" ZBX_FS_UI64 ")", diff->hostid);

	zbx_strcpy_alloc(&msg, &msg_alloc, &msg_offset, " maintenance");

	if (0 != (diff->flags & ZBX_FLAG_HOST_MAINTENANCE_UPDATE_MAINTENANCEID) && 0 != diff->maintenanceid)
		zbx_snprintf_alloc(&msg, &msg_alloc, &msg_offset, "(" ZBX_FS_UI64 ")", diff->maintenanceid);


	if (0 != (diff->flags & ZBX_FLAG_HOST_MAINTENANCE_UPDATE_MAINTENANCE_TYPE) && 0 == maintenance_off)
	{
		const char	*desription[] = {"with data collection", "without data collection"};

		zbx_snprintf_alloc(&msg, &msg_alloc, &msg_offset, " %s", desription[diff->maintenance_type]);
	}

	zabbix_log(LOG_LEVEL_DEBUG, "%s", msg);
	zbx_free(msg);
}
コード例 #24
0
ファイル: nodesender.c プロジェクト: nabnut/zabbix2.0-cookies
/******************************************************************************
 *                                                                            *
 * 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;
}
コード例 #25
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;
}
コード例 #26
0
/******************************************************************************
 *                                                                            *
 * 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);
}
コード例 #27
0
/******************************************************************************
 *                                                                            *
 * Function: save_template_item_applications                                  *
 *                                                                            *
 * Purpose: saves new item applications links in database                     *
 *                                                                            *
 * Parameters:  items   - [IN] the template items                             *
 *                                                                            *
 ******************************************************************************/
void	save_template_item_applications(zbx_vector_ptr_t *items)
{
	typedef struct
	{
		zbx_uint64_t	itemid;
		zbx_uint64_t	applicationid;
	}
	zbx_itemapp_t;

	DB_RESULT		result;
	DB_ROW			row;
	char			*sql = NULL;
	size_t			sql_alloc = 0, sql_offset = 0;
	zbx_vector_uint64_t	itemids;
	zbx_vector_ptr_t	itemapps;
	zbx_itemapp_t		*itemapp;
	int 			i;
	zbx_db_insert_t		db_insert;

	zbx_vector_ptr_create(&itemapps);
	zbx_vector_uint64_create(&itemids);

	for (i = 0; i < items->values_num; i++)
	{
		zbx_template_item_t	*item = items->values[i];

		zbx_vector_uint64_append(&itemids, item->itemid);
	}

	zbx_vector_uint64_sort(&itemids, ZBX_DEFAULT_UINT64_COMPARE_FUNC);

	zbx_strcpy_alloc(&sql, &sql_alloc, &sql_offset,
			"select hi.itemid,ha.applicationid"
			" from items_applications tia"
				" join items hi on hi.templateid=tia.itemid"
					" and");
	DBadd_condition_alloc(&sql, &sql_alloc, &sql_offset, "hi.itemid", itemids.values, itemids.values_num);
	zbx_strcpy_alloc(&sql, &sql_alloc, &sql_offset,
				" join application_template hat on hat.templateid=tia.applicationid"
				" join applications ha on ha.applicationid=hat.applicationid"
					" and ha.hostid=hi.hostid"
					" left join items_applications hia on hia.applicationid=ha.applicationid"
						" and hia.itemid=hi.itemid"
			" where hia.itemappid is null");

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

	while (NULL != (row = DBfetch(result)))
	{
		itemapp = zbx_malloc(NULL, sizeof(zbx_itemapp_t));

		ZBX_STR2UINT64(itemapp->itemid, row[0]);
		ZBX_STR2UINT64(itemapp->applicationid, row[1]);

		zbx_vector_ptr_append(&itemapps, itemapp);
	}
	DBfree_result(result);

	if (0 == itemapps.values_num)
		goto out;

	zbx_db_insert_prepare(&db_insert, "items_applications", "itemappid", "itemid", "applicationid", NULL);

	for (i = 0; i < itemapps.values_num; i++)
	{
		itemapp = itemapps.values[i];

		zbx_db_insert_add_values(&db_insert, __UINT64_C(0), itemapp->itemid, itemapp->applicationid);
	}

	zbx_db_insert_autoincrement(&db_insert, "itemappid");
	zbx_db_insert_execute(&db_insert);
	zbx_db_insert_clean(&db_insert);
out:
	zbx_free(sql);

	zbx_vector_uint64_destroy(&itemids);

	zbx_vector_ptr_clear_ext(&itemapps, zbx_ptr_free);
	zbx_vector_ptr_destroy(&itemapps);
}
コード例 #28
0
/******************************************************************************
 *                                                                            *
 * Function: save_template_lld_rules                                          *
 *                                                                            *
 * Purpose: saves template lld rule item conditions to the target host in     *
 *          database                                                          *
 *                                                                            *
 * Parameters:  items          - [IN] the template items                      *
 *              rules          - [IN] the ldd rule mapping                    *
 *              new_conditions - [IN] the number of new item conditions to    *
 *                                    be inserted                             *
 *                                                                            *
 ******************************************************************************/
static void	save_template_lld_rules(zbx_vector_ptr_t *items, zbx_vector_ptr_t *rules, int new_conditions)
{
	char				*macro_esc, *value_esc;
	int				i, j, index;
	zbx_db_insert_t			db_insert;
	zbx_lld_rule_map_t		*rule;
	zbx_lld_rule_condition_t	*condition;
	char				*sql = NULL;
	size_t				sql_alloc = 0, sql_offset = 0;
	zbx_vector_uint64_t		item_conditionids;

	if (0 == rules->values_num)
		return;

	zbx_vector_uint64_create(&item_conditionids);

	if (0 != new_conditions)
	{
		zbx_db_insert_prepare(&db_insert, "item_condition", "item_conditionid", "itemid", "operator", "macro",
				"value", NULL);

		/* insert lld rule conditions for new items */
		for (i = 0; i < items->values_num; i++)
		{
			zbx_template_item_t	*item = items->values[i];

			if (NULL == item->key)
				continue;

			if (0 == (ZBX_FLAG_DISCOVERY_RULE & item->flags))
				continue;

			index = zbx_vector_ptr_bsearch(rules, &item->templateid, ZBX_DEFAULT_UINT64_PTR_COMPARE_FUNC);

			if (FAIL == index)
			{
				THIS_SHOULD_NEVER_HAPPEN;
				continue;
			}

			rule = rules->values[index];

			for (j = 0; j < rule->conditions.values_num; j++)
			{
				condition = rule->conditions.values[j];

				zbx_db_insert_add_values(&db_insert, rule->conditionid++, item->itemid,
						(int)condition->operator, condition->macro, condition->value);
			}
		}
	}

	DBbegin_multiple_update(&sql, &sql_alloc, &sql_offset);

	/* update lld rule conditions for existing items */
	for (i = 0; i < rules->values_num; i++)
	{
		rule = rules->values[i];

		/* skip lld rules of new items */
		if (0 == rule->itemid)
			continue;

		index = MIN(rule->conditions.values_num, rule->conditionids.values_num);

		/* update intersecting rule conditions */
		for (j = 0; j < index; j++)
		{
			condition = rule->conditions.values[j];

			macro_esc = DBdyn_escape_string(condition->macro);
			value_esc = DBdyn_escape_string(condition->value);

			zbx_snprintf_alloc(&sql, &sql_alloc, &sql_offset, "update item_condition"
					" set operator=%d,macro='%s',value='%s'"
					" where item_conditionid=" ZBX_FS_UI64 ";\n",
					(int)condition->operator, macro_esc, value_esc, rule->conditionids.values[j]);

			DBexecute_overflowed_sql(&sql, &sql_alloc, &sql_offset);

			zbx_free(value_esc);
			zbx_free(macro_esc);
		}

		/* delete removed rule conditions */
		for (j = index; j < rule->conditionids.values_num; j++)
			zbx_vector_uint64_append(&item_conditionids, rule->conditionids.values[j]);

		/* insert new rule conditions */
		for (j = index; j < rule->conditions.values_num; j++)
		{
			condition = rule->conditions.values[j];

			zbx_db_insert_add_values(&db_insert, rule->conditionid++, rule->itemid,
					(int)condition->operator, condition->macro, condition->value);
		}
	}

	/* delete removed item conditions */
	if (0 != item_conditionids.values_num)
	{
		zbx_strcpy_alloc(&sql, &sql_alloc, &sql_offset, "delete from item_condition where");
		DBadd_condition_alloc(&sql, &sql_alloc, &sql_offset, "item_conditionid", item_conditionids.values,
				item_conditionids.values_num);
		zbx_strcpy_alloc(&sql, &sql_alloc, &sql_offset, ";\n");
	}

	DBend_multiple_update(&sql, &sql_alloc, &sql_offset);

	if (16 < sql_offset)
		DBexecute("%s", sql);

	if (0 != new_conditions)
	{
		zbx_db_insert_execute(&db_insert);
		zbx_db_insert_clean(&db_insert);
	}

	zbx_free(sql);
	zbx_vector_uint64_destroy(&item_conditionids);
}
コード例 #29
0
/******************************************************************************
 *                                                                            *
 * Function: get_template_lld_rule_map                                        *
 *                                                                            *
 * Purpose: reads template lld rule conditions and host lld_rule identifiers  *
 *          from database                                                     *
 *                                                                            *
 * Parameters: items - [IN] the host items including lld rules                *
 *             rules - [OUT] the ldd rule mapping                             *
 *                                                                            *
 ******************************************************************************/
static void	get_template_lld_rule_map(const zbx_vector_ptr_t *items, zbx_vector_ptr_t *rules)
{
	zbx_template_item_t		*item;
	zbx_lld_rule_map_t		*rule;
	zbx_lld_rule_condition_t	*condition;
	int				i, index;
	zbx_vector_uint64_t		itemids;
	DB_RESULT			result;
	DB_ROW				row;
	char				*sql = NULL;
	size_t				sql_alloc = 0, sql_offset = 0;
	zbx_uint64_t			itemid, item_conditionid;

	zbx_vector_uint64_create(&itemids);

	/* prepare discovery rules */
	for (i = 0; i < items->values_num; i++)
	{
		item = items->values[i];

		if (0 == (ZBX_FLAG_DISCOVERY_RULE & item->flags))
			continue;

		rule = zbx_malloc(NULL, sizeof(zbx_lld_rule_map_t));

		rule->itemid = item->itemid;
		rule->templateid = item->templateid;
		rule->conditionid = 0;
		zbx_vector_uint64_create(&rule->conditionids);
		zbx_vector_ptr_create(&rule->conditions);

		zbx_vector_ptr_append(rules, rule);

		if (0 != rule->itemid)
			zbx_vector_uint64_append(&itemids, rule->itemid);
		zbx_vector_uint64_append(&itemids, rule->templateid);
	}

	if (0 != itemids.values_num)
	{
		zbx_vector_ptr_sort(rules, ZBX_DEFAULT_UINT64_PTR_COMPARE_FUNC);
		zbx_vector_uint64_sort(&itemids, ZBX_DEFAULT_UINT64_COMPARE_FUNC);

		zbx_strcpy_alloc(&sql, &sql_alloc, &sql_offset,
				"select item_conditionid,itemid,operator,macro,value from item_condition where");
		DBadd_condition_alloc(&sql, &sql_alloc, &sql_offset, "itemid", itemids.values, itemids.values_num);

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

		while (NULL != (row = DBfetch(result)))
		{
			ZBX_STR2UINT64(itemid, row[1]);

			index = zbx_vector_ptr_bsearch(rules, &itemid, ZBX_DEFAULT_UINT64_PTR_COMPARE_FUNC);

			if (FAIL != index)
			{
				/* read template lld conditions */

				rule = (zbx_lld_rule_map_t *)rules->values[index];

				condition = zbx_malloc(NULL, sizeof(zbx_lld_rule_condition_t));

				ZBX_STR2UINT64(condition->item_conditionid, row[0]);
				ZBX_STR2UCHAR(condition->operator, row[2]);
				condition->macro = zbx_strdup(NULL, row[3]);
				condition->value = zbx_strdup(NULL, row[4]);

				zbx_vector_ptr_append(&rule->conditions, condition);
			}
			else
			{
				/* read host lld conditions identifiers */

				for (i = 0; i < rules->values_num; i++)
				{
					rule = (zbx_lld_rule_map_t *)rules->values[i];

					if (itemid != rule->itemid)
						continue;

					ZBX_STR2UINT64(item_conditionid, row[0]);
					zbx_vector_uint64_append(&rule->conditionids, item_conditionid);

					break;
				}

				if (i == rules->values_num)
					THIS_SHOULD_NEVER_HAPPEN;
			}
		}
		DBfree_result(result);

		zbx_free(sql);
	}

	zbx_vector_uint64_destroy(&itemids);
}
コード例 #30
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;

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

	zbx_vector_uint64_create(&housekeeperids);

	/* order by tablename to effectively use DB cache */
	result = DBselect(
			"select housekeeperid,tablename,field,value"
			" from housekeeper"
			" order by tablename");

	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 (0 == d || 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)
	{
		char	*sql = NULL;
		size_t	sql_alloc = 512, sql_offset = 0;

		sql = zbx_malloc(sql, sql_alloc);

		zbx_vector_uint64_sort(&housekeeperids, ZBX_DEFAULT_UINT64_COMPARE_FUNC);

		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);

	zabbix_log(LOG_LEVEL_DEBUG, "End of %s():%d", __function_name, deleted);

	return deleted;
}