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 "sysinfo.h"
22 #include "md5.h"
23 #include "file.h"
24 #include "zbxregexp.h"
25 #include "log.h"
26 
27 #define ZBX_MAX_DB_FILE_SIZE	64 * ZBX_KIBIBYTE	/* files larger than 64 KB cannot be stored in the database */
28 
29 extern int	CONFIG_TIMEOUT;
30 
VFS_FILE_SIZE(AGENT_REQUEST * request,AGENT_RESULT * result)31 int	VFS_FILE_SIZE(AGENT_REQUEST *request, AGENT_RESULT *result)
32 {
33 	zbx_stat_t	buf;
34 	char		*filename;
35 	int		ret = SYSINFO_RET_FAIL;
36 
37 	if (1 < request->nparam)
38 	{
39 		SET_MSG_RESULT(result, zbx_strdup(NULL, "Too many parameters."));
40 		goto err;
41 	}
42 
43 	filename = get_rparam(request, 0);
44 
45 	if (NULL == filename || '\0' == *filename)
46 	{
47 		SET_MSG_RESULT(result, zbx_strdup(NULL, "Invalid first parameter."));
48 		goto err;
49 	}
50 
51 	if (0 != zbx_stat(filename, &buf))
52 	{
53 		SET_MSG_RESULT(result, zbx_dsprintf(NULL, "Cannot obtain file information: %s", zbx_strerror(errno)));
54 		goto err;
55 	}
56 
57 	SET_UI64_RESULT(result, buf.st_size);
58 
59 	ret = SYSINFO_RET_OK;
60 err:
61 	return ret;
62 }
63 
VFS_FILE_TIME(AGENT_REQUEST * request,AGENT_RESULT * result)64 int	VFS_FILE_TIME(AGENT_REQUEST *request, AGENT_RESULT *result)
65 {
66 	zbx_file_time_t	file_time;
67 	char		*filename, *type;
68 	int		ret = SYSINFO_RET_FAIL;
69 
70 	if (2 < request->nparam)
71 	{
72 		SET_MSG_RESULT(result, zbx_strdup(NULL, "Too many parameters."));
73 		goto err;
74 	}
75 
76 	filename = get_rparam(request, 0);
77 	type = get_rparam(request, 1);
78 
79 	if (NULL == filename || '\0' == *filename)
80 	{
81 		SET_MSG_RESULT(result, zbx_strdup(NULL, "Invalid first parameter."));
82 		goto err;
83 	}
84 
85 	if (SUCCEED != zbx_get_file_time(filename, &file_time))
86 	{
87 		SET_MSG_RESULT(result, zbx_dsprintf(NULL, "Cannot obtain file information: %s", zbx_strerror(errno)));
88 		goto err;
89 	}
90 
91 	if (NULL == type || '\0' == *type || 0 == strcmp(type, "modify"))	/* default parameter */
92 		SET_UI64_RESULT(result, file_time.modification_time);
93 	else if (0 == strcmp(type, "access"))
94 		SET_UI64_RESULT(result, file_time.access_time);
95 	else if (0 == strcmp(type, "change"))
96 		SET_UI64_RESULT(result, file_time.change_time);
97 	else
98 	{
99 		SET_MSG_RESULT(result, zbx_strdup(NULL, "Invalid second parameter."));
100 		goto err;
101 	}
102 
103 	ret = SYSINFO_RET_OK;
104 err:
105 	return ret;
106 }
107 
VFS_FILE_EXISTS(AGENT_REQUEST * request,AGENT_RESULT * result)108 int	VFS_FILE_EXISTS(AGENT_REQUEST *request, AGENT_RESULT *result)
109 {
110 	zbx_stat_t	buf;
111 	char		*filename;
112 	int		ret = SYSINFO_RET_FAIL, file_exists;
113 
114 	if (1 < request->nparam)
115 	{
116 		SET_MSG_RESULT(result, zbx_strdup(NULL, "Too many parameters."));
117 		goto err;
118 	}
119 
120 	filename = get_rparam(request, 0);
121 
122 	if (NULL == filename || '\0' == *filename)
123 	{
124 		SET_MSG_RESULT(result, zbx_strdup(NULL, "Invalid first parameter."));
125 		goto err;
126 	}
127 
128 	if (0 == zbx_stat(filename, &buf))
129 	{
130 		file_exists = S_ISREG(buf.st_mode) ? 1 : 0;
131 	}
132 	else if (errno == ENOENT)
133 	{
134 		file_exists = 0;
135 	}
136 	else
137 	{
138 		SET_MSG_RESULT(result, zbx_dsprintf(NULL, "Cannot obtain file information: %s", zbx_strerror(errno)));
139 		goto err;
140 	}
141 
142 	SET_UI64_RESULT(result, file_exists);
143 	ret = SYSINFO_RET_OK;
144 err:
145 	return ret;
146 }
147 
VFS_FILE_CONTENTS(AGENT_REQUEST * request,AGENT_RESULT * result)148 int	VFS_FILE_CONTENTS(AGENT_REQUEST *request, AGENT_RESULT *result)
149 {
150 	char		*filename, *tmp, encoding[32];
151 	char		read_buf[MAX_BUFFER_LEN], *utf8, *contents = NULL;
152 	size_t		contents_alloc = 0, contents_offset = 0;
153 	int		nbytes, flen, f = -1, ret = SYSINFO_RET_FAIL;
154 	zbx_stat_t	stat_buf;
155 	double		ts;
156 
157 	ts = zbx_time();
158 
159 	if (2 < request->nparam)
160 	{
161 		SET_MSG_RESULT(result, zbx_strdup(NULL, "Too many parameters."));
162 		goto err;
163 	}
164 
165 	filename = get_rparam(request, 0);
166 	tmp = get_rparam(request, 1);
167 
168 	if (NULL == tmp)
169 		*encoding = '\0';
170 	else
171 		strscpy(encoding, tmp);
172 
173 	if (NULL == filename || '\0' == *filename)
174 	{
175 		SET_MSG_RESULT(result, zbx_strdup(NULL, "Invalid first parameter."));
176 		goto err;
177 	}
178 
179 	if (-1 == (f = zbx_open(filename, O_RDONLY)))
180 	{
181 		SET_MSG_RESULT(result, zbx_dsprintf(NULL, "Cannot open file: %s", zbx_strerror(errno)));
182 		goto err;
183 	}
184 
185 	if (CONFIG_TIMEOUT < zbx_time() - ts)
186 	{
187 		SET_MSG_RESULT(result, zbx_strdup(NULL, "Timeout while processing item."));
188 		goto err;
189 	}
190 
191 	if (0 != zbx_fstat(f, &stat_buf))
192 	{
193 		SET_MSG_RESULT(result, zbx_dsprintf(NULL, "Cannot obtain file information: %s", zbx_strerror(errno)));
194 		goto err;
195 	}
196 
197 	if (ZBX_MAX_DB_FILE_SIZE < stat_buf.st_size)
198 	{
199 		SET_MSG_RESULT(result, zbx_strdup(NULL, "File is too large for this check."));
200 		goto err;
201 	}
202 
203 	if (CONFIG_TIMEOUT < zbx_time() - ts)
204 	{
205 		SET_MSG_RESULT(result, zbx_strdup(NULL, "Timeout while processing item."));
206 		goto err;
207 	}
208 
209 	flen = 0;
210 
211 	while (0 < (nbytes = zbx_read(f, read_buf, sizeof(read_buf), encoding)))
212 	{
213 		if (CONFIG_TIMEOUT < zbx_time() - ts)
214 		{
215 			SET_MSG_RESULT(result, zbx_strdup(NULL, "Timeout while processing item."));
216 			zbx_free(contents);
217 			goto err;
218 		}
219 
220 		if (ZBX_MAX_DB_FILE_SIZE < (flen += nbytes))
221 		{
222 			SET_MSG_RESULT(result, zbx_strdup(NULL, "File is too large for this check."));
223 			zbx_free(contents);
224 			goto err;
225 		}
226 
227 		utf8 = convert_to_utf8(read_buf, nbytes, encoding);
228 		zbx_strcpy_alloc(&contents, &contents_alloc, &contents_offset, utf8);
229 		zbx_free(utf8);
230 	}
231 
232 	if (-1 == nbytes)	/* error occurred */
233 	{
234 		SET_MSG_RESULT(result, zbx_strdup(NULL, "Cannot read from file."));
235 		zbx_free(contents);
236 		goto err;
237 	}
238 
239 	if (0 != contents_offset)
240 		contents_offset -= zbx_rtrim(contents, "\r\n");
241 
242 	if (0 == contents_offset) /* empty file */
243 	{
244 		zbx_free(contents);
245 		contents = zbx_strdup(contents, "");
246 	}
247 
248 	SET_TEXT_RESULT(result, contents);
249 
250 	ret = SYSINFO_RET_OK;
251 err:
252 	if (-1 != f)
253 		close(f);
254 
255 	return ret;
256 }
257 
VFS_FILE_REGEXP(AGENT_REQUEST * request,AGENT_RESULT * result)258 int	VFS_FILE_REGEXP(AGENT_REQUEST *request, AGENT_RESULT *result)
259 {
260 	char		*filename, *regexp, encoding[32], *output, *start_line_str, *end_line_str;
261 	char		buf[MAX_BUFFER_LEN], *utf8, *tmp, *ptr = NULL;
262 	int		nbytes, f = -1, ret = SYSINFO_RET_FAIL;
263 	zbx_uint32_t	start_line, end_line, current_line = 0;
264 	double		ts;
265 
266 	ts = zbx_time();
267 
268 	if (6 < request->nparam)
269 	{
270 		SET_MSG_RESULT(result, zbx_strdup(NULL, "Too many parameters."));
271 		goto err;
272 	}
273 
274 	filename = get_rparam(request, 0);
275 	regexp = get_rparam(request, 1);
276 	tmp = get_rparam(request, 2);
277 	start_line_str = get_rparam(request, 3);
278 	end_line_str = get_rparam(request, 4);
279 	output = get_rparam(request, 5);
280 
281 	if (NULL == filename || '\0' == *filename)
282 	{
283 		SET_MSG_RESULT(result, zbx_strdup(NULL, "Invalid first parameter."));
284 		goto err;
285 	}
286 
287 	if (NULL == regexp || '\0' == *regexp)
288 	{
289 		SET_MSG_RESULT(result, zbx_strdup(NULL, "Invalid second parameter."));
290 		goto err;
291 	}
292 
293 	if (NULL == tmp)
294 		*encoding = '\0';
295 	else
296 		strscpy(encoding, tmp);
297 
298 	if (NULL == start_line_str || '\0' == *start_line_str)
299 		start_line = 0;
300 	else if (FAIL == is_uint32(start_line_str, &start_line))
301 	{
302 		SET_MSG_RESULT(result, zbx_strdup(NULL, "Invalid fourth parameter."));
303 		goto err;
304 	}
305 
306 	if (NULL == end_line_str || '\0' == *end_line_str)
307 		end_line = 0xffffffff;
308 	else if (FAIL == is_uint32(end_line_str, &end_line))
309 	{
310 		SET_MSG_RESULT(result, zbx_strdup(NULL, "Invalid fifth parameter."));
311 		goto err;
312 	}
313 
314 	if (start_line > end_line)
315 	{
316 		SET_MSG_RESULT(result, zbx_strdup(NULL, "Start line parameter must not exceed end line."));
317 		goto err;
318 	}
319 
320 	if (-1 == (f = zbx_open(filename, O_RDONLY)))
321 	{
322 		SET_MSG_RESULT(result, zbx_dsprintf(NULL, "Cannot open file: %s", zbx_strerror(errno)));
323 		goto err;
324 	}
325 
326 	if (CONFIG_TIMEOUT < zbx_time() - ts)
327 	{
328 		SET_MSG_RESULT(result, zbx_strdup(NULL, "Timeout while processing item."));
329 		goto err;
330 	}
331 
332 	while (0 < (nbytes = zbx_read(f, buf, sizeof(buf), encoding)))
333 	{
334 		if (CONFIG_TIMEOUT < zbx_time() - ts)
335 		{
336 			SET_MSG_RESULT(result, zbx_strdup(NULL, "Timeout while processing item."));
337 			goto err;
338 		}
339 
340 		if (++current_line < start_line)
341 			continue;
342 
343 		utf8 = convert_to_utf8(buf, nbytes, encoding);
344 		zbx_rtrim(utf8, "\r\n");
345 		zbx_regexp_sub(utf8, regexp, output, &ptr);
346 		zbx_free(utf8);
347 
348 		if (NULL != ptr)
349 		{
350 			SET_STR_RESULT(result, ptr);
351 			break;
352 		}
353 
354 		if (current_line >= end_line)
355 		{
356 			/* force EOF state */
357 			nbytes = 0;
358 			break;
359 		}
360 	}
361 
362 	if (-1 == nbytes)	/* error occurred */
363 	{
364 		SET_MSG_RESULT(result, zbx_strdup(NULL, "Cannot read from file."));
365 		goto err;
366 	}
367 
368 	if (0 == nbytes)	/* EOF */
369 		SET_STR_RESULT(result, zbx_strdup(NULL, ""));
370 
371 	ret = SYSINFO_RET_OK;
372 err:
373 	if (-1 != f)
374 		close(f);
375 
376 	return ret;
377 }
378 
VFS_FILE_REGMATCH(AGENT_REQUEST * request,AGENT_RESULT * result)379 int	VFS_FILE_REGMATCH(AGENT_REQUEST *request, AGENT_RESULT *result)
380 {
381 	char		*filename, *regexp, *tmp, encoding[32];
382 	char		buf[MAX_BUFFER_LEN], *utf8, *start_line_str, *end_line_str;
383 	int		nbytes, res, f = -1, ret = SYSINFO_RET_FAIL;
384 	zbx_uint32_t	start_line, end_line, current_line = 0;
385 	double		ts;
386 
387 	ts = zbx_time();
388 
389 	if (5 < request->nparam)
390 	{
391 		SET_MSG_RESULT(result, zbx_strdup(NULL, "Too many parameters."));
392 		goto err;
393 	}
394 
395 	filename = get_rparam(request, 0);
396 	regexp = get_rparam(request, 1);
397 	tmp = get_rparam(request, 2);
398 	start_line_str = get_rparam(request, 3);
399 	end_line_str = get_rparam(request, 4);
400 
401 	if (NULL == filename || '\0' == *filename)
402 	{
403 		SET_MSG_RESULT(result, zbx_strdup(NULL, "Invalid first parameter."));
404 		goto err;
405 	}
406 
407 	if (NULL == regexp || '\0' == *regexp)
408 	{
409 		SET_MSG_RESULT(result, zbx_strdup(NULL, "Invalid second parameter."));
410 		goto err;
411 	}
412 
413 	if (NULL == tmp)
414 		*encoding = '\0';
415 	else
416 		strscpy(encoding, tmp);
417 
418 	if (NULL == start_line_str || '\0' == *start_line_str)
419 		start_line = 0;
420 	else if (FAIL == is_uint32(start_line_str, &start_line))
421 	{
422 		SET_MSG_RESULT(result, zbx_strdup(NULL, "Invalid fourth parameter."));
423 		goto err;
424 	}
425 
426 	if (NULL == end_line_str || '\0' == *end_line_str)
427 		end_line = 0xffffffff;
428 	else if (FAIL == is_uint32(end_line_str, &end_line))
429 	{
430 		SET_MSG_RESULT(result, zbx_strdup(NULL, "Invalid fifth parameter."));
431 		goto err;
432 	}
433 
434 	if (start_line > end_line)
435 	{
436 		SET_MSG_RESULT(result, zbx_strdup(NULL, "Start line must not exceed end line."));
437 		goto err;
438 	}
439 
440 	if (-1 == (f = zbx_open(filename, O_RDONLY)))
441 	{
442 		SET_MSG_RESULT(result, zbx_dsprintf(NULL, "Cannot open file: %s", zbx_strerror(errno)));
443 		goto err;
444 	}
445 
446 	if (CONFIG_TIMEOUT < zbx_time() - ts)
447 	{
448 		SET_MSG_RESULT(result, zbx_strdup(NULL, "Timeout while processing item."));
449 		goto err;
450 	}
451 
452 	res = 0;
453 
454 	while (0 == res && 0 < (nbytes = zbx_read(f, buf, sizeof(buf), encoding)))
455 	{
456 		if (CONFIG_TIMEOUT < zbx_time() - ts)
457 		{
458 			SET_MSG_RESULT(result, zbx_strdup(NULL, "Timeout while processing item."));
459 			goto err;
460 		}
461 
462 		if (++current_line < start_line)
463 			continue;
464 
465 		utf8 = convert_to_utf8(buf, nbytes, encoding);
466 		zbx_rtrim(utf8, "\r\n");
467 		if (NULL != zbx_regexp_match(utf8, regexp, NULL))
468 			res = 1;
469 		zbx_free(utf8);
470 
471 		if (current_line >= end_line)
472 			break;
473 	}
474 
475 	if (-1 == nbytes)	/* error occurred */
476 	{
477 		SET_MSG_RESULT(result, zbx_strdup(NULL, "Cannot read from file."));
478 		goto err;
479 	}
480 
481 	SET_UI64_RESULT(result, res);
482 
483 	ret = SYSINFO_RET_OK;
484 err:
485 	if (-1 != f)
486 		close(f);
487 
488 	return ret;
489 }
490 
VFS_FILE_MD5SUM(AGENT_REQUEST * request,AGENT_RESULT * result)491 int	VFS_FILE_MD5SUM(AGENT_REQUEST *request, AGENT_RESULT *result)
492 {
493 	char		*filename;
494 	int		i, nbytes, f = -1, ret = SYSINFO_RET_FAIL;
495 	md5_state_t	state;
496 	u_char		buf[16 * ZBX_KIBIBYTE];
497 	char		*hash_text = NULL;
498 	size_t		sz;
499 	md5_byte_t	hash[MD5_DIGEST_SIZE];
500 	double		ts;
501 
502 	ts = zbx_time();
503 
504 	if (1 < request->nparam)
505 	{
506 		SET_MSG_RESULT(result, zbx_strdup(NULL, "Too many parameters."));
507 		goto err;
508 	}
509 
510 	filename = get_rparam(request, 0);
511 
512 	if (NULL == filename || '\0' == *filename)
513 	{
514 		SET_MSG_RESULT(result, zbx_strdup(NULL, "Invalid first parameter."));
515 		goto err;
516 	}
517 
518 	if (-1 == (f = zbx_open(filename, O_RDONLY)))
519 	{
520 		SET_MSG_RESULT(result, zbx_dsprintf(NULL, "Cannot open file: %s", zbx_strerror(errno)));
521 		goto err;
522 	}
523 
524 	if (CONFIG_TIMEOUT < zbx_time() - ts)
525 	{
526 		SET_MSG_RESULT(result, zbx_strdup(NULL, "Timeout while processing item."));
527 		goto err;
528 	}
529 
530 	zbx_md5_init(&state);
531 
532 	while (0 < (nbytes = (int)read(f, buf, sizeof(buf))))
533 	{
534 		if (CONFIG_TIMEOUT < zbx_time() - ts)
535 		{
536 			SET_MSG_RESULT(result, zbx_strdup(NULL, "Timeout while processing item."));
537 			goto err;
538 		}
539 
540 		zbx_md5_append(&state, (const md5_byte_t *)buf, nbytes);
541 	}
542 
543 	zbx_md5_finish(&state, hash);
544 
545 	if (0 > nbytes)
546 	{
547 		SET_MSG_RESULT(result, zbx_strdup(NULL, "Cannot read from file."));
548 		goto err;
549 	}
550 
551 	/* convert MD5 hash to text form */
552 
553 	sz = MD5_DIGEST_SIZE * 2 + 1;
554 	hash_text = (char *)zbx_malloc(hash_text, sz);
555 
556 	for (i = 0; i < MD5_DIGEST_SIZE; i++)
557 	{
558 		zbx_snprintf(&hash_text[i << 1], sz - (i << 1), "%02x", hash[i]);
559 	}
560 
561 	SET_STR_RESULT(result, hash_text);
562 
563 	ret = SYSINFO_RET_OK;
564 err:
565 	if (-1 != f)
566 		close(f);
567 
568 	return ret;
569 }
570 
571 static u_long	crctab[] =
572 {
573 	0x0,
574 	0x04c11db7, 0x09823b6e, 0x0d4326d9, 0x130476dc, 0x17c56b6b,
575 	0x1a864db2, 0x1e475005, 0x2608edb8, 0x22c9f00f, 0x2f8ad6d6,
576 	0x2b4bcb61, 0x350c9b64, 0x31cd86d3, 0x3c8ea00a, 0x384fbdbd,
577 	0x4c11db70, 0x48d0c6c7, 0x4593e01e, 0x4152fda9, 0x5f15adac,
578 	0x5bd4b01b, 0x569796c2, 0x52568b75, 0x6a1936c8, 0x6ed82b7f,
579 	0x639b0da6, 0x675a1011, 0x791d4014, 0x7ddc5da3, 0x709f7b7a,
580 	0x745e66cd, 0x9823b6e0, 0x9ce2ab57, 0x91a18d8e, 0x95609039,
581 	0x8b27c03c, 0x8fe6dd8b, 0x82a5fb52, 0x8664e6e5, 0xbe2b5b58,
582 	0xbaea46ef, 0xb7a96036, 0xb3687d81, 0xad2f2d84, 0xa9ee3033,
583 	0xa4ad16ea, 0xa06c0b5d, 0xd4326d90, 0xd0f37027, 0xddb056fe,
584 	0xd9714b49, 0xc7361b4c, 0xc3f706fb, 0xceb42022, 0xca753d95,
585 	0xf23a8028, 0xf6fb9d9f, 0xfbb8bb46, 0xff79a6f1, 0xe13ef6f4,
586 	0xe5ffeb43, 0xe8bccd9a, 0xec7dd02d, 0x34867077, 0x30476dc0,
587 	0x3d044b19, 0x39c556ae, 0x278206ab, 0x23431b1c, 0x2e003dc5,
588 	0x2ac12072, 0x128e9dcf, 0x164f8078, 0x1b0ca6a1, 0x1fcdbb16,
589 	0x018aeb13, 0x054bf6a4, 0x0808d07d, 0x0cc9cdca, 0x7897ab07,
590 	0x7c56b6b0, 0x71159069, 0x75d48dde, 0x6b93dddb, 0x6f52c06c,
591 	0x6211e6b5, 0x66d0fb02, 0x5e9f46bf, 0x5a5e5b08, 0x571d7dd1,
592 	0x53dc6066, 0x4d9b3063, 0x495a2dd4, 0x44190b0d, 0x40d816ba,
593 	0xaca5c697, 0xa864db20, 0xa527fdf9, 0xa1e6e04e, 0xbfa1b04b,
594 	0xbb60adfc, 0xb6238b25, 0xb2e29692, 0x8aad2b2f, 0x8e6c3698,
595 	0x832f1041, 0x87ee0df6, 0x99a95df3, 0x9d684044, 0x902b669d,
596 	0x94ea7b2a, 0xe0b41de7, 0xe4750050, 0xe9362689, 0xedf73b3e,
597 	0xf3b06b3b, 0xf771768c, 0xfa325055, 0xfef34de2, 0xc6bcf05f,
598 	0xc27dede8, 0xcf3ecb31, 0xcbffd686, 0xd5b88683, 0xd1799b34,
599 	0xdc3abded, 0xd8fba05a, 0x690ce0ee, 0x6dcdfd59, 0x608edb80,
600 	0x644fc637, 0x7a089632, 0x7ec98b85, 0x738aad5c, 0x774bb0eb,
601 	0x4f040d56, 0x4bc510e1, 0x46863638, 0x42472b8f, 0x5c007b8a,
602 	0x58c1663d, 0x558240e4, 0x51435d53, 0x251d3b9e, 0x21dc2629,
603 	0x2c9f00f0, 0x285e1d47, 0x36194d42, 0x32d850f5, 0x3f9b762c,
604 	0x3b5a6b9b, 0x0315d626, 0x07d4cb91, 0x0a97ed48, 0x0e56f0ff,
605 	0x1011a0fa, 0x14d0bd4d, 0x19939b94, 0x1d528623, 0xf12f560e,
606 	0xf5ee4bb9, 0xf8ad6d60, 0xfc6c70d7, 0xe22b20d2, 0xe6ea3d65,
607 	0xeba91bbc, 0xef68060b, 0xd727bbb6, 0xd3e6a601, 0xdea580d8,
608 	0xda649d6f, 0xc423cd6a, 0xc0e2d0dd, 0xcda1f604, 0xc960ebb3,
609 	0xbd3e8d7e, 0xb9ff90c9, 0xb4bcb610, 0xb07daba7, 0xae3afba2,
610 	0xaafbe615, 0xa7b8c0cc, 0xa379dd7b, 0x9b3660c6, 0x9ff77d71,
611 	0x92b45ba8, 0x9675461f, 0x8832161a, 0x8cf30bad, 0x81b02d74,
612 	0x857130c3, 0x5d8a9099, 0x594b8d2e, 0x5408abf7, 0x50c9b640,
613 	0x4e8ee645, 0x4a4ffbf2, 0x470cdd2b, 0x43cdc09c, 0x7b827d21,
614 	0x7f436096, 0x7200464f, 0x76c15bf8, 0x68860bfd, 0x6c47164a,
615 	0x61043093, 0x65c52d24, 0x119b4be9, 0x155a565e, 0x18197087,
616 	0x1cd86d30, 0x029f3d35, 0x065e2082, 0x0b1d065b, 0x0fdc1bec,
617 	0x3793a651, 0x3352bbe6, 0x3e119d3f, 0x3ad08088, 0x2497d08d,
618 	0x2056cd3a, 0x2d15ebe3, 0x29d4f654, 0xc5a92679, 0xc1683bce,
619 	0xcc2b1d17, 0xc8ea00a0, 0xd6ad50a5, 0xd26c4d12, 0xdf2f6bcb,
620 	0xdbee767c, 0xe3a1cbc1, 0xe760d676, 0xea23f0af, 0xeee2ed18,
621 	0xf0a5bd1d, 0xf464a0aa, 0xf9278673, 0xfde69bc4, 0x89b8fd09,
622 	0x8d79e0be, 0x803ac667, 0x84fbdbd0, 0x9abc8bd5, 0x9e7d9662,
623 	0x933eb0bb, 0x97ffad0c, 0xafb010b1, 0xab710d06, 0xa6322bdf,
624 	0xa2f33668, 0xbcb4666d, 0xb8757bda, 0xb5365d03, 0xb1f740b4
625 };
626 
627 /******************************************************************************
628  *                                                                            *
629  * Comments: computes POSIX 1003.2 checksum                                   *
630  *                                                                            *
631  ******************************************************************************/
VFS_FILE_CKSUM(AGENT_REQUEST * request,AGENT_RESULT * result)632 int	VFS_FILE_CKSUM(AGENT_REQUEST *request, AGENT_RESULT *result)
633 {
634 	char		*filename;
635 	int		i, nr, f = -1, ret = SYSINFO_RET_FAIL;
636 	zbx_uint32_t	crc, flen;
637 	u_char		buf[16 * ZBX_KIBIBYTE];
638 	u_long		cval;
639 	double		ts;
640 
641 	ts = zbx_time();
642 
643 	if (1 < request->nparam)
644 	{
645 		SET_MSG_RESULT(result, zbx_strdup(NULL, "Too many parameters."));
646 		goto err;
647 	}
648 
649 	filename = get_rparam(request, 0);
650 
651 	if (NULL == filename || '\0' == *filename)
652 	{
653 		SET_MSG_RESULT(result, zbx_strdup(NULL, "Invalid first parameter."));
654 		goto err;
655 	}
656 
657 	if (-1 == (f = zbx_open(filename, O_RDONLY)))
658 	{
659 		SET_MSG_RESULT(result, zbx_dsprintf(NULL, "Cannot open file: %s", zbx_strerror(errno)));
660 		goto err;
661 	}
662 
663 	if (CONFIG_TIMEOUT < zbx_time() - ts)
664 	{
665 		SET_MSG_RESULT(result, zbx_strdup(NULL, "Timeout while processing item."));
666 		goto err;
667 	}
668 
669 	crc = flen = 0;
670 
671 	while (0 < (nr = (int)read(f, buf, sizeof(buf))))
672 	{
673 		if (CONFIG_TIMEOUT < zbx_time() - ts)
674 		{
675 			SET_MSG_RESULT(result, zbx_strdup(NULL, "Timeout while processing item."));
676 			goto err;
677 		}
678 
679 		flen += nr;
680 
681 		for (i = 0; i < nr; i++)
682 			crc = (crc << 8) ^ crctab[((crc >> 24) ^ buf[i]) & 0xff];
683 	}
684 
685 	if (0 > nr)
686 	{
687 		SET_MSG_RESULT(result, zbx_strdup(NULL, "Cannot read from file."));
688 		goto err;
689 	}
690 
691 	/* include the length of the file */
692 	for (; 0 != flen; flen >>= 8)
693 		crc = (crc << 8) ^ crctab[((crc >> 24) ^ flen) & 0xff];
694 
695 	cval = ~crc;
696 
697 	SET_UI64_RESULT(result, cval);
698 
699 	ret = SYSINFO_RET_OK;
700 err:
701 	if (-1 != f)
702 		close(f);
703 
704 	return ret;
705 }
706