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