1 /*
2 ** Zabbix
3 ** Copyright (C) 2001-2021 Zabbix SIA
4 **
5 ** This program is free software; you can redistribute it and/or modify
6 ** it under the terms of the GNU General Public License as published by
7 ** the Free Software Foundation; either version 2 of the License, or
8 ** (at your option) any later version.
9 **
10 ** This program is distributed in the hope that it will be useful,
11 ** but WITHOUT ANY WARRANTY; without even the implied warranty of
12 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 ** GNU General Public License for more details.
14 **
15 ** You should have received a copy of the GNU General Public License
16 ** along with this program; if not, write to the Free Software
17 ** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
18 **/
19 
20 #include "common.h"
21 #include "checks_internal.h"
22 #include "checks_java.h"
23 #include "dbcache.h"
24 #include "zbxself.h"
25 #include "valuecache.h"
26 #include "proxy.h"
27 
28 #include "../vmware/vmware.h"
29 
30 extern unsigned char	program_type;
31 
32 /******************************************************************************
33  *                                                                            *
34  * Function: get_value_internal                                               *
35  *                                                                            *
36  * Purpose: retrieve data from Zabbix server (internally supported items)     *
37  *                                                                            *
38  * Parameters: item - item we are interested in                               *
39  *                                                                            *
40  * Return value: SUCCEED - data successfully retrieved and stored in result   *
41  *               NOTSUPPORTED - requested item is not supported               *
42  *                                                                            *
43  * Author: Alexei Vladishev                                                   *
44  *                                                                            *
45  ******************************************************************************/
get_value_internal(DC_ITEM * item,AGENT_RESULT * result)46 int	get_value_internal(DC_ITEM *item, AGENT_RESULT *result)
47 {
48 	AGENT_REQUEST	request;
49 	int		ret = NOTSUPPORTED, nparams;
50 	const char	*tmp, *tmp1;
51 
52 	init_result(result);
53 	init_request(&request);
54 
55 	if (SUCCEED != parse_item_key(item->key, &request))
56 	{
57 		SET_MSG_RESULT(result, zbx_strdup(NULL, "Invalid item key format."));
58 		goto out;
59 	}
60 
61 	if (0 != strcmp("zabbix", get_rkey(&request)))
62 	{
63 		SET_MSG_RESULT(result, zbx_strdup(NULL, "Unsupported item key for this item type."));
64 		goto out;
65 	}
66 
67 	if (0 == (nparams = get_rparams_num(&request)))
68 	{
69 		SET_MSG_RESULT(result, zbx_strdup(NULL, "Invalid number of parameters."));
70 		goto out;
71 	}
72 
73 	tmp = get_rparam(&request, 0);
74 
75 	if (0 == strcmp(tmp, "triggers"))			/* zabbix["triggers"] */
76 	{
77 		if (0 == (program_type & ZBX_PROGRAM_TYPE_SERVER))
78 			goto out;
79 
80 		if (1 != nparams)
81 		{
82 			SET_MSG_RESULT(result, zbx_strdup(NULL, "Invalid number of parameters."));
83 			goto out;
84 		}
85 
86 		SET_UI64_RESULT(result, DCget_trigger_count());
87 	}
88 	else if (0 == strcmp(tmp, "items"))			/* zabbix["items"] */
89 	{
90 		if (1 != nparams)
91 		{
92 			SET_MSG_RESULT(result, zbx_strdup(NULL, "Invalid number of parameters."));
93 			goto out;
94 		}
95 
96 		SET_UI64_RESULT(result, DCget_item_count(0));
97 	}
98 	else if (0 == strcmp(tmp, "items_unsupported"))		/* zabbix["items_unsupported"] */
99 	{
100 		if (1 != nparams)
101 		{
102 			SET_MSG_RESULT(result, zbx_strdup(NULL, "Invalid number of parameters."));
103 			goto out;
104 		}
105 
106 		SET_UI64_RESULT(result, DCget_item_unsupported_count(0));
107 	}
108 	else if (0 == strcmp(tmp, "hosts"))			/* zabbix["hosts"] */
109 	{
110 		if (1 != nparams)
111 		{
112 			SET_MSG_RESULT(result, zbx_strdup(NULL, "Invalid number of parameters."));
113 			goto out;
114 		}
115 
116 		SET_UI64_RESULT(result, DCget_host_count());
117 	}
118 	else if (0 == strcmp(tmp, "history") ||			/* zabbix["history"] */
119 			0 == strcmp(tmp, "history_log") ||	/* zabbix["history_log"] */
120 			0 == strcmp(tmp, "history_str") ||	/* zabbix["history_str"] */
121 			0 == strcmp(tmp, "history_text") ||	/* zabbix["history_text"] */
122 			0 == strcmp(tmp, "history_uint"))	/* zabbix["history_uint"] */
123 	{
124 		if (0 == (program_type & ZBX_PROGRAM_TYPE_SERVER))
125 			goto out;
126 
127 		if (1 != nparams)
128 		{
129 			SET_MSG_RESULT(result, zbx_strdup(NULL, "Invalid number of parameters."));
130 			goto out;
131 		}
132 
133 		SET_UI64_RESULT(result, DBget_row_count(tmp));
134 	}
135 	else if (0 == strcmp(tmp, "trends") ||			/* zabbix["trends"] */
136 			0 == strcmp(tmp, "trends_uint"))	/* zabbix["trends_uint"] */
137 	{
138 		if (0 == (program_type & ZBX_PROGRAM_TYPE_SERVER))
139 			goto out;
140 
141 		if (1 != nparams)
142 		{
143 			SET_MSG_RESULT(result, zbx_strdup(NULL, "Invalid number of parameters."));
144 			goto out;
145 		}
146 
147 		SET_UI64_RESULT(result, DBget_row_count(tmp));
148 	}
149 	else if (0 == strcmp(tmp, "queue"))			/* zabbix["queue",<from>,<to>] */
150 	{
151 		int	from = ZBX_QUEUE_FROM_DEFAULT, to = ZBX_QUEUE_TO_INFINITY;
152 
153 		if (3 < nparams)
154 		{
155 			SET_MSG_RESULT(result, zbx_strdup(NULL, "Invalid number of parameters."));
156 			goto out;
157 		}
158 
159 		if (NULL != (tmp = get_rparam(&request, 1)) && '\0' != *tmp && FAIL == is_time_suffix(tmp, &from))
160 		{
161 			SET_MSG_RESULT(result, zbx_strdup(NULL, "Invalid second parameter."));
162 			goto out;
163 		}
164 
165 		if (NULL != (tmp = get_rparam(&request, 2)) && '\0' != *tmp && FAIL == is_time_suffix(tmp, &to))
166 		{
167 			SET_MSG_RESULT(result, zbx_strdup(NULL, "Invalid third parameter."));
168 			goto out;
169 		}
170 
171 		if (ZBX_QUEUE_TO_INFINITY != to && from > to)
172 		{
173 			SET_MSG_RESULT(result, zbx_strdup(NULL, "Parameters represent an invalid interval."));
174 			goto out;
175 		}
176 
177 		SET_UI64_RESULT(result, DCget_item_queue(NULL, from, to));
178 	}
179 	else if (0 == strcmp(tmp, "requiredperformance"))	/* zabbix["requiredperformance"] */
180 	{
181 		if (1 != nparams)
182 		{
183 			SET_MSG_RESULT(result, zbx_strdup(NULL, "Invalid number of parameters."));
184 			goto out;
185 		}
186 
187 		SET_DBL_RESULT(result, DCget_required_performance());
188 	}
189 	else if (0 == strcmp(tmp, "uptime"))			/* zabbix["uptime"] */
190 	{
191 		if (1 != nparams)
192 		{
193 			SET_MSG_RESULT(result, zbx_strdup(NULL, "Invalid number of parameters."));
194 			goto out;
195 		}
196 
197 		SET_UI64_RESULT(result, time(NULL) - CONFIG_SERVER_STARTUP_TIME);
198 	}
199 	else if (0 == strcmp(tmp, "boottime"))			/* zabbix["boottime"] */
200 	{
201 		if (1 != nparams)
202 		{
203 			SET_MSG_RESULT(result, zbx_strdup(NULL, "Invalid number of parameters."));
204 			goto out;
205 		}
206 
207 		SET_UI64_RESULT(result, CONFIG_SERVER_STARTUP_TIME);
208 	}
209 	else if (0 == strcmp(tmp, "host"))			/* zabbix["host",*] */
210 	{
211 		if (3 != nparams)
212 		{
213 			SET_MSG_RESULT(result, zbx_strdup(NULL, "Invalid number of parameters."));
214 			goto out;
215 		}
216 
217 		tmp = get_rparam(&request, 2);
218 
219 		if (0 == strcmp(tmp, "available"))		/* zabbix["host",<type>,"available"] */
220 		{
221 			tmp = get_rparam(&request, 1);
222 
223 			if (0 == strcmp(tmp, "agent"))
224 				SET_UI64_RESULT(result, item->host.available);
225 			else if (0 == strcmp(tmp, "snmp"))
226 				SET_UI64_RESULT(result, item->host.snmp_available);
227 			else if (0 == strcmp(tmp, "ipmi"))
228 				SET_UI64_RESULT(result, item->host.ipmi_available);
229 			else if (0 == strcmp(tmp, "jmx"))
230 				SET_UI64_RESULT(result, item->host.jmx_available);
231 			else
232 			{
233 				SET_MSG_RESULT(result, zbx_strdup(NULL, "Invalid second parameter."));
234 				goto out;
235 			}
236 
237 			result->ui64 = 2 - result->ui64;
238 		}
239 		else if (0 == strcmp(tmp, "maintenance"))	/* zabbix["host",,"maintenance"] */
240 		{
241 			/* this item is always processed by server */
242 			if (NULL != (tmp = get_rparam(&request, 1)) && '\0' != *tmp)
243 			{
244 				SET_MSG_RESULT(result, zbx_strdup(NULL, "Invalid second parameter."));
245 				goto out;
246 			}
247 
248 			if (HOST_MAINTENANCE_STATUS_ON == item->host.maintenance_status)
249 				SET_UI64_RESULT(result, item->host.maintenance_type + 1);
250 			else
251 				SET_UI64_RESULT(result, 0);
252 		}
253 		else if (0 == strcmp(tmp, "items"))	/* zabbix["host",,"items"] */
254 		{
255 			/* this item is always processed by server */
256 			if (NULL != (tmp = get_rparam(&request, 1)) && '\0' != *tmp)
257 			{
258 				SET_MSG_RESULT(result, zbx_strdup(NULL, "Invalid second parameter."));
259 				goto out;
260 			}
261 
262 			SET_UI64_RESULT(result, DCget_item_count(item->host.hostid));
263 		}
264 		else if (0 == strcmp(tmp, "items_unsupported"))	/* zabbix["host",,"items_unsupported"] */
265 		{
266 			/* this item is always processed by server */
267 			if (NULL != (tmp = get_rparam(&request, 1)) && '\0' != *tmp)
268 			{
269 				SET_MSG_RESULT(result, zbx_strdup(NULL, "Invalid second parameter."));
270 				goto out;
271 			}
272 
273 			SET_UI64_RESULT(result, DCget_item_unsupported_count(item->host.hostid));
274 		}
275 		else
276 		{
277 			SET_MSG_RESULT(result, zbx_strdup(NULL, "Invalid third parameter."));
278 			goto out;
279 		}
280 
281 	}
282 	else if (0 == strcmp(tmp, "proxy"))			/* zabbix["proxy",<hostname>,"lastaccess"] */
283 	{
284 		int	lastaccess;
285 		char	*error = NULL;
286 
287 		/* this item is always processed by server */
288 
289 		if (3 != nparams)
290 		{
291 			SET_MSG_RESULT(result, zbx_strdup(NULL, "Invalid number of parameters."));
292 			goto out;
293 		}
294 
295 		tmp = get_rparam(&request, 2);
296 		if ('\0' == *tmp || 0 != strcmp(tmp, "lastaccess"))
297 		{
298 			SET_MSG_RESULT(result, zbx_strdup(NULL, "Invalid third parameter."));
299 			goto out;
300 		}
301 
302 		if (FAIL == DBget_proxy_lastaccess(get_rparam(&request, 1), &lastaccess, &error))
303 		{
304 			SET_MSG_RESULT(result, error);
305 			goto out;
306 		}
307 
308 		SET_UI64_RESULT(result, lastaccess);
309 	}
310 	else if (0 == strcmp(tmp, "java"))			/* zabbix["java",...] */
311 	{
312 		int	res;
313 
314 		zbx_alarm_on(CONFIG_TIMEOUT);
315 		res = get_value_java(ZBX_JAVA_GATEWAY_REQUEST_INTERNAL, item, result);
316 		zbx_alarm_off();
317 
318 		if (SUCCEED != res)
319 		{
320 			tmp1 = get_rparam(&request, 2);
321 			/* the default error code "NOTSUPPORTED" renders nodata() trigger function nonfunctional */
322 			if (NULL != tmp1 && 0 == strcmp(tmp1, "ping"))
323 				ret = GATEWAY_ERROR;
324 			goto out;
325 		}
326 	}
327 	else if (0 == strcmp(tmp, "process"))			/* zabbix["process",<type>,<mode>,<state>] */
328 	{
329 		unsigned char	process_type = ZBX_PROCESS_TYPE_UNKNOWN;
330 		int		process_forks;
331 		double		value;
332 
333 		if (2 > nparams || nparams > 4)
334 		{
335 			SET_MSG_RESULT(result, zbx_strdup(NULL, "Invalid number of parameters."));
336 			goto out;
337 		}
338 
339 		process_type = get_process_type_by_name(get_rparam(&request, 1));
340 
341 		switch (process_type)
342 		{
343 			case ZBX_PROCESS_TYPE_WATCHDOG:
344 			case ZBX_PROCESS_TYPE_ALERTER:
345 			case ZBX_PROCESS_TYPE_ESCALATOR:
346 			case ZBX_PROCESS_TYPE_PROXYPOLLER:
347 			case ZBX_PROCESS_TYPE_TIMER:
348 				if (0 == (program_type & ZBX_PROGRAM_TYPE_SERVER))
349 					process_type = ZBX_PROCESS_TYPE_UNKNOWN;
350 				break;
351 			case ZBX_PROCESS_TYPE_DATASENDER:
352 			case ZBX_PROCESS_TYPE_HEARTBEAT:
353 				if (0 == (program_type & ZBX_PROGRAM_TYPE_PROXY))
354 					process_type = ZBX_PROCESS_TYPE_UNKNOWN;
355 				break;
356 		}
357 
358 		if (ZBX_PROCESS_TYPE_UNKNOWN == process_type)
359 		{
360 			SET_MSG_RESULT(result, zbx_strdup(NULL, "Invalid second parameter."));
361 			goto out;
362 		}
363 
364 		process_forks = get_process_type_forks(process_type);
365 
366 		if (NULL == (tmp = get_rparam(&request, 2)))
367 			tmp = "";
368 
369 		if (0 == strcmp(tmp, "count"))
370 		{
371 			if (4 == nparams)
372 			{
373 				SET_MSG_RESULT(result, zbx_strdup(NULL, "Invalid number of parameters."));
374 				goto out;
375 			}
376 
377 			SET_UI64_RESULT(result, process_forks);
378 		}
379 		else
380 		{
381 			unsigned char	aggr_func, state;
382 			unsigned short	process_num = 0;
383 
384 			if ('\0' == *tmp || 0 == strcmp(tmp, "avg"))
385 				aggr_func = ZBX_AGGR_FUNC_AVG;
386 			else if (0 == strcmp(tmp, "max"))
387 				aggr_func = ZBX_AGGR_FUNC_MAX;
388 			else if (0 == strcmp(tmp, "min"))
389 				aggr_func = ZBX_AGGR_FUNC_MIN;
390 			else if (SUCCEED == is_ushort(tmp, &process_num) && 0 < process_num)
391 				aggr_func = ZBX_AGGR_FUNC_ONE;
392 			else
393 			{
394 				SET_MSG_RESULT(result, zbx_strdup(NULL, "Invalid third parameter."));
395 				goto out;
396 			}
397 
398 			if (0 == process_forks)
399 			{
400 				SET_MSG_RESULT(result, zbx_dsprintf(NULL, "No \"%s\" processes started.",
401 						get_process_type_string(process_type)));
402 				goto out;
403 			}
404 			else if (process_num > process_forks)
405 			{
406 				SET_MSG_RESULT(result, zbx_dsprintf(NULL, "Process \"%s #%d\" is not started.",
407 						get_process_type_string(process_type), process_num));
408 				goto out;
409 			}
410 
411 			if (NULL == (tmp = get_rparam(&request, 3)) || '\0' == *tmp || 0 == strcmp(tmp, "busy"))
412 				state = ZBX_PROCESS_STATE_BUSY;
413 			else if (0 == strcmp(tmp, "idle"))
414 				state = ZBX_PROCESS_STATE_IDLE;
415 			else
416 			{
417 				SET_MSG_RESULT(result, zbx_strdup(NULL, "Invalid fourth parameter."));
418 				goto out;
419 			}
420 
421 			get_selfmon_stats(process_type, aggr_func, process_num, state, &value);
422 
423 			SET_DBL_RESULT(result, value);
424 		}
425 	}
426 	else if (0 == strcmp(tmp, "wcache"))			/* zabbix[wcache,<cache>,<mode>] */
427 	{
428 		if (2 > nparams || nparams > 3)
429 		{
430 			SET_MSG_RESULT(result, zbx_strdup(NULL, "Invalid number of parameters."));
431 			goto out;
432 		}
433 
434 		tmp = get_rparam(&request, 1);
435 		tmp1 = get_rparam(&request, 2);
436 
437 		if (0 == strcmp(tmp, "values"))
438 		{
439 			if (NULL == tmp1 || '\0' == *tmp1 || 0 == strcmp(tmp1, "all"))
440 				SET_UI64_RESULT(result, *(zbx_uint64_t *)DCget_stats(ZBX_STATS_HISTORY_COUNTER));
441 			else if (0 == strcmp(tmp1, "float"))
442 				SET_UI64_RESULT(result, *(zbx_uint64_t *)DCget_stats(ZBX_STATS_HISTORY_FLOAT_COUNTER));
443 			else if (0 == strcmp(tmp1, "uint"))
444 				SET_UI64_RESULT(result, *(zbx_uint64_t *)DCget_stats(ZBX_STATS_HISTORY_UINT_COUNTER));
445 			else if (0 == strcmp(tmp1, "str"))
446 				SET_UI64_RESULT(result, *(zbx_uint64_t *)DCget_stats(ZBX_STATS_HISTORY_STR_COUNTER));
447 			else if (0 == strcmp(tmp1, "log"))
448 				SET_UI64_RESULT(result, *(zbx_uint64_t *)DCget_stats(ZBX_STATS_HISTORY_LOG_COUNTER));
449 			else if (0 == strcmp(tmp1, "text"))
450 				SET_UI64_RESULT(result, *(zbx_uint64_t *)DCget_stats(ZBX_STATS_HISTORY_TEXT_COUNTER));
451 			else if (0 == strcmp(tmp1, "not supported"))
452 				SET_UI64_RESULT(result, *(zbx_uint64_t *)DCget_stats(ZBX_STATS_NOTSUPPORTED_COUNTER));
453 			else
454 			{
455 				SET_MSG_RESULT(result, zbx_strdup(NULL, "Invalid third parameter."));
456 				goto out;
457 			}
458 		}
459 		else if (0 == strcmp(tmp, "history"))
460 		{
461 			if (NULL == tmp1 || '\0' == *tmp1 || 0 == strcmp(tmp1, "pfree"))
462 				SET_DBL_RESULT(result, *(double *)DCget_stats(ZBX_STATS_HISTORY_PFREE));
463 			else if (0 == strcmp(tmp1, "total"))
464 				SET_UI64_RESULT(result, *(zbx_uint64_t *)DCget_stats(ZBX_STATS_HISTORY_TOTAL));
465 			else if (0 == strcmp(tmp1, "used"))
466 				SET_UI64_RESULT(result, *(zbx_uint64_t *)DCget_stats(ZBX_STATS_HISTORY_USED));
467 			else if (0 == strcmp(tmp1, "free"))
468 				SET_UI64_RESULT(result, *(zbx_uint64_t *)DCget_stats(ZBX_STATS_HISTORY_FREE));
469 			else
470 			{
471 				SET_MSG_RESULT(result, zbx_strdup(NULL, "Invalid third parameter."));
472 				goto out;
473 			}
474 		}
475 		else if (0 == strcmp(tmp, "trend"))
476 		{
477 			if (0 == (program_type & ZBX_PROGRAM_TYPE_SERVER))
478 			{
479 				SET_MSG_RESULT(result, zbx_strdup(NULL, "Invalid second parameter."));
480 				goto out;
481 			}
482 
483 			if (NULL == tmp1 || '\0' == *tmp1 || 0 == strcmp(tmp1, "pfree"))
484 				SET_DBL_RESULT(result, *(double *)DCget_stats(ZBX_STATS_TREND_PFREE));
485 			else if (0 == strcmp(tmp1, "total"))
486 				SET_UI64_RESULT(result, *(zbx_uint64_t *)DCget_stats(ZBX_STATS_TREND_TOTAL));
487 			else if (0 == strcmp(tmp1, "used"))
488 				SET_UI64_RESULT(result, *(zbx_uint64_t *)DCget_stats(ZBX_STATS_TREND_USED));
489 			else if (0 == strcmp(tmp1, "free"))
490 				SET_UI64_RESULT(result, *(zbx_uint64_t *)DCget_stats(ZBX_STATS_TREND_FREE));
491 			else
492 			{
493 				SET_MSG_RESULT(result, zbx_strdup(NULL, "Invalid third parameter."));
494 				goto out;
495 			}
496 		}
497 		else if (0 == strcmp(tmp, "index"))
498 		{
499 			if (NULL == tmp1 || '\0' == *tmp1 || 0 == strcmp(tmp1, "pfree"))
500 				SET_DBL_RESULT(result, *(double *)DCget_stats(ZBX_STATS_HISTORY_INDEX_PFREE));
501 			else if (0 == strcmp(tmp1, "total"))
502 				SET_UI64_RESULT(result, *(zbx_uint64_t *)DCget_stats(ZBX_STATS_HISTORY_INDEX_TOTAL));
503 			else if (0 == strcmp(tmp1, "used"))
504 				SET_UI64_RESULT(result, *(zbx_uint64_t *)DCget_stats(ZBX_STATS_HISTORY_INDEX_USED));
505 			else if (0 == strcmp(tmp1, "free"))
506 				SET_UI64_RESULT(result, *(zbx_uint64_t *)DCget_stats(ZBX_STATS_HISTORY_INDEX_FREE));
507 			else
508 			{
509 				SET_MSG_RESULT(result, zbx_strdup(NULL, "Invalid third parameter."));
510 				goto out;
511 			}
512 		}
513 		else
514 		{
515 			SET_MSG_RESULT(result, zbx_strdup(NULL, "Invalid second parameter."));
516 			goto out;
517 		}
518 	}
519 	else if (0 == strcmp(tmp, "rcache"))			/* zabbix[rcache,<cache>,<mode>] */
520 	{
521 		if (2 > nparams || nparams > 3)
522 		{
523 			SET_MSG_RESULT(result, zbx_strdup(NULL, "Invalid number of parameters."));
524 			goto out;
525 		}
526 
527 		tmp = get_rparam(&request, 1);
528 		tmp1 = get_rparam(&request, 2);
529 
530 		if (0 == strcmp(tmp, "buffer"))
531 		{
532 			if (NULL == tmp1 || '\0' == *tmp1 || 0 == strcmp(tmp1, "pfree"))
533 				SET_DBL_RESULT(result, *(double *)DCconfig_get_stats(ZBX_CONFSTATS_BUFFER_PFREE));
534 			else if (0 == strcmp(tmp1, "total"))
535 				SET_UI64_RESULT(result, *(zbx_uint64_t *)DCconfig_get_stats(ZBX_CONFSTATS_BUFFER_TOTAL));
536 			else if (0 == strcmp(tmp1, "used"))
537 				SET_UI64_RESULT(result, *(zbx_uint64_t *)DCconfig_get_stats(ZBX_CONFSTATS_BUFFER_USED));
538 			else if (0 == strcmp(tmp1, "free"))
539 				SET_UI64_RESULT(result, *(zbx_uint64_t *)DCconfig_get_stats(ZBX_CONFSTATS_BUFFER_FREE));
540 			else
541 			{
542 				SET_MSG_RESULT(result, zbx_strdup(NULL, "Invalid third parameter."));
543 				goto out;
544 			}
545 		}
546 		else
547 		{
548 			SET_MSG_RESULT(result, zbx_strdup(NULL, "Invalid second parameter."));
549 			goto out;
550 		}
551 	}
552 	else if (0 == strcmp(tmp, "vcache"))
553 	{
554 		zbx_vc_stats_t	stats;
555 
556 		if (0 == (program_type & ZBX_PROGRAM_TYPE_SERVER))
557 			goto out;
558 
559 		if (FAIL == zbx_vc_get_statistics(&stats))
560 		{
561 			SET_MSG_RESULT(result, zbx_strdup(NULL, "Value cache is disabled."));
562 			goto out;
563 		}
564 
565 		if (2 > nparams || nparams > 3)
566 		{
567 			SET_MSG_RESULT(result, zbx_strdup(NULL, "Invalid number of parameters."));
568 			goto out;
569 		}
570 
571 		tmp = get_rparam(&request, 1);
572 		if (NULL == (tmp1 = get_rparam(&request, 2)))
573 			tmp1 = "";
574 
575 		if (0 == strcmp(tmp, "buffer"))
576 		{
577 			if (0 == strcmp(tmp1, "free"))
578 				SET_UI64_RESULT(result, stats.free_size);
579 			else if (0 == strcmp(tmp1, "pfree"))
580 				SET_DBL_RESULT(result, (double)stats.free_size / stats.total_size * 100);
581 			else if (0 == strcmp(tmp1, "total"))
582 				SET_UI64_RESULT(result, stats.total_size);
583 			else if (0 == strcmp(tmp1, "used"))
584 				SET_UI64_RESULT(result, stats.total_size - stats.free_size);
585 			else if (0 == strcmp(tmp1, "pused"))
586 				SET_DBL_RESULT(result, (double)(stats.total_size - stats.free_size) /
587 						stats.total_size * 100);
588 			else
589 			{
590 				SET_MSG_RESULT(result, zbx_strdup(NULL, "Invalid third parameter."));
591 				goto out;
592 			}
593 		}
594 		else if (0 == strcmp(tmp, "cache"))
595 		{
596 			if (0 == strcmp(tmp1, "hits"))
597 				SET_UI64_RESULT(result, stats.hits);
598 			else if (0 == strcmp(tmp1, "requests"))
599 				SET_UI64_RESULT(result, stats.hits + stats.misses);
600 			else if (0 == strcmp(tmp1, "misses"))
601 				SET_UI64_RESULT(result, stats.misses);
602 			else if (0 == strcmp(tmp1, "mode"))
603 				SET_UI64_RESULT(result, stats.mode);
604 			else
605 			{
606 				SET_MSG_RESULT(result, zbx_strdup(NULL, "Invalid third parameter."));
607 				goto out;
608 			}
609 		}
610 		else
611 		{
612 			SET_MSG_RESULT(result, zbx_strdup(NULL, "Invalid second parameter."));
613 			goto out;
614 		}
615 	}
616 	else if (0 == strcmp(tmp, "proxy_history"))
617 	{
618 		if (0 == (program_type & ZBX_PROGRAM_TYPE_PROXY))
619 			goto out;
620 
621 		if (1 != nparams)
622 		{
623 			SET_MSG_RESULT(result, zbx_strdup(NULL, "Invalid number of parameters."));
624 			goto out;
625 		}
626 
627 		SET_UI64_RESULT(result, proxy_get_history_count());
628 	}
629 	else if (0 == strcmp(tmp, "vmware"))
630 	{
631 		zbx_vmware_stats_t	stats;
632 
633 		if (FAIL == zbx_vmware_get_statistics(&stats))
634 		{
635 			SET_MSG_RESULT(result, zbx_dsprintf(NULL, "No \"%s\" processes started.",
636 					get_process_type_string(ZBX_PROCESS_TYPE_VMWARE)));
637 			goto out;
638 		}
639 
640 		if (2 > nparams || nparams > 3)
641 		{
642 			SET_MSG_RESULT(result, zbx_strdup(NULL, "Invalid number of parameters."));
643 			goto out;
644 		}
645 
646 		tmp = get_rparam(&request, 1);
647 		if (NULL == (tmp1 = get_rparam(&request, 2)))
648 			tmp1 = "";
649 
650 		if (0 == strcmp(tmp, "buffer"))
651 		{
652 			if (0 == strcmp(tmp1, "free"))
653 			{
654 				SET_UI64_RESULT(result, stats.memory_total - stats.memory_used);
655 			}
656 			else if (0 == strcmp(tmp1, "pfree"))
657 			{
658 				SET_DBL_RESULT(result, (double)(stats.memory_total - stats.memory_used) /
659 						stats.memory_total * 100);
660 			}
661 			else if (0 == strcmp(tmp1, "total"))
662 			{
663 				SET_UI64_RESULT(result, stats.memory_total);
664 			}
665 			else if (0 == strcmp(tmp1, "used"))
666 			{
667 				SET_UI64_RESULT(result, stats.memory_used);
668 			}
669 			else if (0 == strcmp(tmp1, "pused"))
670 			{
671 				SET_DBL_RESULT(result, (double)stats.memory_used / stats.memory_total * 100);
672 			}
673 			else
674 			{
675 				SET_MSG_RESULT(result, zbx_strdup(NULL, "Invalid third parameter."));
676 				goto out;
677 			}
678 		}
679 		else
680 		{
681 			SET_MSG_RESULT(result, zbx_strdup(NULL, "Invalid second parameter."));
682 			goto out;
683 		}
684 	}
685 	else
686 	{
687 		SET_MSG_RESULT(result, zbx_strdup(NULL, "Invalid first parameter."));
688 		goto out;
689 	}
690 
691 	ret = SUCCEED;
692 out:
693 	if (NOTSUPPORTED == ret && !ISSET_MSG(result))
694 		SET_MSG_RESULT(result, zbx_strdup(NULL, "Internal check is not supported."));
695 
696 	free_request(&request);
697 
698 	return ret;
699 }
700