source: trunk/src/sh_hash.c@ 114

Last change on this file since 114 was 114, checked in by rainer, 17 years ago

Revision of file flag code.

File size: 90.5 KB
Line 
1/* SAMHAIN file system integrity testing */
2/* Copyright (C) 1999, 2000, 2001, 2002 Rainer Wichmann */
3/* */
4/* This program is free software; you can redistribute it */
5/* and/or modify */
6/* it under the terms of the GNU General Public License as */
7/* published by */
8/* the Free Software Foundation; either version 2 of the License, or */
9/* (at your option) any later version. */
10/* */
11/* This program is distributed in the hope that it will be useful, */
12/* but WITHOUT ANY WARRANTY; without even the implied warranty of */
13/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
14/* GNU General Public License for more details. */
15/* */
16/* You should have received a copy of the GNU General Public License */
17/* along with this program; if not, write to the Free Software */
18/* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
19
20#include "config_xor.h"
21
22/* define this if you want version 1.3 style database file */
23/* #define OLD_BUG */
24
25/* make sure state changes of a file are always reported, even
26 * with reportonlyonce=true
27 */
28/* #define REPLACE_OLD *//* moved to samhain.h */
29
30#include <stdlib.h>
31#include <string.h>
32#include <stdio.h>
33#include <sys/types.h>
34#include <sys/stat.h>
35#include <unistd.h>
36
37#ifdef MAJOR_IN_MKDEV
38#include <sys/mkdev.h>
39#else
40#ifdef MAJOR_IN_SYSMACROS
41#include <sys/sysmacros.h>
42#endif
43#endif
44
45#ifdef HAVE_MEMORY_H
46#include <memory.h>
47#endif
48
49#if defined(SH_WITH_CLIENT) || defined(SH_STANDALONE)
50
51#include "sh_hash.h"
52#include "sh_utils.h"
53#include "sh_error.h"
54#include "sh_tiger.h"
55#include "sh_gpg.h"
56#include "sh_unix.h"
57#include "sh_files.h"
58#include "sh_ignore.h"
59
60#if defined(SH_WITH_CLIENT)
61#include "sh_forward.h"
62#endif
63
64
65#define SH_KEY_NULL _("000000000000000000000000000000000000000000000000")
66
67
68#undef FIL__
69#define FIL__ _("sh_hash.c")
70
71static char * all_items (file_type * theFile, char * fileHash, int is_new);
72
73#define QUOTE_CHAR '='
74
75char * unquote_string (const char * str)
76{
77 int i = 0, t1, t2;
78 char * tmp = NULL;
79 size_t len, l2, j, k = 0;
80
81 SL_ENTER(_("unquote_string"));
82
83 if (str != NULL)
84 {
85 len = sl_strlen(str);
86 l2 = len - 2;
87 tmp = SH_ALLOC(len + 1);
88
89 for (j = 0; j <= len; ++j)
90 {
91 if (str[j] != QUOTE_CHAR)
92 {
93 tmp[k] = str[j];
94 }
95 else if (str[j] == QUOTE_CHAR && j < l2)
96 {
97 t1 = sh_util_hexchar(str[j+1]);
98 t2 = sh_util_hexchar(str[j+2]);
99 if ((t1|t2) >= 0)
100 {
101 i = 16 * t1 + t2;
102 tmp[k] = i;
103 j += 2;
104 }
105 else
106 {
107 tmp[k] = str[j];
108 }
109 }
110 else
111 tmp[k] = str[j];
112 ++k;
113 }
114 }
115 SL_RETURN(tmp, _("unquote_string"));
116}
117
118static char i2h[2];
119
120char * int2hex (unsigned char i)
121{
122 static char hexchars[] = "0123456789ABCDEF";
123
124 i2h[0] = hexchars[(((i) & 0xF0) >> 4)]; /* high */
125 i2h[1] = hexchars[((i) & 0x0F)]; /* low */
126
127 return i2h;
128}
129
130
131char * quote_string (const char * str)
132{
133 char * tmp;
134 char * tmp2;
135 size_t len, l2, j, i = 0, k = 0;
136
137 SL_ENTER(_("quote_string"));
138
139 if (str == NULL)
140 {
141 SL_RETURN(NULL, _("quote_string"));
142 }
143
144 len = sl_strlen(str);
145
146 for (j = 0; j < len; ++j)
147 if (str[j] == '\n' || str[j] == QUOTE_CHAR) ++i;
148
149 l2 = len + 1;
150 if (sl_ok_muls(3, i) && sl_ok_adds(l2, (3*i)))
151 {
152 tmp = SH_ALLOC(len + 1 + 3*i);
153 }
154 else
155 {
156 sh_error_handle((-1), FIL__, __LINE__, -1, MSG_E_SUBGEN,
157 _("integer overflow"),
158 _("quote_string"));
159 SL_RETURN(NULL, _("quote_string"));
160 }
161
162 for (j = 0; j <= len; ++j)
163 {
164 if (str[j] == '\n')
165 {
166 tmp2 = int2hex((unsigned char) '\n'); /* was 'n', fixed in 1.5.4 */
167 tmp[k] = QUOTE_CHAR; ++k;
168 tmp[k] = tmp2[0]; ++k;
169 tmp[k] = tmp2[1];
170 }
171 else if (str[j] == QUOTE_CHAR)
172 {
173 tmp2 = int2hex((unsigned char) QUOTE_CHAR);
174 tmp[k] = QUOTE_CHAR; ++k;
175 tmp[k] = tmp2[0]; ++k;
176 tmp[k] = tmp2[1];
177 }
178 else
179 {
180 tmp[k] = str[j];
181 }
182 ++k;
183 }
184 SL_RETURN(tmp, _("quote_string"));
185}
186
187static UINT32 * swap_32 (UINT32 * iptr)
188{
189#ifdef WORDS_BIGENDIAN
190 unsigned char swap;
191 unsigned char * ii = (unsigned char *) iptr;
192 swap = ii[0]; ii[0] = ii[3]; ii[3] = swap;
193 swap = ii[1]; ii[1] = ii[2]; ii[2] = swap;
194 return iptr;
195#else
196 return iptr;
197#endif
198}
199
200static UINT64 * swap_64 (UINT64 * iptr)
201{
202#ifdef WORDS_BIGENDIAN
203#ifdef UINT64_IS_32
204 swap_32 ((UINT32*) iptr);
205#else
206 unsigned char swap;
207 unsigned char * ii = (unsigned char *) iptr;
208 swap = ii[0]; ii[0] = ii[7]; ii[7] = swap;
209 swap = ii[1]; ii[1] = ii[6]; ii[6] = swap;
210 swap = ii[2]; ii[2] = ii[5]; ii[5] = swap;
211 swap = ii[3]; ii[3] = ii[4]; ii[4] = swap;
212#endif
213 return iptr;
214#else
215 return iptr;
216#endif
217}
218
219static unsigned short * swap_short (unsigned short * iptr)
220{
221#ifdef WORDS_BIGENDIAN
222 if (sizeof(short) == 4)
223 swap_32 ((UINT32*) iptr);
224 else
225 {
226 /* alignment problem */
227 unsigned char swap;
228 static unsigned short ooop;
229 unsigned char * ii;
230 ooop = *iptr;
231 ii = (unsigned char *) &ooop;
232 /* printf("SWAP0: %hd %d\n", *iptr, sizeof(unsigned short)); */
233 swap = ii[0]; ii[0] = ii[1]; ii[1] = swap;
234 /* printf("SWAP1: %hd\n", (unsigned short) ooop); */
235#ifndef OLD_BUG
236 return &ooop;
237#endif
238 }
239 return iptr;
240#else
241 return iptr;
242#endif
243}
244
245
246/* MAX_PATH_STORE must be >= KEY_LEN
247 */
248#define MAX_PATH_STORE 12287
249
250typedef struct store_info {
251 /*
252 char fullpath[MAX_PATH_STORE+2];
253 char linkpath[MAX_PATH_STORE+2];
254 */
255 UINT32 mode;
256 UINT32 linkmode;
257
258 UINT64 dev;
259 UINT64 rdev;
260 UINT32 hardlinks;
261 UINT32 ino;
262 UINT64 size;
263 UINT64 atime;
264 UINT64 mtime;
265 UINT64 ctime;
266 UINT32 owner;
267 UINT32 group;
268
269#ifdef OLD_BUG
270#if defined(__linux__)
271 UINT32 attributes;
272 char c_attributes[16];
273#endif
274#else
275 /* #if defined(__linux__) */
276 UINT32 attributes;
277 char c_attributes[16];
278 /* endif */
279#endif
280 unsigned short mark;
281 char c_owner[USER_MAX+2];
282 char c_group[GROUP_MAX+2];
283 char c_mode[11];
284 char checksum[KEY_LEN+1];
285} sh_filestore_t;
286
287typedef struct file_info {
288 sh_filestore_t theFile;
289 char * fullpath;
290 char * linkpath;
291 char * attr_string;
292 int fflags;
293 unsigned long modi_mask;
294 struct file_info * next;
295} sh_file_t;
296
297 static char *policy[] = {
298 N_("[]"),
299 N_("[ReadOnly]"),
300 N_("[LogFiles]"),
301 N_("[GrowingLogs]"),
302 N_("[IgnoreNone]"),
303 N_("[IgnoreAll]"),
304 N_("[Attributes]"),
305 N_("[User0]"),
306 N_("[User1]"),
307 N_("[User2]"),
308 N_("[User3]"),
309 N_("[User4]"),
310 N_("[Prelink]"),
311 NULL
312 };
313
314
315/**********************************
316 *
317 * hash table functions
318 *
319 **********************************
320 */
321
322#include "sh_hash.h"
323
324/* must fit an int */
325/* #define TABSIZE 2048 */
326#define TABSIZE 65536
327
328/* must fit an unsigned short */
329/* changed for V0.8, as the */
330/* database format has changed */
331
332/* changed again for V0.9 */
333/* #define REC_MAGIC 19 */
334/* changed again for V1.3 */
335#ifdef OLD_BUG
336#define REC_MAGIC 20
337#else
338/* changed again for V1.4 */
339#define REC_MAGIC 21
340#endif
341
342#define REC_FLAGS_ATTR (1<<8)
343#define REC_FLAGS_MASK 0xFF00
344
345/**************************************************************
346 *
347 * create a file_type from a sh_file_t
348 *
349 **************************************************************/
350static file_type * sh_hash_create_ft (const sh_file_t * p, char * fileHash)
351{
352 file_type * theFile;
353#if defined(__linux__) || defined(HAVE_STAT_FLAGS)
354 int i = 16;
355#endif
356
357 SL_ENTER(_("sh_hash_create_ft"));
358
359 theFile = SH_ALLOC(sizeof(file_type));
360
361 sl_strlcpy(theFile->c_mode, p->theFile.c_mode, 11);
362 theFile->mode = p->theFile.mode;
363#if defined(__linux__) || defined(HAVE_STAT_FLAGS)
364 sl_strlcpy(theFile->c_attributes, p->theFile.c_attributes, i /* 16 */);
365 theFile->attributes = p->theFile.attributes;
366#endif
367
368 sl_strlcpy(theFile->fullpath, p->fullpath, PATH_MAX);
369 if (p->linkpath != NULL && theFile->c_mode[0] == 'l')
370 {
371 sl_strlcpy(theFile->linkpath, p->linkpath, PATH_MAX);
372 }
373 else
374 {
375 theFile->linkpath[0] = '-';
376 theFile->linkpath[1] = '\0';
377 }
378 sl_strlcpy(fileHash, p->theFile.checksum, KEY_LEN+1);
379
380 theFile->mtime = p->theFile.mtime;
381 theFile->ctime = p->theFile.ctime;
382 theFile->atime = p->theFile.atime;
383
384 theFile->size = p->theFile.size;
385
386 sl_strlcpy(theFile->c_group, p->theFile.c_group, GROUP_MAX+2);
387 theFile->group = p->theFile.group;
388 sl_strlcpy(theFile->c_owner, p->theFile.c_owner, USER_MAX+2);
389 theFile->owner = p->theFile.owner;
390
391 theFile->ino = p->theFile.ino;
392 theFile->rdev = p->theFile.rdev;
393 theFile->dev = p->theFile.dev;
394 theFile->hardlinks = p->theFile.hardlinks;
395
396 if (p->attr_string)
397 theFile->attr_string = sh_util_strdup(p->attr_string);
398 else
399 theFile->attr_string = NULL;
400
401 SL_RETURN((theFile), _("sh_hash_create_ft"));
402}
403
404static sh_file_t * hashsearch (char * s);
405
406static sh_file_t * tab[TABSIZE];
407
408/**************************************************************
409 *
410 * compute hash function
411 *
412 **************************************************************/
413
414static int hashfunc(char *s)
415{
416 unsigned int n = 0;
417
418 for ( ; *s; s++)
419 n = 31 * n + *s;
420
421 return n & (TABSIZE - 1); /* % TABSIZE */;
422}
423
424
425int hashreport_missing( char *fullpath, int level)
426{
427 sh_file_t * p;
428 char * tmp;
429 char fileHash[KEY_LEN + 1];
430 file_type * theFile;
431 char * str;
432
433 /* -------- find the entry for the file ---------------- */
434
435 if (sl_strlen(fullpath) <= MAX_PATH_STORE)
436 p = hashsearch(fullpath);
437 else
438 p = hashsearch( sh_tiger_hash(fullpath,
439 TIGER_DATA,
440 sl_strlen(fullpath))
441 );
442 if (p == NULL)
443 return -1;
444
445 theFile = sh_hash_create_ft (p, fileHash);
446 str = all_items(theFile, fileHash, 0);
447 tmp = sh_util_safe_name(fullpath);
448 sh_error_handle (level, FIL__, __LINE__, 0,
449 MSG_FI_MISS2, tmp, str);
450 SH_FREE(tmp);
451 SH_FREE(str);
452 if (theFile->attr_string)
453 SH_FREE(theFile->attr_string);
454 SH_FREE(theFile);
455 return 0;
456}
457
458
459/**************************************************************
460 *
461 * search for files not visited, and check whether they exist
462 *
463 **************************************************************/
464static void hash_unvisited (int j,
465 sh_file_t *prev, sh_file_t *p, ShErrLevel level)
466{
467 struct stat buf;
468 int i;
469 char * tmp;
470 char * ptr;
471 char fileHash[KEY_LEN + 1];
472 file_type * theFile;
473
474 char * str;
475
476
477 SL_ENTER(_("hash_unvisited"));
478
479 if (p->next != NULL)
480 hash_unvisited (j, p, p->next, level);
481
482 if (p->fullpath == NULL)
483 {
484 SL_RET0(_("hash_unvisited"));
485 }
486
487 /* Not a fully qualified path, i.e. some info stored by some module
488 */
489 if (p->fullpath[0] != '/')
490 {
491 SL_RET0(_("hash_unvisited"));
492 }
493
494 /* visited flag not set: not seen;
495 * checked flag set: not seen (i.e. missing), and already checked
496 * reported flag not set: not reported yet
497 * allignore flag not set: not under IgnoreAll
498 *
499 * Files/directories under IgnoreAll are noticed as missing already
500 * during the file check.
501 */
502 if (((!SH_FFLAG_VISITED_SET(p->fflags)) || SH_FFLAG_CHECKED_SET(p->fflags))
503 && (!SH_FFLAG_REPORTED_SET(p->fflags))
504 && (!SH_FFLAG_ALLIGNORE_SET(p->fflags)))
505 {
506 i = retry_lstat(FIL__, __LINE__, p->fullpath, &buf);
507
508 /* if file does not exist
509 */
510 if (0 != i)
511 {
512 ptr = sh_util_dirname (p->fullpath);
513 if (ptr)
514 {
515 /* If any of the parent directories is under IgnoreAll
516 */
517 if (0 != sh_files_is_allignore(ptr))
518 level = ShDFLevel[SH_LEVEL_ALLIGNORE];
519 SH_FREE(ptr);
520 }
521
522 /* Only report if !SH_FFLAG_CHECKED_SET
523 */
524 if (!SH_FFLAG_CHECKED_SET(p->fflags))
525 {
526 if (S_FALSE == sh_ignore_chk_del(p->fullpath))
527 {
528 tmp = sh_util_safe_name(p->fullpath);
529
530 theFile = sh_hash_create_ft (p, fileHash);
531 str = all_items(theFile, fileHash, 0);
532 sh_error_handle (level, FIL__, __LINE__, 0,
533 MSG_FI_MISS2, tmp, str);
534 SH_FREE(str);
535 if (theFile->attr_string)
536 SH_FREE(theFile->attr_string);
537 SH_FREE(theFile);
538
539 SH_FREE(tmp);
540 }
541 }
542
543 /* We rewrite the db on update, thus we need to keep this
544 * if the user does not want to purge it from the db.
545 */
546
547 if ((sh.flag.reportonce == S_TRUE && sh.flag.update == S_FALSE) ||
548 (S_TRUE == sh.flag.update && S_TRUE == sh_util_ask_update(p->fullpath)))
549 {
550#ifdef REPLACE_OLD
551 /* Remove the old entry
552 */
553 if (prev == p)
554 tab[j] = p->next;
555 else
556 prev->next = p->next;
557 if (p->fullpath)
558 {
559 SH_FREE(p->fullpath);
560 p->fullpath = NULL;
561 }
562 if (p->linkpath)
563 {
564 SH_FREE(p->linkpath);
565 p->linkpath = NULL;
566 }
567 if (p->attr_string)
568 {
569 SH_FREE(p->attr_string);
570 p->attr_string = NULL;
571 }
572 SH_FREE(p);
573 p = NULL;
574 SL_RET0(_("hash_unvisited"));
575#else
576 SET_SH_FFLAG_REPORTED(p->fflags);
577#endif
578 }
579 }
580 }
581
582 else if (SH_FFLAG_VISITED_SET(p->fflags) && SH_FFLAG_REPORTED_SET(p->fflags)
583 && (!SH_FFLAG_ALLIGNORE_SET(p->fflags)))
584 {
585 if (S_FALSE == sh_ignore_chk_new(p->fullpath))
586 {
587 tmp = sh_util_safe_name(p->fullpath);
588
589 theFile = sh_hash_create_ft (p, fileHash);
590 str = all_items(theFile, fileHash, 0);
591 sh_error_handle (level, FIL__, __LINE__, 0,
592 MSG_FI_MISS2, tmp, str);
593 SH_FREE(str);
594 if (theFile->attr_string)
595 SH_FREE(theFile->attr_string);
596 SH_FREE(theFile);
597
598 SH_FREE(tmp);
599 }
600
601 CLEAR_SH_FFLAG_REPORTED(p->fflags);
602 }
603
604 if (sh.flag.reportonce == S_FALSE)
605 CLEAR_SH_FFLAG_REPORTED(p->fflags);
606
607 CLEAR_SH_FFLAG_VISITED(p->fflags);
608 CLEAR_SH_FFLAG_CHECKED(p->fflags);
609
610 SL_RET0(_("hash_unvisited"));
611}
612
613
614/*********************************************************************
615 *
616 * Search for files in the database that have been deleted from disk.
617 *
618 *********************************************************************/
619void sh_hash_unvisited (ShErrLevel level)
620{
621 int i;
622
623 SL_ENTER(_("sh_hash_unvisited"));
624 for (i = 0; i < TABSIZE; ++i)
625 {
626 if (tab[i] != NULL)
627 hash_unvisited (i, tab[i], tab[i], level);
628 }
629 SL_RET0(_("hash_unvisited"));
630}
631
632
633/**********************************************************************
634 *
635 * delete hash array
636 *
637 **********************************************************************/
638static void hash_kill (sh_file_t *p)
639{
640 SL_ENTER(_("hash_kill"));
641
642 if (p == NULL)
643 SL_RET0(_("hash_kill"));
644
645 if (p->next != NULL)
646 hash_kill (p->next);
647
648 if (p->fullpath)
649 {
650 SH_FREE(p->fullpath);
651 p->fullpath = NULL;
652 }
653 if (p->linkpath)
654 {
655 SH_FREE(p->linkpath);
656 p->linkpath = NULL;
657 }
658 if (p->attr_string)
659 {
660 SH_FREE(p->attr_string);
661 p->attr_string = NULL;
662 }
663 SH_FREE(p);
664 p = NULL;
665 SL_RET0(_("hash_kill"));
666}
667
668
669/***********************************************************************
670 *
671 * get info out of hash array
672 *
673 ***********************************************************************/
674static sh_file_t * hashsearch (char * s)
675{
676 sh_file_t * p;
677
678 SL_ENTER(_("hashsearch"));
679
680 if (s)
681 {
682 for (p = tab[hashfunc(s)]; p; p = p->next)
683 if ((p->fullpath != NULL) && (0 == strcmp(s, p->fullpath)))
684 SL_RETURN( p, _("hashsearch"));
685 }
686 SL_RETURN( NULL, _("hashsearch"));
687}
688
689
690/***********************************************************************
691 *
692 * insert into hash array
693 *
694 ***********************************************************************/
695static void hashinsert (sh_file_t * s)
696{
697 sh_file_t * p;
698 sh_file_t * q;
699 int key;
700
701 SL_ENTER(_("hashinsert"));
702
703 key = hashfunc(s->fullpath);
704
705 if (tab[key] == NULL)
706 {
707 tab[key] = s;
708 tab[key]->next = NULL;
709 SL_RET0(_("hashinsert"));
710 }
711 else
712 {
713 p = tab[key];
714 while (1)
715 {
716 if (p && p->fullpath &&
717 0 == strcmp(s->fullpath, p->fullpath))
718 {
719 q = p->next;
720 SH_FREE(p->fullpath);
721 if(p->linkpath)
722 SH_FREE(p->linkpath);
723 if(p->attr_string)
724 SH_FREE(p->attr_string);
725 memcpy(p, s, sizeof(sh_file_t));
726 p->next = q;
727 SH_FREE(s);
728 s = NULL;
729 SL_RET0(_("hashinsert"));
730 }
731 else
732 if (p->next == NULL)
733 {
734 p->next = s;
735 p->next->next = NULL;
736 SL_RET0(_("hashinsert"));
737 }
738 p = p->next;
739 }
740 }
741 /* notreached */
742}
743
744
745/******************************************************************
746 *
747 * Get a single line
748 *
749 ******************************************************************/
750static FILE * sh_fin_fd = NULL;
751
752static int sh_hash_getline (FILE * fd, char * line, int sizeofline)
753{
754 register int n = 0;
755 char * res;
756
757 if (sizeofline < 2) {
758 if (sizeofline > 0) line[0] = '\0';
759 return 0;
760 }
761 res = fgets(line, sizeofline, fd);
762 if (res == NULL)
763 {
764 line[0] = '\0';
765 return -1;
766 }
767 n = strlen(line);
768 if (n > 1) {
769 --n;
770 line[n] = '\0'; /* remove terminating '\n' */
771 }
772 return n;
773}
774
775static void sh_hash_getline_end ()
776{
777 fclose (sh_fin_fd);
778 sh_fin_fd = NULL;
779 return;
780}
781
782/******************************************************************
783 *
784 * ------- Check functions -------
785 *
786 ******************************************************************/
787
788static int IsInit = 0;
789
790
791/******************************************************************
792 *
793 * Fast forward to start of data
794 *
795 ******************************************************************/
796int sh_hash_setdataent (SL_TICKET fd, char * line, int size, const char * file)
797{
798 long i;
799 extern int get_the_fd (SL_TICKET ticket);
800
801 SL_ENTER(_("sh_hash_setdataent"));
802
803 sl_rewind (fd);
804
805 if (sh_fin_fd != NULL)
806 {
807 fclose (sh_fin_fd);
808 sh_fin_fd = NULL;
809 }
810
811 sh_fin_fd = fdopen(get_the_fd(fd), "rb");
812 if (!sh_fin_fd)
813 {
814 dlog(1, FIL__, __LINE__,
815 _("The file signature database: %s is not readable.\n"),
816 (NULL == file) ? _("(null)") : file);
817 sh_error_handle ((-1), FIL__, __LINE__, 0, MSG_P_NODATA,
818 ( (NULL == file) ? _("(null)") : file)
819 );
820 aud_exit (FIL__, __LINE__, EXIT_FAILURE);
821 }
822
823 while (1)
824 {
825 i = sh_hash_getline (sh_fin_fd, line, size);
826 if (i < 0 )
827 {
828 SH_FREE(line);
829 dlog(1, FIL__, __LINE__,
830 _("The file signature database: %s does not\ncontain any data, or the start-of-file marker is missing (unlikely,\nunless modified by hand).\n"),
831 (NULL == file) ? _("(null)") : file);
832
833 sh_error_handle ((-1), FIL__, __LINE__, 0, MSG_P_NODATA,
834 ( (NULL == file) ? _("(null)") : file)
835 );
836 aud_exit (FIL__, __LINE__, EXIT_FAILURE);
837 }
838
839#if defined(SH_STEALTH)
840 if (0 == sl_strncmp (line, N_("[SOF]"), 5))
841#else
842 if (0 == sl_strncmp (line, _("[SOF]"), 5))
843#endif
844 break;
845 }
846 SL_RETURN( 1, _("sh_hash_setdataent"));
847}
848
849static int sh_hash_setdataent_old (SL_TICKET fd, char * line, int size,
850 char * file)
851{
852 long i;
853
854 SL_ENTER(_("sh_hash_setdataent_old"));
855
856 sl_rewind (fd);
857
858 while (1)
859 {
860 i = sh_unix_getline (fd, line, size-1);
861 if (i < 0 )
862 {
863 SH_FREE(line);
864 dlog(1, FIL__, __LINE__,
865 _("The file signature database: %s does not\ncontain any data, or the start-of-file marker is missing (unlikely,\nunless modified by hand).\n"),
866 (NULL == file) ? _("(null)") : file);
867
868 sh_error_handle ((-1), FIL__, __LINE__, 0, MSG_P_NODATA,
869 ( (NULL == file) ? _("(null)") : file)
870 );
871 aud_exit (FIL__, __LINE__, EXIT_FAILURE);
872 }
873
874#if defined(SH_STEALTH)
875 if (0 == sl_strncmp (line, N_("[SOF]"), 5))
876#else
877 if (0 == sl_strncmp (line, _("[SOF]"), 5))
878#endif
879 break;
880 }
881 SL_RETURN( 1, _("sh_hash_setdataent_old"));
882}
883
884/******************************************************************
885 *
886 * Read next record
887 *
888 ******************************************************************/
889sh_file_t * sh_hash_getdataent (SL_TICKET fd, char * line, int size)
890{
891 sh_file_t * p;
892 sh_filestore_t ft;
893 long i;
894 size_t len;
895 char * fullpath;
896 char * linkpath;
897 char * attr_string = NULL;
898 char * tmp;
899
900 SL_ENTER(_("sh_hash_getdataent"));
901
902 (void) fd;
903
904 /* Read next record -- Part One
905 */
906 p = SH_ALLOC(sizeof(sh_file_t));
907
908 i = fread (&ft, sizeof(sh_filestore_t), 1, sh_fin_fd);
909 /* i = sl_read(fd, &ft, sizeof(sh_filestore_t)); */
910 /* if ( SL_ISERROR(i) || i == 0) */
911 if (i < 1)
912 {
913 SH_FREE(p);
914 SL_RETURN( NULL, _("sh_hash_getdataent"));
915 }
916
917 swap_32(&(ft.mode));
918 swap_32(&(ft.linkmode));
919 swap_64(&(ft.dev));
920 swap_64(&(ft.rdev));
921 swap_32(&(ft.hardlinks));
922 swap_32(&(ft.ino));
923 swap_64(&(ft.size));
924 swap_64(&(ft.atime));
925 swap_64(&(ft.mtime));
926 swap_64(&(ft.ctime));
927 swap_32(&(ft.owner));
928 swap_32(&(ft.group));
929#if defined(__linux__) || defined(HAVE_STAT_FLAGS)
930 swap_32(&(ft.attributes));
931#endif
932#ifdef OLD_BUG
933 swap_short(&(ft.mark));
934#else
935 ft.mark = *(swap_short(&(ft.mark)));
936#endif
937
938 if ((ft.mark & ~REC_FLAGS_MASK) != REC_MAGIC)
939 {
940 SH_FREE(p);
941 SL_RETURN( NULL, _("sh_hash_getdataent"));
942 }
943
944 /* Read next record -- Part Two -- Fullpath
945 */
946 i = sh_hash_getline (sh_fin_fd, line, size);
947 if (i < 0 )
948 {
949 SH_FREE(line);
950 SH_FREE(p);
951 dlog(1, FIL__, __LINE__,
952 _("There is a corrupt record in the file signature database: %s\nThe file path is missing.\n"),
953 (NULL == file_path('D', 'R'))? _("(null)"):file_path('D', 'R'));
954 sh_error_handle ((-1), FIL__, __LINE__, 0, MSG_P_NODATA,
955 ( (NULL == file_path('D', 'R')) ? _("(null)") :
956 file_path('D', 'R'))
957 );
958 aud_exit (FIL__, __LINE__,EXIT_FAILURE);
959 }
960
961 tmp = unquote_string (line);
962 len = sl_strlen(tmp)+1;
963 fullpath = SH_ALLOC(len);
964 (void) sl_strlcpy (fullpath, tmp, len);
965 if (tmp)
966 SH_FREE(tmp);
967 if (fullpath[len-2] == '\n')
968 fullpath[len-2] = '\0';
969
970 /* Read next record -- Part Three -- Linkpath
971 */
972 i = sh_hash_getline (sh_fin_fd, line, size);
973 if (i < 0 )
974 {
975 SH_FREE(line);
976 SH_FREE(fullpath);
977 SH_FREE(p);
978 dlog(1, FIL__, __LINE__,
979 _("There is a corrupt record in the file signature database: %s\nThe link path (or its placeholder) is missing.\n"),
980 (NULL == file_path('D', 'R'))? _("(null)"):file_path('D', 'R'));
981 sh_error_handle ((-1), FIL__, __LINE__, 0, MSG_P_NODATA,
982 ( (NULL == file_path('D', 'R')) ? _("(null)") :
983 file_path('D', 'R'))
984 );
985 aud_exit (FIL__, __LINE__,EXIT_FAILURE);
986 }
987
988 tmp = unquote_string (line);
989 len = sl_strlen(tmp)+1;
990 linkpath = SH_ALLOC(len);
991 (void) sl_strlcpy (linkpath, tmp, len);
992 if (tmp)
993 SH_FREE(tmp);
994 if (linkpath[len-2] == '\n')
995 linkpath[len-2] = '\0';
996
997 /* Read next record -- Part Four -- attr_string
998 */
999 if ((ft.mark & REC_FLAGS_ATTR) != 0)
1000 {
1001 i = sh_hash_getline (sh_fin_fd, line, size);
1002 if (i < 0 )
1003 {
1004 SH_FREE(line);
1005 SH_FREE(fullpath);
1006 SH_FREE(linkpath);
1007 SH_FREE(p);
1008 dlog(1, FIL__, __LINE__,
1009 _("There is a corrupt record in the file signature database: %s\nThe attribute string is missing.\n"),
1010 (NULL == file_path('D', 'R'))? _("(null)"):file_path('D', 'R'));
1011 sh_error_handle ((-1), FIL__, __LINE__, 0, MSG_P_NODATA,
1012 ( (NULL == file_path('D', 'R')) ? _("(null)") :
1013 file_path('D', 'R'))
1014 );
1015 aud_exit (FIL__, __LINE__,EXIT_FAILURE);
1016 }
1017
1018 tmp = unquote_string (line);
1019
1020 len = sl_strlen(tmp)+1;
1021 attr_string = SH_ALLOC(len);
1022 (void) sl_strlcpy (attr_string, tmp, len);
1023 if (tmp)
1024 SH_FREE(tmp);
1025 if (attr_string[len-2] == '\n')
1026 attr_string[len-2] = '\0';
1027 }
1028
1029 /* Read next record -- Part Four -- Decode
1030 */
1031#if defined(SH_STEALTH)
1032 sh_do_decode(fullpath, sl_strlen(fullpath));
1033
1034#if defined(__linux__) || defined(HAVE_STAT_FLAGS)
1035 sh_do_decode(ft.c_attributes, sl_strlen(ft.c_attributes));
1036#endif
1037
1038 sh_do_decode(ft.c_mode, sl_strlen(ft.c_mode));
1039 sh_do_decode(ft.c_owner, sl_strlen(ft.c_owner));
1040 sh_do_decode(ft.c_group, sl_strlen(ft.c_group));
1041 sh_do_decode(ft.checksum, sl_strlen(ft.checksum));
1042
1043
1044 if (ft.c_mode[0] == 'l')
1045 {
1046 sh_do_decode(linkpath, sl_strlen(linkpath));
1047 }
1048 if ((ft.mark & REC_FLAGS_ATTR) != 0)
1049 {
1050 sh_do_decode(attr_string, sl_strlen(attr_string));
1051 }
1052#endif
1053
1054 memcpy( &(*p).theFile, &ft, sizeof(sh_filestore_t) );
1055
1056 p->fflags = 0;
1057
1058 p->modi_mask = 0L;
1059 p->fullpath = fullpath;
1060 p->linkpath = linkpath;
1061
1062 p->attr_string = attr_string;
1063
1064 /* set to an invalid value
1065 */
1066 ft.mark = (REC_MAGIC + 5);
1067
1068 SL_RETURN( p, _("sh_hash_getdataent"));
1069}
1070
1071/******************************************************************
1072 *
1073 * Initialize
1074 *
1075 ******************************************************************/
1076void sh_hash_init ()
1077{
1078
1079#define FGETS_BUF 16384
1080
1081 sh_file_t * p;
1082 SL_TICKET fd = (-1);
1083 long i;
1084 int count = 0;
1085 char * line = NULL;
1086
1087#if defined(WITH_GPG) || defined(WITH_PGP)
1088 extern int get_the_fd (SL_TICKET ticket);
1089 FILE * fin_cp;
1090
1091 char * buf = NULL;
1092 int bufc;
1093 int flag_pgp = S_FALSE;
1094 int flag_nohead = S_FALSE;
1095 SL_TICKET fdTmp = (-1);
1096 SL_TICKET open_tmp (void);
1097#endif
1098
1099 SL_ENTER(_("sh_hash_init"));
1100
1101 if (IsInit == 1)
1102 SL_RET0(_("sh_hash_init"));
1103
1104 for (i = 0; i < TABSIZE; ++i)
1105 tab[i] = NULL;
1106
1107#if defined(SH_WITH_CLIENT)
1108
1109 /* Data file from Server
1110 */
1111
1112 if (fd == (-1) && 0 == sl_strcmp(file_path('D', 'R'), _("REQ_FROM_SERVER")))
1113 {
1114 sh_error_handle ((-1), FIL__, __LINE__, 0, MSG_D_DSTART);
1115 fd = sh_forward_req_file(_("DATA"));
1116 if (SL_ISERROR(fd))
1117 {
1118 dlog(1, FIL__, __LINE__,
1119 _("Could not retrieve the file signature database from the server(errnum = %ld).\nPossible reasons include:\n - the server is not running,\n - session key negotiation failed (see the manual for proper setup), or\n - the server cannot access the file.\n"), fd);
1120 sh_error_handle ((-1), FIL__, __LINE__, fd, MSG_EXIT_ABORT1,
1121 sh.prg_name);
1122 aud_exit (FIL__, __LINE__, EXIT_FAILURE);
1123 }
1124 sl_rewind (fd);
1125
1126 tiger_fd = fd;
1127 sl_strlcpy (sh.data.hash,
1128 sh_tiger_hash (file_path('C', 'R'), /*irrelevant, TIGER_FD*/
1129 TIGER_FD, 0),
1130 KEY_LEN+1);
1131 sl_rewind (fd);
1132 }
1133 else
1134#endif
1135 /* Local data file
1136 */
1137
1138 if (fd == (-1))
1139 {
1140 if ( SL_ISERROR(fd = sl_open_read(file_path('D', 'R'), SL_YESPRIV)))
1141 {
1142 TPT(( 0, FIL__, __LINE__, _("msg=<Error opening: %s>\n"),
1143 file_path('D', 'R')));
1144 dlog(1, FIL__, __LINE__,
1145 _("Could not open the local file signature database for reading because\nof the following error: %s (errnum = %ld)\nIf this is a permission problem, you need to change file permissions\nto make the file readable for the effective UID: %d\n"),
1146 sl_get_errmsg(), fd, (int) sl_ret_euid());
1147 sh_error_handle ((-1), FIL__, __LINE__, fd, MSG_EXIT_ABORT1,
1148 sh.prg_name);
1149 aud_exit (FIL__, __LINE__, EXIT_FAILURE);
1150 }
1151
1152 TPT(( 0, FIL__, __LINE__, _("msg=<Opened database: %s>\n"),
1153 file_path('D', 'R')));
1154
1155 tiger_fd = fd;
1156 if (0 != sl_strncmp(sh.data.hash,
1157 sh_tiger_hash (file_path('D', 'R'), TIGER_FD, 0),
1158 KEY_LEN)
1159 && sh.flag.checkSum != SH_CHECK_INIT)
1160 {
1161 dlog(1, FIL__, __LINE__,
1162 _("The checksum of the file signature database has changed since startup.\n"));
1163 sh_error_handle ((-1), FIL__, __LINE__, 0, MSG_E_AUTH,
1164 ( (NULL == file_path('D', 'R')) ? _("(null)") :
1165 file_path('D', 'R') )
1166 );
1167 aud_exit (FIL__, __LINE__, EXIT_FAILURE);
1168 }
1169 sl_rewind (fd);
1170
1171 } /* new 1.4.8 */
1172
1173 if (sig_termfast == 1) /* SIGTERM */
1174 {
1175 TPT((0, FIL__, __LINE__, _("msg=<Terminate.>\n")));
1176 --sig_raised; --sig_urgent;
1177 aud_exit (FIL__, __LINE__, EXIT_SUCCESS);
1178 }
1179
1180#if defined(WITH_GPG) || defined(WITH_PGP)
1181 /* new 1.4.8: also checked for server data */
1182
1183 /* extract the data and copy to temporary file
1184 */
1185 fdTmp = open_tmp();
1186
1187 fin_cp = fdopen(get_the_fd(fd), "rb");
1188 buf = SH_ALLOC(FGETS_BUF);
1189
1190 while (NULL != fgets(buf, FGETS_BUF, fin_cp))
1191 {
1192 bufc = 0;
1193 while (bufc < FGETS_BUF) {
1194 if (buf[bufc] == '\n') { ++bufc; break; }
1195 ++bufc;
1196 }
1197
1198 if (sig_termfast == 1) /* SIGTERM */
1199 {
1200 TPT((0, FIL__, __LINE__, _("msg=<Terminate.>\n")));
1201 --sig_raised; --sig_urgent;
1202 aud_exit (FIL__, __LINE__, EXIT_SUCCESS);
1203 }
1204
1205 if (flag_pgp == S_FALSE &&
1206 (0 == sl_strcmp(buf, _("-----BEGIN PGP SIGNED MESSAGE-----\n"))||
1207 0 == sl_strcmp(buf, _("-----BEGIN PGP MESSAGE-----\n")))
1208 )
1209 {
1210 flag_pgp = S_TRUE;
1211 sl_write(fdTmp, buf, bufc);
1212 continue;
1213 }
1214
1215 if (flag_pgp == S_TRUE && flag_nohead == S_FALSE)
1216 {
1217 if (buf[0] == '\n')
1218 {
1219 flag_nohead = S_TRUE;
1220 sl_write(fdTmp, buf, 1);
1221 continue;
1222 }
1223 else if (0 == sl_strncmp(buf, _("Hash:"), 5) ||
1224 0 == sl_strncmp(buf, _("NotDashEscaped:"), 15))
1225 {
1226 sl_write(fdTmp, buf, bufc);
1227 continue;
1228 }
1229 else
1230 continue;
1231 }
1232
1233 if (flag_pgp == S_TRUE && buf[0] == '\n')
1234 {
1235 sl_write(fdTmp, buf, 1);
1236 }
1237 else if (flag_pgp == S_TRUE)
1238 {
1239 /* sl_write_line(fdTmp, buf, bufc); */
1240 sl_write(fdTmp, buf, bufc);
1241 }
1242
1243 if (flag_pgp == S_TRUE &&
1244 0 == sl_strcmp(buf, _("-----END PGP SIGNATURE-----\n")))
1245 break;
1246 }
1247 SH_FREE(buf);
1248 sl_close(fd);
1249 fclose(fin_cp);
1250
1251 fd = fdTmp;
1252 sl_rewind (fd);
1253
1254 /* Validate signature of open file.
1255 */
1256 if (0 != sh_gpg_check_sign (0, fd, 2))
1257 {
1258 aud_exit (FIL__, __LINE__, EXIT_FAILURE);
1259 }
1260 sl_rewind (fd);
1261#endif
1262 /* } new 1.4.8 check sig also for files downloaded from server */
1263
1264 line = SH_ALLOC(MAX_PATH_STORE+1);
1265
1266 /* fast forward to start of data
1267 */
1268 sh_hash_setdataent(fd, line, MAX_PATH_STORE, file_path('D', 'R'));
1269
1270 while (1)
1271 {
1272 if (sig_termfast == 1) /* SIGTERM */
1273 {
1274 TPT((0, FIL__, __LINE__, _("msg=<Terminate.>\n")));
1275 --sig_raised; --sig_urgent;
1276 aud_exit (FIL__, __LINE__, EXIT_SUCCESS);
1277 }
1278
1279 p = sh_hash_getdataent (fd, line, MAX_PATH_STORE);
1280 if (p != NULL)
1281 {
1282 hashinsert (p);
1283 ++count;
1284 }
1285 else
1286 break;
1287 }
1288
1289 if (line != NULL)
1290 SH_FREE(line);
1291
1292 /* Always keep db in memory, so we have no open file
1293 */
1294 sl_close (fd);
1295 sh_hash_getline_end();
1296 fd = -1;
1297
1298 /* --- Initialization done successfully. ---
1299 */
1300 IsInit = 1;
1301 SL_RET0(_("sh_hash_init"));
1302}
1303
1304/*****************************************************************
1305 *
1306 * delete hash array
1307 *
1308 *****************************************************************/
1309void sh_hash_hashdelete ()
1310{
1311 int i;
1312
1313 SL_ENTER(_("sh_hash_hashdelete"));
1314
1315 if (IsInit == 0)
1316 SL_RET0(_("sh_hash_hashdelete"));
1317 for (i = 0; i < TABSIZE; ++i)
1318 if (tab[i] != NULL)
1319 {
1320 hash_kill (tab[i]);
1321 tab[i] = NULL;
1322 }
1323 IsInit = 0;
1324 SL_RET0(_("sh_hash_hashdelete"));
1325}
1326
1327/******************************************************************
1328 *
1329 * Insert a file into the database.
1330 *
1331 ******************************************************************/
1332static int pushdata_isfirst = 1;
1333static SL_TICKET pushdata_fd = -1;
1334
1335static int pushdata_stdout = S_FALSE;
1336
1337static char * sh_db_version_string = NULL;
1338
1339int sh_hash_pushdata_stdout (const char * str)
1340{
1341 if (!str)
1342 { pushdata_stdout = S_TRUE; return 0; }
1343 return -1;
1344}
1345
1346int sh_hash_version_string(const char * str)
1347{
1348 if (str)
1349 {
1350 if (sh_db_version_string != NULL) {
1351 SH_FREE(sh_db_version_string);
1352 }
1353 if (0 == sl_strncmp(str, _("NULL"), 4))
1354 {
1355 sh_db_version_string = NULL;
1356 return 0;
1357 }
1358 sh_db_version_string = sh_util_strdup(str);
1359 return 0;
1360 }
1361 return -1;
1362}
1363
1364
1365void sh_hash_pushdata (file_type * buf, char * fileHash)
1366{
1367 static long p_count = 0;
1368
1369 int status = 0;
1370
1371 char * tmp;
1372 size_t tmp_len = 0;
1373 size_t old_len = 0;
1374
1375 sh_filestore_t p;
1376
1377 struct stat sbuf;
1378
1379 char * fullpath = NULL;
1380 char * linkpath = NULL;
1381 char * attr_string = NULL;
1382
1383 char * line = NULL;
1384
1385 char timestring[81];
1386 char * timep;
1387
1388#if !defined(__linux__) && !defined(HAVE_STAT_FLAGS)
1389 int i;
1390#endif
1391
1392 SL_ENTER(_("sh_hash_pushdata"));
1393
1394 fullpath = SH_ALLOC(MAX_PATH_STORE+1);
1395 linkpath = SH_ALLOC(MAX_PATH_STORE+1);
1396
1397 linkpath[0] = '-';
1398 linkpath[1] = '\0';
1399 fullpath[0] = '-';
1400 fullpath[1] = '\0';
1401
1402 if (!buf) {
1403 memset(&p, '\0', sizeof(sh_filestore_t));
1404 }
1405
1406 if ((pushdata_stdout == S_TRUE) && (sh.flag.update == S_TRUE))
1407 {
1408 dlog(1, FIL__, __LINE__,
1409 _("You cannot write the database to stdout when you use update rather than init.\n"));
1410 sh_error_handle((-1), FIL__, __LINE__, 0, MSG_EXIT_ABORTS,
1411 _("Writing database to stdout with update"),
1412 sh.prg_name,
1413 _("sh_hash_pushdata"));
1414 aud_exit(FIL__, __LINE__, EXIT_FAILURE);
1415 }
1416
1417 if ((pushdata_stdout == S_TRUE) && (sl_is_suid()))
1418 {
1419 dlog(1, FIL__, __LINE__,
1420 _("You cannot write the database to stdout when running with suid privileges.\n"));
1421 sh_error_handle((-1), FIL__, __LINE__, 0, MSG_EXIT_ABORTS,
1422 _("Writing database to stdout when suid"),
1423 sh.prg_name,
1424 _("sh_hash_pushdata"));
1425 aud_exit(FIL__, __LINE__, EXIT_FAILURE);
1426 }
1427
1428
1429 if ((pushdata_stdout == S_FALSE) &&
1430 ( (NULL == file_path('D', 'W')) ||
1431 (0 == sl_strcmp(file_path('D', 'W'), _("REQ_FROM_SERVER"))) ))
1432 {
1433 dlog(1, FIL__, __LINE__,
1434 _("You need to configure a local path for initializing the database\nlike ./configure --with-data-file=REQ_FROM_SERVER/some/local/path\n"));
1435 sh_error_handle((-1), FIL__, __LINE__, 0, MSG_EXIT_ABORTS,
1436 _("No local path for database specified"),
1437 sh.prg_name,
1438 _("sh_hash_pushdata"));
1439 aud_exit(FIL__, __LINE__, EXIT_FAILURE);
1440 }
1441
1442
1443 if ((pushdata_stdout == S_FALSE) && (pushdata_isfirst == 1))
1444 {
1445 /* Warn that file already exists; file_path != NULL here because
1446 * checked above
1447 */
1448 if (0 == retry_lstat(FIL__, __LINE__, file_path('D', 'W'), &sbuf))
1449 {
1450 if (sh.flag.update == S_FALSE)
1451 {
1452 sh_error_handle((-1), FIL__, __LINE__, 0, MSG_FI_DBEX,
1453 file_path('D', 'W'));
1454 }
1455 }
1456 }
1457
1458
1459 if (sh.flag.update == S_FALSE)
1460 {
1461 if (pushdata_stdout == S_FALSE && pushdata_fd == -1)
1462 {
1463 if ( SL_ISERROR(pushdata_fd = sl_open_write(file_path('D', 'W'), SL_YESPRIV)))
1464 {
1465 SH_FREE(fullpath);
1466 SH_FREE(linkpath);
1467 sh_error_handle((-1), FIL__, __LINE__, pushdata_fd, MSG_E_ACCESS,
1468 geteuid(), file_path('D', 'W'));
1469 SL_RET0(_("sh_hash_pushdata"));
1470 }
1471 if ( SL_ISERROR(status = sl_forward(pushdata_fd)))
1472 {
1473 SH_FREE(fullpath);
1474 SH_FREE(linkpath);
1475 sh_error_handle((-1), FIL__, __LINE__, status, MSG_E_SUBGPATH,
1476 _("Fast forward failed"), _("sh_hash_pushdata"),
1477 file_path('D', 'W'));
1478 SL_RET0(_("sh_hash_pushdata"));
1479 }
1480 }
1481 }
1482 else /* update == TRUE */
1483 {
1484 if (pushdata_isfirst == 1)
1485 {
1486 TPT((0, FIL__, __LINE__, _("msg=<Update.>\n")))
1487 if ( SL_ISERROR(pushdata_fd = sl_open_rdwr(file_path('D', 'W'), SL_YESPRIV))){
1488 SH_FREE(fullpath);
1489 SH_FREE(linkpath);
1490 sh_error_handle((-1), FIL__, __LINE__, pushdata_fd, MSG_E_ACCESS,
1491 geteuid(), file_path('D', 'W'));
1492 SL_RET0(_("sh_hash_pushdata"));
1493 }
1494 line = SH_ALLOC(MAX_PATH_STORE+1);
1495 if (SL_ISERROR(sh_hash_setdataent_old (pushdata_fd, line,
1496 MAX_PATH_STORE,
1497 file_path('D', 'W'))))
1498 {
1499 SH_FREE(fullpath);
1500 SH_FREE(linkpath);
1501 SH_FREE(line);
1502 SL_RET0(_("sh_hash_pushdata"));
1503 }
1504 SH_FREE(line);
1505 }
1506 }
1507
1508 if (buf != NULL && buf->fullpath != NULL) {
1509
1510 old_len = sl_strlen(buf->fullpath);
1511#if defined(SH_STEALTH)
1512 sh_do_encode(buf->fullpath, old_len);
1513#endif
1514 tmp = quote_string(buf->fullpath);
1515 tmp_len = sl_strlen(tmp);
1516#if defined(SH_STEALTH)
1517 sh_do_decode(buf->fullpath, old_len);
1518#endif
1519
1520 if (tmp && tmp_len <= MAX_PATH_STORE)
1521 {
1522 sl_strlcpy(fullpath, buf->fullpath, MAX_PATH_STORE+1);
1523 /*
1524 if (sl_strlen(buf->fullpath) < (MAX_PATH_STORE-3))
1525 {
1526 fullpath[MAX_PATH_STORE-2] = '\0';
1527 fullpath[MAX_PATH_STORE-1] = '\n';
1528 }
1529 */
1530 }
1531 else
1532 {
1533 sl_strlcpy(fullpath,
1534 sh_tiger_hash (buf->fullpath,
1535 TIGER_DATA, old_len),
1536 KEY_LEN+1);
1537 }
1538 if (tmp) SH_FREE(tmp);
1539 }
1540
1541#if defined(SH_STEALTH)
1542 sh_do_encode(fullpath, sl_strlen(fullpath));
1543#endif
1544
1545 tmp = quote_string(fullpath);
1546 if (tmp) {
1547 sl_strlcpy(fullpath, tmp, MAX_PATH_STORE+1);
1548 SH_FREE(tmp);
1549 }
1550
1551 if (buf != NULL && buf->c_mode[0] == 'l' && buf->linkpath != NULL)
1552 {
1553
1554 old_len = sl_strlen(buf->linkpath);
1555#if defined(SH_STEALTH)
1556 sh_do_encode(buf->linkpath, old_len);
1557#endif
1558 tmp = quote_string(buf->linkpath);
1559 tmp_len = sl_strlen(tmp);
1560#if defined(SH_STEALTH)
1561 sh_do_decode(buf->linkpath, old_len);
1562#endif
1563
1564 if (tmp && tmp_len <= MAX_PATH_STORE)
1565 {
1566 sl_strlcpy(linkpath, buf->linkpath, MAX_PATH_STORE+1);
1567 }
1568 else
1569 {
1570 sl_strlcpy(linkpath,
1571 sh_tiger_hash (buf->linkpath,
1572 TIGER_DATA, old_len),
1573 KEY_LEN+1);
1574 }
1575 if (tmp) SH_FREE(tmp);
1576
1577#if defined(SH_STEALTH)
1578 sh_do_encode(linkpath, sl_strlen(linkpath));
1579#endif
1580 tmp = quote_string(linkpath);
1581 if (tmp)
1582 {
1583 sl_strlcpy(linkpath, tmp, MAX_PATH_STORE+1);
1584 SH_FREE(tmp);
1585 }
1586 }
1587
1588 if (buf != NULL && buf->attr_string != NULL)
1589 {
1590 old_len = sl_strlen(buf->attr_string);
1591#if defined(SH_STEALTH)
1592 sh_do_encode(buf->attr_string, old_len);
1593#endif
1594 tmp = quote_string(buf->attr_string);
1595 if (tmp)
1596 {
1597 attr_string = tmp;
1598 tmp = NULL;
1599 }
1600#if defined(SH_STEALTH)
1601 sh_do_decode(buf->attr_string, old_len);
1602#endif
1603 }
1604
1605
1606 if (buf != NULL) {
1607 p.mark = REC_MAGIC;
1608 if (attr_string)
1609 p.mark |= REC_FLAGS_ATTR;
1610 sl_strlcpy(p.c_mode, buf->c_mode, 11);
1611 sl_strlcpy(p.c_group, buf->c_group, GROUP_MAX+1);
1612 sl_strlcpy(p.c_owner, buf->c_owner, USER_MAX+1);
1613 if (fileHash) {
1614 sl_strlcpy(p.checksum, fileHash, KEY_LEN+1);
1615 }
1616#if defined(__linux__) || defined(HAVE_STAT_FLAGS)
1617 sl_strlcpy(p.c_attributes, buf->c_attributes, 13);
1618#else
1619 for (i = 0; i < 12; ++i) p.c_attributes[i] = '-';
1620 p.c_attributes[12] = '\0';
1621#endif
1622
1623#if defined(SH_STEALTH)
1624 sh_do_encode(p.c_mode, sl_strlen(p.c_mode));
1625 sh_do_encode(p.c_owner, sl_strlen(p.c_owner));
1626 sh_do_encode(p.c_group, sl_strlen(p.c_group));
1627 sh_do_encode(p.checksum, sl_strlen(p.checksum));
1628
1629 sh_do_encode(p.c_attributes, sl_strlen(p.c_attributes));
1630#endif
1631
1632#if defined(__linux__) || defined(HAVE_STAT_FLAGS)
1633 p.attributes = (UINT32) buf->attributes;
1634#else
1635 p.attributes = 0;
1636#endif
1637 p.linkmode = (UINT32) buf->linkmode;
1638 p.hardlinks = (UINT32) buf->hardlinks;
1639 p.dev = (UINT64) buf->dev;
1640 p.rdev = (UINT64) buf->rdev;
1641 p.mode = (UINT32) buf->mode;
1642 p.ino = (UINT32) buf->ino;
1643 p.size = (UINT64) buf->size;
1644 p.mtime = (UINT64) buf->mtime;
1645 p.atime = (UINT64) buf->atime;
1646 p.ctime = (UINT64) buf->ctime;
1647 p.owner = (UINT32) buf->owner;
1648 p.group = (UINT32) buf->group;
1649
1650 swap_32(&(p.mode));
1651 swap_32(&(p.linkmode));
1652 swap_64(&(p.dev));
1653 swap_64(&(p.rdev));
1654 swap_32(&(p.hardlinks));
1655 swap_32(&(p.ino));
1656 swap_64(&(p.size));
1657 swap_64(&(p.atime));
1658 swap_64(&(p.mtime));
1659 swap_64(&(p.ctime));
1660 swap_32(&(p.owner));
1661 swap_32(&(p.group));
1662 swap_32(&(p.attributes));
1663
1664#ifdef OLD_BUG
1665 swap_short(&(p.mark));
1666#else
1667 p.mark = *(swap_short(&(p.mark)));
1668#endif
1669 }
1670
1671 /* write the start marker
1672 */
1673 if (pushdata_isfirst == 1)
1674 {
1675 if (sh.flag.update == S_FALSE)
1676 {
1677 if (sh_db_version_string != NULL)
1678 {
1679 if (pushdata_stdout == S_FALSE)
1680 {
1681 sl_write (pushdata_fd, _("\n#Host "), 7);
1682 sl_write (pushdata_fd, sh.host.name,
1683 sl_strlen(sh.host.name));
1684 sl_write (pushdata_fd, _(" Version "), 9);
1685 sl_write (pushdata_fd, sh_db_version_string,
1686 sl_strlen(sh_db_version_string));
1687 sl_write (pushdata_fd, _(" Date "), 6);
1688 timep = sh_unix_time(0);
1689 sl_strlcpy(timestring, timep, sizeof(timestring));
1690 sl_write (pushdata_fd, timestring, sl_strlen(timestring));
1691 sl_write (pushdata_fd, "\n", 1);
1692 } else {
1693 printf (_("\n#Host "));
1694 printf ("%s", sh.host.name);
1695 printf (_(" Version "));
1696 printf ("%s", sh_db_version_string);
1697 printf (_(" Date "));
1698 timep = sh_unix_time(0);
1699 sl_strlcpy(timestring, timep, sizeof(timestring));
1700 printf ("%s\n", timestring);
1701 }
1702 }
1703
1704 if (pushdata_stdout == S_FALSE)
1705 {
1706#if defined(SH_STEALTH)
1707 sl_write (pushdata_fd, "\n", 1);
1708 sl_write_line (pushdata_fd, N_("[SOF]"), 5);
1709#else
1710 sl_write_line (pushdata_fd, _("\n[SOF]"), 6);
1711#endif
1712 }
1713 else
1714 {
1715#if defined(SH_STEALTH)
1716 printf ("\n%s\n", N_("[SOF]"));
1717#else
1718 printf ("%s\n", _("\n[SOF]"));
1719#endif
1720 }
1721 }
1722 pushdata_isfirst = 0;
1723 }
1724
1725 if (pushdata_stdout == S_FALSE)
1726 {
1727 sl_write (pushdata_fd, &p, sizeof(sh_filestore_t));
1728 sl_write_line_fast (pushdata_fd, fullpath, sl_strlen(fullpath));
1729 sl_write_line_fast (pushdata_fd, linkpath, sl_strlen(linkpath));
1730 if (attr_string)
1731 sl_write_line_fast (pushdata_fd, attr_string, sl_strlen(attr_string));
1732 } else {
1733 fwrite (&p, sizeof(sh_filestore_t), 1, stdout);
1734 printf ("%s\n", fullpath);
1735 printf ("%s\n", linkpath);
1736 if (attr_string)
1737 printf ("%s\n", attr_string);
1738 }
1739
1740 ++p_count;
1741
1742 if ((sh.flag.update != S_TRUE) && (pushdata_stdout == S_FALSE))
1743 {
1744 if (sh.flag.checkSum != SH_CHECK_INIT || (buf == NULL && fileHash == NULL))
1745 {
1746 sl_close (pushdata_fd);
1747 pushdata_fd = -1;
1748 }
1749 }
1750
1751 SH_FREE(fullpath);
1752 SH_FREE(linkpath);
1753 if (attr_string)
1754 SH_FREE(attr_string);
1755
1756 SL_RET0(_("sh_hash_pushdata"));
1757}
1758
1759int sh_hash_writeout()
1760{
1761 sh_file_t * p;
1762 int i;
1763 file_type * f;
1764 char fileHash[KEY_LEN + 1];
1765
1766 SL_ENTER(_("sh_hash_writeout"));
1767
1768 if (S_TRUE == file_is_remote())
1769 {
1770 sh_error_handle((-1), FIL__, __LINE__, S_FALSE, MSG_E_SUBGEN,
1771 _("Baseline database is remote"), _("sh_hash_writeout"));
1772 SL_RETURN (1, _("sh_hash_writeout"));
1773 }
1774
1775 if (!SL_ISERROR(pushdata_fd))
1776 {
1777 sl_close(pushdata_fd);
1778 pushdata_fd = -1;
1779 }
1780 pushdata_isfirst = 1;
1781
1782 for (i = 0; i < TABSIZE; ++i)
1783 {
1784 for (p = tab[i]; p; p = p->next)
1785 {
1786 f = sh_hash_create_ft (p, fileHash);
1787 sh_hash_pushdata (f, fileHash);
1788 if (f->attr_string)
1789 SH_FREE(f->attr_string);
1790 SH_FREE(f);
1791 }
1792 }
1793
1794 if (!SL_ISERROR(pushdata_fd))
1795 {
1796 sl_close(pushdata_fd);
1797 pushdata_fd = -1;
1798 }
1799 pushdata_isfirst = 1;
1800
1801 SL_RETURN (0, _("sh_hash_writeout"));
1802}
1803
1804
1805/*********************************************************************
1806 *
1807 * Check whether a file is present in the database.
1808 *
1809 *********************************************************************/
1810static sh_file_t * sh_hash_have_it_int (char * newname)
1811{
1812 sh_file_t * p;
1813
1814 SL_ENTER(_("sh_hash_have_it"));
1815
1816 if (newname == NULL)
1817 SL_RETURN( (NULL), _("sh_hash_have_it"));
1818
1819 if (IsInit != 1)
1820 sh_hash_init();
1821 if (sl_strlen(newname) <= MAX_PATH_STORE)
1822 p = hashsearch(newname);
1823 else
1824 p = hashsearch ( sh_tiger_hash(newname, TIGER_DATA, sl_strlen(newname)) );
1825 if (p == NULL)
1826 SL_RETURN( (NULL), _("sh_hash_have_it"));
1827 /*
1828 if (p->allignore == S_FALSE &&
1829 (p->modi_mask & MODI_CHK) != 0 &&
1830 (p->modi_mask & MODI_MOD) != 0)
1831 SL_RETURN( (1), _("sh_hash_have_it"));
1832 */
1833 SL_RETURN( (p), _("sh_hash_have_it"));
1834}
1835
1836int sh_hash_have_it (char * newname)
1837{
1838 sh_file_t * p = sh_hash_have_it_int (newname);
1839
1840 if (!p) return (-1);
1841 if ((!SH_FFLAG_ALLIGNORE_SET(p->fflags)) &&
1842 (p->modi_mask & MODI_CHK) != 0 &&
1843 (p->modi_mask & MODI_MOD) != 0)
1844 return 1;
1845 return 0;
1846}
1847
1848int sh_hash_get_it (char * newname, file_type * tmpFile)
1849{
1850 sh_file_t * p = sh_hash_have_it_int (newname);
1851 if (!p)
1852 return (-1);
1853 sl_strlcpy(tmpFile->fullpath, p->fullpath, PATH_MAX);
1854 sl_strlcpy(tmpFile->linkpath, p->linkpath, PATH_MAX);
1855 tmpFile->size = p->theFile.size;
1856 tmpFile->mtime = p->theFile.mtime;
1857 tmpFile->ctime = p->theFile.ctime;
1858
1859 tmpFile->attr_string = NULL;
1860 return 0;
1861}
1862
1863
1864/*****************************************************************
1865 *
1866 * Set a file's status to 'visited'. This is required for
1867 * files that should be ignored, and may be present in the
1868 * database, but not on disk.
1869 *
1870 *****************************************************************/
1871static int sh_hash_set_visited_int (char * newname, int flag)
1872{
1873 sh_file_t * p;
1874
1875 SL_ENTER(_("sh_hash_set_visited_int"));
1876
1877 if (newname == NULL)
1878 SL_RETURN((-1), _("sh_hash_set_visited_int"));
1879 if (IsInit != 1)
1880 sh_hash_init();
1881
1882 if (sl_strlen(newname) <= MAX_PATH_STORE)
1883 p = hashsearch(newname);
1884 else
1885 p = hashsearch (sh_tiger_hash(newname, TIGER_DATA, sl_strlen(newname)));
1886
1887 if (p == NULL)
1888 SL_RETURN((-1), _("sh_hash_set_visited_int"));
1889
1890 if (flag == SH_FFLAG_CHECKED)
1891 {
1892 CLEAR_SH_FFLAG_REPORTED(p->fflags);
1893 CLEAR_SH_FFLAG_VISITED(p->fflags);
1894 SET_SH_FFLAG_CHECKED(p->fflags);
1895 }
1896 else
1897 {
1898 SET_SH_FFLAG_VISITED(p->fflags);
1899 CLEAR_SH_FFLAG_CHECKED(p->fflags);
1900 if (flag == SH_FFLAG_REPORTED)
1901 SET_SH_FFLAG_REPORTED(p->fflags);
1902 else
1903 CLEAR_SH_FFLAG_REPORTED(p->fflags);
1904 }
1905 SL_RETURN((0), _("sh_hash_set_visited_int"));
1906}
1907
1908
1909/* cause the record to be deleted without a 'missing' message
1910 */
1911int sh_hash_set_missing (char * newname)
1912{
1913 int i;
1914 SL_ENTER(_("sh_hash_set_visited"));
1915 i = sh_hash_set_visited_int(newname, SH_FFLAG_CHECKED);
1916 SL_RETURN(i, _("sh_hash_set_visited"));
1917}
1918
1919/* mark the file as visited and reported
1920 */
1921int sh_hash_set_visited (char * newname)
1922{
1923 int i;
1924 SL_ENTER(_("sh_hash_set_visited"));
1925 i = sh_hash_set_visited_int(newname, SH_FFLAG_REPORTED);
1926 SL_RETURN(i, _("sh_hash_set_visited"));
1927}
1928
1929/* mark the file as visited and NOT reported
1930 * used to avoid deletion of file from internal database
1931 */
1932int sh_hash_set_visited_true (char * newname)
1933{
1934 int i;
1935 SL_ENTER(_("sh_hash_set_visited_true"));
1936 i = sh_hash_set_visited_int(newname, 0);
1937 SL_RETURN(i, _("sh_hash_set_visited_true"));
1938}
1939
1940
1941/******************************************************************
1942 *
1943 * Data entry for arbitrary data into database
1944 *
1945 ******************************************************************/
1946
1947void sh_hash_push2db (char * key, unsigned long val1,
1948 unsigned long val2, unsigned long val3,
1949 unsigned char * str, int size)
1950{
1951 file_type tmpFile;
1952 int i = 0;
1953 char * p;
1954
1955 tmpFile.attr_string = NULL;
1956
1957 sl_strlcpy(tmpFile.fullpath, key, PATH_MAX);
1958 tmpFile.size = val1;
1959 tmpFile.mtime = val2;
1960 tmpFile.ctime = val3;
1961
1962 tmpFile.atime = 0;
1963 tmpFile.mode = 0;
1964 tmpFile.owner = 0;
1965 tmpFile.group = 0;
1966 sl_strlcpy(tmpFile.c_owner, _("root"), 5);
1967 sl_strlcpy(tmpFile.c_group, _("root"), 5);
1968
1969 if ((str != NULL) && (size < (PATH_MAX/2)-1))
1970 {
1971 tmpFile.c_mode[0] = 'l';
1972 tmpFile.c_mode[1] = 'r'; tmpFile.c_mode[2] = 'w';
1973 tmpFile.c_mode[3] = 'x'; tmpFile.c_mode[4] = 'r';
1974 tmpFile.c_mode[5] = 'w'; tmpFile.c_mode[6] = 'x';
1975 tmpFile.c_mode[7] = 'r'; tmpFile.c_mode[8] = 'w';
1976 tmpFile.c_mode[9] = 'x'; tmpFile.c_mode[10] = '\0';
1977 for (i = 0; i < size; ++i)
1978 {
1979 p = sh_util_charhex (str[i]);
1980 tmpFile.linkpath[2*i] = p[0];
1981 tmpFile.linkpath[2*i+1] = p[1];
1982 tmpFile.linkpath[2*i+2] = '\0';
1983 }
1984 }
1985 else
1986 {
1987 for (i = 0; i < 10; ++i)
1988 tmpFile.c_mode[i] = '-';
1989 tmpFile.c_mode[10] = '\0';
1990 tmpFile.linkpath[0] = '-';
1991 tmpFile.linkpath[1] = '\0';
1992 }
1993
1994 if (sh.flag.checkSum == SH_CHECK_CHECK &&
1995 sh.flag.update == S_TRUE)
1996 sh_hash_pushdata_memory (&tmpFile, SH_KEY_NULL);
1997 else
1998 sh_hash_pushdata (&tmpFile, SH_KEY_NULL);
1999
2000 return;
2001}
2002
2003extern int sh_util_hextobinary (char * binary, char * hex, int bytes);
2004
2005char * sh_hash_db2pop (char * key, unsigned long * val1,
2006 unsigned long * val2, unsigned long * val3,
2007 int * size)
2008{
2009 file_type tmpFile;
2010 size_t len;
2011 char * p;
2012 int i;
2013
2014 *size = 0;
2015
2016 if (0 == sh_hash_get_it (key, &tmpFile))
2017 {
2018 *val1 = tmpFile.size;
2019 *val2 = tmpFile.mtime;
2020 *val3 = tmpFile.ctime;
2021
2022 if (tmpFile.linkpath[0] != '-')
2023 {
2024 len = strlen(tmpFile.linkpath);
2025
2026 p = SH_ALLOC((len/2)+1);
2027 i = sh_util_hextobinary (p, tmpFile.linkpath, len);
2028
2029 if (i == 0)
2030 {
2031 *size = (len/2);
2032 p[*size] = '\0';
2033 return p;
2034 }
2035 else
2036 {
2037 SH_FREE(p);
2038 *size = 0;
2039 return NULL;
2040 }
2041 }
2042 else
2043 {
2044 *size = 0;
2045 return NULL;
2046 }
2047 }
2048 else
2049 {
2050 *size = -1;
2051 *val1 = 0;
2052 *val2 = 0;
2053 *val3 = 0;
2054 return NULL;
2055 }
2056}
2057
2058
2059
2060
2061/******************************************************************
2062 *
2063 * Data entry in hash table
2064 *
2065 ******************************************************************/
2066sh_file_t * sh_hash_push_int (file_type * buf, char * fileHash)
2067{
2068 sh_file_t * fp;
2069 sh_filestore_t p;
2070
2071 size_t len;
2072 char * fullpath;
2073 char * linkpath;
2074 char * attr_string = NULL;
2075
2076 SL_ENTER(_("sh_hash_push_int"));
2077
2078 fp = SH_ALLOC(sizeof(sh_file_t));
2079
2080 p.mark = REC_MAGIC;
2081 if (buf->attr_string)
2082 p.mark |= REC_FLAGS_ATTR;
2083 sl_strlcpy(p.c_mode, buf->c_mode, 11);
2084 sl_strlcpy(p.c_group, buf->c_group, GROUP_MAX+1);
2085 sl_strlcpy(p.c_owner, buf->c_owner, USER_MAX+1);
2086 sl_strlcpy(p.checksum, fileHash, KEY_LEN+1);
2087#if defined(__linux__) || defined(HAVE_STAT_FLAGS)
2088 sl_strlcpy(p.c_attributes, buf->c_attributes, 13);
2089#endif
2090
2091#if defined(__linux__) || defined(HAVE_STAT_FLAGS)
2092 p.attributes = (UINT32) buf->attributes;
2093#endif
2094 p.linkmode = (UINT32) buf->linkmode;
2095 p.hardlinks = (UINT32) buf->hardlinks;
2096 p.dev = (UINT64) buf->dev;
2097 p.rdev = (UINT64) buf->rdev;
2098 p.mode = (UINT32) buf->mode;
2099 p.ino = (UINT32) buf->ino;
2100 p.size = (UINT64) buf->size;
2101 p.mtime = (UINT64) buf->mtime;
2102 p.atime = (UINT64) buf->atime;
2103 p.ctime = (UINT64) buf->ctime;
2104 p.owner = (UINT32) buf->owner;
2105 p.group = (UINT32) buf->group;
2106
2107 memcpy( &(*fp).theFile, &p, sizeof(sh_filestore_t) );
2108 fp->fflags = 0;
2109 fp->modi_mask = 0L;
2110
2111 if (buf->attr_string)
2112 attr_string = sh_util_strdup(buf->attr_string);
2113 fp->attr_string = attr_string;
2114
2115 len = sl_strlen(buf->fullpath);
2116 if (len <= MAX_PATH_STORE)
2117 {
2118 fullpath = SH_ALLOC(len+1);
2119 sl_strlcpy(fullpath, buf->fullpath, len+1);
2120 }
2121 else
2122 {
2123 fullpath = SH_ALLOC(KEY_LEN + 1);
2124 sl_strlcpy(fullpath,
2125 sh_tiger_hash (buf->fullpath, TIGER_DATA, len),
2126 KEY_LEN+1);
2127 }
2128 fp->fullpath = fullpath;
2129
2130 if (buf->c_mode[0] == 'l')
2131 {
2132 len = sl_strlen(buf->linkpath);
2133 if (len <= MAX_PATH_STORE)
2134 {
2135 linkpath = SH_ALLOC(len+1);
2136 sl_strlcpy(linkpath, buf->linkpath, len+1);
2137 }
2138 else
2139 {
2140 linkpath = SH_ALLOC(KEY_LEN + 1);
2141 sl_strlcpy(linkpath,
2142 sh_tiger_hash (buf->linkpath, TIGER_DATA, len),
2143 KEY_LEN+1);
2144 }
2145 fp->linkpath = linkpath;
2146 }
2147 else
2148 fp->linkpath = NULL;
2149
2150 SL_RETURN( fp, _("sh_hash_push_int"));
2151}
2152
2153#ifdef HAVE_INTTYPES_H
2154#include <inttypes.h>
2155#else
2156#ifdef HAVE_STDINT_H
2157#include <stdint.h>
2158#endif
2159#endif
2160
2161#ifndef PRIu64
2162#ifdef HAVE_LONG_32
2163#define PRIu64 "llu"
2164#else
2165#define PRIu64 "lu"
2166#endif
2167#endif
2168
2169char * sh_hash_size_format()
2170{
2171 static char form_rval[81];
2172
2173 SL_ENTER(_("sh_hash_size_format"));
2174
2175
2176#ifdef SH_USE_XML
2177 sl_snprintf(form_rval, 80, _("%s%s%s%s%s"),
2178 _("size_old=\"%"), PRIu64, _("\" size_new=\"%"), PRIu64, "\" ");
2179#else
2180 sl_snprintf(form_rval, 80, _("%s%s%s%s%s"),
2181 _("size_old=<%"), PRIu64, _(">, size_new=<%"), PRIu64, ">, ");
2182#endif
2183
2184 SL_RETURN( form_rval, _("sh_hash_size_format"));
2185}
2186
2187
2188#ifdef SH_USE_XML
2189static char * all_items (file_type * theFile, char * fileHash, int is_new)
2190{
2191 char timstr1c[32];
2192 char timstr1a[32];
2193 char timstr1m[32];
2194
2195 char * tmp_lnk;
2196 char * format;
2197
2198 char * tmp = SH_ALLOC(SH_BUFSIZE);
2199 char * msg = SH_ALLOC(SH_BUFSIZE);
2200
2201 tmp[0] = '\0';
2202 msg[0] = '\0';
2203
2204
2205#if defined(__linux__) || defined(HAVE_STAT_FLAGS)
2206 if (is_new)
2207 format = _("mode_new=\"%s\" attr_new=\"%s\" imode_new=\"%ld\" iattr_new=\"%ld\" ");
2208 else
2209 format = _("mode_old=\"%s\" attr_old=\"%s\" imode_old=\"%ld\" iattr_old=\"%ld\" ");
2210 sl_snprintf(tmp, SH_BUFSIZE, format,
2211 theFile->c_mode,
2212 theFile->c_attributes,
2213 (long) theFile->mode,
2214 (long) theFile->attributes
2215 );
2216#else
2217 if (is_new)
2218 format = _("mode_new=\"%s\" imode_new=\"%ld\" ");
2219 else
2220 format = _("mode_old=\"%s\" imode_old=\"%ld\" ");
2221
2222 sl_snprintf(tmp, SH_BUFSIZE, format,
2223 theFile->c_mode,
2224 (long) theFile->mode
2225 );
2226#endif
2227 sl_strlcat(msg, tmp, SH_BUFSIZE);
2228
2229 if (is_new)
2230 format = _("hardlinks_new=\"%lu\" ");
2231 else
2232 format = _("hardlinks_old=\"%lu\" ");
2233 sl_snprintf(tmp, SH_BUFSIZE, format,
2234 (unsigned long) theFile->hardlinks);
2235 sl_strlcat(msg, tmp, SH_BUFSIZE);
2236
2237
2238 if (is_new)
2239 format = _("idevice_new=\"%lu\" ");
2240 else
2241 format = _("idevice_old=\"%lu\" ");
2242 sl_snprintf(tmp, SH_BUFSIZE, format, (unsigned long) theFile->rdev);
2243 sl_strlcat(msg, tmp, SH_BUFSIZE);
2244
2245
2246 if (is_new)
2247 format = _("inode_new=\"%lu\" ");
2248 else
2249 format = _("inode_old=\"%lu\" ");
2250 sl_snprintf(tmp, SH_BUFSIZE, format, (unsigned long) theFile->ino);
2251 sl_strlcat(msg, tmp, SH_BUFSIZE);
2252
2253 /*
2254 * also report device for prelude
2255 */
2256#if defined(HAVE_LIBPRELUDE) && defined(HAVE_LIBPRELUDE_9)
2257 if (is_new)
2258 format = _("dev_new=\"%lu,%lu\" ");
2259 else
2260 format = _("dev_old=\"%lu,%lu\" ");
2261 sl_snprintf(tmp, SH_BUFSIZE, format,
2262 (unsigned long) major(theFile->dev),
2263 (unsigned long) minor(theFile->dev));
2264 sl_strlcat(msg, tmp, SH_BUFSIZE);
2265#endif
2266
2267
2268 if (is_new)
2269 format = _("owner_new=\"%s\" iowner_new=\"%ld\" ");
2270 else
2271 format = _("owner_old=\"%s\" iowner_old=\"%ld\" ");
2272 sl_snprintf(tmp, SH_BUFSIZE, format,
2273 theFile->c_owner, (long) theFile->owner);
2274 sl_strlcat(msg, tmp, SH_BUFSIZE);
2275
2276
2277 if (is_new)
2278 format = _("group_new=\"%s\" igroup_new=\"%ld\" ");
2279 else
2280 format = _("group_old=\"%s\" igroup_old=\"%ld\" ");
2281 sl_snprintf(tmp, SH_BUFSIZE, format,
2282 theFile->c_group, (long) theFile->group);
2283 sl_strlcat(msg, tmp, SH_BUFSIZE);
2284
2285
2286 if (is_new)
2287 sl_snprintf(tmp, SH_BUFSIZE, sh_hash_size_format(),
2288 (UINT64) 0, (UINT64) theFile->size);
2289 else
2290 sl_snprintf(tmp, SH_BUFSIZE, sh_hash_size_format(),
2291 (UINT64) theFile->size, (UINT64) 0);
2292 sl_strlcat(msg, tmp, SH_BUFSIZE);
2293
2294
2295 sl_strlcpy (timstr1c, sh_unix_gmttime (theFile->ctime), 32);
2296 if (is_new)
2297 sl_snprintf(tmp, SH_BUFSIZE, _("ctime_new=\"%s\" "), timstr1c);
2298 else
2299 sl_snprintf(tmp, SH_BUFSIZE, _("ctime_old=\"%s\" "), timstr1c);
2300 sl_strlcat(msg, tmp, SH_BUFSIZE);
2301
2302 sl_strlcpy (timstr1a, sh_unix_gmttime (theFile->atime), 32);
2303 if (is_new)
2304 sl_snprintf(tmp, SH_BUFSIZE, _("atime_new=\"%s\" "), timstr1a);
2305 else
2306 sl_snprintf(tmp, SH_BUFSIZE, _("atime_old=\"%s\" "), timstr1a);
2307 sl_strlcat(msg, tmp, SH_BUFSIZE);
2308
2309 sl_strlcpy (timstr1m, sh_unix_gmttime (theFile->mtime), 32);
2310 if (is_new)
2311 sl_snprintf(tmp, SH_BUFSIZE, _("mtime_new=\"%s\" "), timstr1m);
2312 else
2313 sl_snprintf(tmp, SH_BUFSIZE, _("mtime_old=\"%s\" "), timstr1m);
2314 sl_strlcat(msg, tmp, SH_BUFSIZE);
2315
2316 if (is_new)
2317 sl_snprintf(tmp, SH_BUFSIZE, _("chksum_new=\"%s\" "), fileHash);
2318 else
2319 sl_snprintf(tmp, SH_BUFSIZE, _("chksum_old=\"%s\" "), fileHash);
2320 sl_strlcat(msg, tmp, SH_BUFSIZE);
2321
2322 if (theFile->c_mode[0] == 'l')
2323 {
2324 tmp_lnk = sh_util_safe_name(theFile->linkpath);
2325 if (tmp_lnk)
2326 {
2327 if (is_new)
2328 sl_snprintf(tmp, SH_BUFSIZE, _("link_new=\"%s\" "), tmp_lnk);
2329 else
2330 sl_snprintf(tmp, SH_BUFSIZE, _("link_old=\"%s\" "), tmp_lnk);
2331 SH_FREE(tmp_lnk);
2332 sl_strlcat(msg, tmp, SH_BUFSIZE);
2333 }
2334 }
2335
2336 if (theFile->attr_string)
2337 {
2338 tmp_lnk = sh_util_safe_name(theFile->attr_string);
2339 if (tmp_lnk)
2340 {
2341 if (is_new)
2342 sl_snprintf(tmp, SH_BUFSIZE, _("acl_new=\"%s\" "), tmp_lnk);
2343 else
2344 sl_snprintf(tmp, SH_BUFSIZE, _("acl_old=\"%s\" "), tmp_lnk);
2345 SH_FREE(tmp_lnk);
2346 sl_strlcat(msg, tmp, SH_BUFSIZE);
2347 }
2348 }
2349
2350
2351 SH_FREE(tmp);
2352 return (msg);
2353}
2354#else
2355static char * all_items (file_type * theFile, char * fileHash, int is_new)
2356{
2357 char timstr1c[32];
2358 char timstr1a[32];
2359 char timstr1m[32];
2360
2361 char * tmp_lnk;
2362 char * format;
2363
2364 char * tmp = SH_ALLOC(SH_BUFSIZE);
2365 char * msg = SH_ALLOC(SH_BUFSIZE);
2366
2367 tmp[0] = '\0';
2368 msg[0] = '\0';
2369
2370
2371#if defined(__linux__) || defined(HAVE_STAT_FLAGS)
2372 if (is_new)
2373 format = _("mode_new=<%s>, attr_new=<%s>, imode_new=<%ld>, iattr_new=<%ld>, ");
2374 else
2375 format = _("mode_old=<%s>, attr_old=<%s>, imode_old=<%ld>, iattr_old=<%ld>, ");
2376 sl_snprintf(tmp, SH_BUFSIZE, format,
2377 theFile->c_mode,
2378 theFile->c_attributes,
2379 (long) theFile->mode,
2380 (long) theFile->attributes
2381 );
2382#else
2383 if (is_new)
2384 format = _("mode_new=<%s>, imode_new=<%ld>, ");
2385 else
2386 format = _("mode_old=<%s>, imode_old=<%ld>, ");
2387
2388 sl_snprintf(tmp, SH_BUFSIZE, format,
2389 theFile->c_mode,
2390 (long) theFile->mode
2391 );
2392#endif
2393 sl_strlcat(msg, tmp, SH_BUFSIZE);
2394
2395 if (is_new)
2396 format = _("hardlinks_new=<%lu>, ");
2397 else
2398 format = _("hardlinks_old=<%lu>, ");
2399 sl_snprintf(tmp, SH_BUFSIZE, format,
2400 (unsigned long) theFile->hardlinks);
2401 sl_strlcat(msg, tmp, SH_BUFSIZE);
2402
2403
2404 if (is_new)
2405 format = _("idevice_new=<%lu>, ");
2406 else
2407 format = _("idevice_old=<%lu>, ");
2408 sl_snprintf(tmp, SH_BUFSIZE, format, (unsigned long) theFile->rdev);
2409 sl_strlcat(msg, tmp, SH_BUFSIZE);
2410
2411
2412 if (is_new)
2413 format = _("inode_new=<%lu>, ");
2414 else
2415 format = _("inode_old=<%lu>, ");
2416 sl_snprintf(tmp, SH_BUFSIZE, format, (unsigned long) theFile->ino);
2417 sl_strlcat(msg, tmp, SH_BUFSIZE);
2418
2419
2420 /*
2421 * also report device for prelude
2422 */
2423#if defined(HAVE_LIBPRELUDE) && defined(HAVE_LIBPRELUDE_9)
2424 if (is_new)
2425 format = _("dev_new=<%lu,%lu>, ");
2426 else
2427 format = _("dev_old=<%lu,%lu>, ");
2428 sl_snprintf(tmp, SH_BUFSIZE, format,
2429 (unsigned long) major(theFile->dev),
2430 (unsigned long) minor(theFile->dev));
2431 sl_strlcat(msg, tmp, SH_BUFSIZE);
2432#endif
2433
2434 if (is_new)
2435 format = _("owner_new=<%s>, iowner_new=<%ld>, ");
2436 else
2437 format = _("owner_old=<%s>, iowner_old=<%ld>, ");
2438 sl_snprintf(tmp, SH_BUFSIZE, format,
2439 theFile->c_owner, (long) theFile->owner);
2440 sl_strlcat(msg, tmp, SH_BUFSIZE);
2441
2442
2443 if (is_new)
2444 format = _("group_new=<%s>, igroup_new=<%ld>, ");
2445 else
2446 format = _("group_old=<%s>, igroup_old=<%ld>, ");
2447 sl_snprintf(tmp, SH_BUFSIZE, format,
2448 theFile->c_group, (long) theFile->group);
2449 sl_strlcat(msg, tmp, SH_BUFSIZE);
2450
2451
2452 if (is_new)
2453 sl_snprintf(tmp, SH_BUFSIZE, sh_hash_size_format(),
2454 (UINT64) 0, (UINT64) theFile->size);
2455 else
2456 sl_snprintf(tmp, SH_BUFSIZE, sh_hash_size_format(),
2457 (UINT64) theFile->size, (UINT64) 0);
2458 sl_strlcat(msg, tmp, SH_BUFSIZE);
2459
2460
2461 sl_strlcpy (timstr1c, sh_unix_gmttime (theFile->ctime), 32);
2462 if (is_new)
2463 sl_snprintf(tmp, SH_BUFSIZE, _("ctime_new=<%s>, "), timstr1c);
2464 else
2465 sl_snprintf(tmp, SH_BUFSIZE, _("ctime_old=<%s>, "), timstr1c);
2466 sl_strlcat(msg, tmp, SH_BUFSIZE);
2467
2468 sl_strlcpy (timstr1a, sh_unix_gmttime (theFile->atime), 32);
2469 if (is_new)
2470 sl_snprintf(tmp, SH_BUFSIZE, _("atime_new=<%s>, "), timstr1a);
2471 else
2472 sl_snprintf(tmp, SH_BUFSIZE, _("atime_old=<%s>, "), timstr1a);
2473 sl_strlcat(msg, tmp, SH_BUFSIZE);
2474
2475 sl_strlcpy (timstr1m, sh_unix_gmttime (theFile->mtime), 32);
2476 if (is_new)
2477 sl_snprintf(tmp, SH_BUFSIZE, _("mtime_new=<%s>, "), timstr1m);
2478 else
2479 sl_snprintf(tmp, SH_BUFSIZE, _("mtime_old=<%s>, "), timstr1m);
2480 sl_strlcat(msg, tmp, SH_BUFSIZE);
2481
2482 if (is_new)
2483 sl_snprintf(tmp, SH_BUFSIZE, _("chksum_new=<%s>"), fileHash);
2484 else
2485 sl_snprintf(tmp, SH_BUFSIZE, _("chksum_old=<%s>"), fileHash);
2486 sl_strlcat(msg, tmp, SH_BUFSIZE);
2487
2488 if (theFile->c_mode[0] == 'l')
2489 {
2490 tmp_lnk = sh_util_safe_name(theFile->linkpath);
2491 if (tmp_lnk)
2492 {
2493 if (is_new)
2494 sl_snprintf(tmp, SH_BUFSIZE, _(", link_new=<%s> "), tmp_lnk);
2495 else
2496 sl_snprintf(tmp, SH_BUFSIZE, _(", link_old=<%s> "), tmp_lnk);
2497 SH_FREE(tmp_lnk);
2498 sl_strlcat(msg, tmp, SH_BUFSIZE);
2499 }
2500 }
2501
2502 if (theFile->attr_string)
2503 {
2504 tmp_lnk = sh_util_safe_name(theFile->attr_string);
2505 if (tmp_lnk)
2506 {
2507 if (is_new)
2508 sl_snprintf(tmp, SH_BUFSIZE, _(", acl_new=<%s> "), tmp_lnk);
2509 else
2510 sl_snprintf(tmp, SH_BUFSIZE, _(", acl_old=<%s> "), tmp_lnk);
2511 SH_FREE(tmp_lnk);
2512 sl_strlcat(msg, tmp, SH_BUFSIZE);
2513 }
2514 }
2515
2516 SH_FREE(tmp);
2517 return (msg);
2518}
2519#endif
2520
2521void sh_hash_pushdata_memory (file_type * theFile, char * fileHash)
2522{
2523 sh_file_t * p;
2524
2525 SL_ENTER(_("sh_hash_pushdata_memory"));
2526
2527 p = sh_hash_push_int(theFile, fileHash);
2528 if (p)
2529 {
2530 hashinsert (p);
2531 p->modi_mask = theFile->check_mask;
2532 }
2533
2534 SL_RET0(_("sh_hash_pushdata_memory"));
2535}
2536
2537
2538/*****************************************************************
2539 *
2540 * Compare a file with the database status.
2541 *
2542 *****************************************************************/
2543int sh_hash_compdata (int class, file_type * theFile, char * fileHash,
2544 char * policy_override, int severity_override)
2545{
2546 char * msg;
2547 sh_file_t * p;
2548 char * tmp;
2549 char * tmp_path;
2550 char * tmp_lnk;
2551 char * tmp_lnk_old;
2552
2553 char * str;
2554
2555 char timstr1c[32];
2556 char timstr2c[32];
2557 char timstr1a[32];
2558 char timstr2a[32];
2559 char timstr1m[32];
2560 char timstr2m[32];
2561 char linkHash[KEY_LEN+1];
2562 int maxcomp;
2563
2564 char change_code[16];
2565 int i;
2566
2567 unsigned long modi_mask = 0;
2568
2569 char log_policy[32];
2570 int log_severity;
2571
2572 SL_ENTER(_("sh_hash_compdata"));
2573
2574 if (IsInit != 1) sh_hash_init();
2575
2576 if (severity_override < 0)
2577 log_severity = ShDFLevel[class];
2578 else
2579 log_severity = severity_override;
2580
2581 if (policy_override != NULL)
2582 sl_strlcpy (log_policy, policy_override, 32);
2583
2584 /* -------- find the entry for the file ---------------- */
2585
2586 if (sl_strlen(theFile->fullpath) <= MAX_PATH_STORE)
2587 p = hashsearch(theFile->fullpath);
2588 else
2589 p = hashsearch( sh_tiger_hash(theFile->fullpath,
2590 TIGER_DATA,
2591 sl_strlen(theFile->fullpath))
2592 );
2593
2594
2595 /* --------- Not found in database. ------------
2596 */
2597
2598 if (p == NULL)
2599 {
2600 if (S_FALSE == sh_ignore_chk_new(theFile->fullpath))
2601 {
2602 tmp = sh_util_safe_name(theFile->fullpath);
2603
2604 str = all_items (theFile, fileHash, 1);
2605 sh_error_handle (log_severity, FIL__, __LINE__, 0,
2606 MSG_FI_ADD2,
2607 tmp, str);
2608 SH_FREE(str);
2609
2610 SH_FREE(tmp);
2611 }
2612
2613 if (p)
2614 {
2615 SET_SH_FFLAG_VISITED(p->fflags);
2616 CLEAR_SH_FFLAG_CHECKED(p->fflags);
2617 }
2618
2619 if (sh.flag.reportonce == S_TRUE)
2620 SET_SH_FFLAG_REPORTED(theFile->file_reported);
2621
2622 if (sh.flag.reportonce == S_TRUE && sh.flag.update == S_FALSE)
2623 {
2624 p = sh_hash_push_int(theFile, fileHash);
2625 hashinsert (p);
2626 if (p)
2627 p->modi_mask = theFile->check_mask;
2628 }
2629
2630 else if (S_TRUE == sh.flag.update)
2631 {
2632 if (S_TRUE == sh_util_ask_update (theFile->fullpath))
2633 {
2634 p = sh_hash_push_int(theFile, fileHash);
2635 hashinsert (p);
2636 if (p)
2637 p->modi_mask = theFile->check_mask;
2638 }
2639 else
2640 {
2641 SL_RETURN(1, _("sh_hash_compdata"));
2642 }
2643 }
2644
2645 SL_RETURN(0, _("sh_hash_compdata"));
2646 }
2647 else
2648 {
2649 p->modi_mask = theFile->check_mask;
2650 }
2651
2652 /* initialize change_code */
2653 for (i = 0; i < 15; ++i)
2654 change_code[i] = '-';
2655 change_code[15] = '\0';
2656
2657 TPT ((0, FIL__, __LINE__, _("file=<%s>, cs_old=<%s>, cs_new=<%s>\n"),
2658 theFile->fullpath, fileHash, p->theFile.checksum));
2659
2660 if ( (fileHash != NULL) && (p->theFile.checksum != NULL) &&
2661 (strncmp (fileHash, p->theFile.checksum, KEY_LEN) != 0) &&
2662 (theFile->check_mask & MODI_CHK) != 0)
2663 {
2664 if ((theFile->check_mask & MODI_SGROW) == 0)
2665 {
2666 modi_mask |= MODI_CHK;
2667 change_code[0] = 'C';
2668 TPT ((0, FIL__, __LINE__, _("mod=<checksum>")));
2669 }
2670 else
2671 {
2672 if (0 != strncmp (&fileHash[KEY_LEN + 1],
2673 p->theFile.checksum, KEY_LEN))
2674 {
2675 modi_mask |= MODI_CHK;
2676 change_code[0] = 'C';
2677 TPT ((0, FIL__, __LINE__, _("mod=<checksum>")));
2678 }
2679 else
2680 {
2681 p->theFile.size = theFile->size;
2682 sl_strlcpy(p->theFile.checksum, fileHash, KEY_LEN+1);
2683 }
2684 }
2685 }
2686
2687 if (p->theFile.c_mode[0] == 'l')
2688 {
2689 if (sl_strlen(theFile->linkpath) >= MAX_PATH_STORE)
2690 {
2691 sl_strlcpy(linkHash,
2692 sh_tiger_hash(theFile->linkpath,
2693 TIGER_DATA,
2694 sl_strlen(theFile->linkpath)),
2695 MAX_PATH_STORE+1);
2696 maxcomp = MAX_PATH_STORE;
2697 }
2698 else
2699 {
2700 sl_strlcpy(linkHash, theFile->linkpath, KEY_LEN + 1);
2701 maxcomp = KEY_LEN;
2702 }
2703
2704
2705 if ( sl_strncmp (linkHash, p->linkpath, maxcomp) != 0 &&
2706 (theFile->check_mask & MODI_LNK) != 0)
2707 {
2708 modi_mask |= MODI_LNK;
2709 change_code[1] = 'L';
2710 TPT ((0, FIL__, __LINE__, _("mod=<link>")));
2711 }
2712 }
2713
2714 if (p->theFile.c_mode[0] == 'c' || p->theFile.c_mode[0] == 'b')
2715 {
2716 if ( ( major(theFile->rdev) != major((dev_t)p->theFile.rdev) ||
2717 minor(theFile->rdev) != minor((dev_t)p->theFile.rdev) ) &&
2718 (theFile->check_mask & MODI_RDEV) != 0)
2719 {
2720 modi_mask |= MODI_RDEV;
2721 change_code[2] = 'D';
2722 TPT ((0, FIL__, __LINE__, _("mod=<rdev>")));
2723 }
2724 }
2725
2726 /* cast to UINT32 in case ino_t is not 32bit
2727 */
2728 if ( (UINT32) theFile->ino != (UINT32) p->theFile.ino &&
2729 (theFile->check_mask & MODI_INO) != 0)
2730 {
2731 modi_mask |= MODI_INO;
2732 change_code[3] = 'I';
2733 TPT ((0, FIL__, __LINE__, _("mod=<inode>")));
2734 }
2735
2736 if ( theFile->hardlinks != (nlink_t) p->theFile.hardlinks &&
2737 (theFile->check_mask & MODI_HLN) != 0)
2738 {
2739 modi_mask |= MODI_HLN;
2740 change_code[4] = 'H';
2741 TPT ((0, FIL__, __LINE__, _("mod=<hardlink>")));
2742 }
2743
2744
2745 if ( ( (theFile->mode != p->theFile.mode)
2746#if defined(USE_ACL) || defined(USE_XATTR)
2747 || ( (sh_unix_check_selinux|sh_unix_check_acl) &&
2748 (
2749 (theFile->attr_string == NULL && p->attr_string != NULL) ||
2750 (theFile->attr_string != NULL && p->attr_string == NULL) ||
2751 (theFile->attr_string != NULL && 0 != strcmp(theFile->attr_string, p->attr_string))
2752 )
2753 )
2754#endif
2755#if defined(__linux__) || defined(HAVE_STAT_FLAGS)
2756 || (theFile->attributes != p->theFile.attributes)
2757#endif
2758 )
2759 && (theFile->check_mask & MODI_MOD) != 0)
2760 {
2761 modi_mask |= MODI_MOD;
2762 change_code[5] = 'M';
2763 TPT ((0, FIL__, __LINE__, _("mod=<mode>")));
2764 /*
2765 * report link path if switch link/no link
2766 */
2767 if ((theFile->check_mask & MODI_LNK) != 0 &&
2768 (theFile->c_mode[0] != p->theFile.c_mode[0]) &&
2769 (theFile->c_mode[0] == 'l' || p->theFile.c_mode[0] == 'l'))
2770 {
2771 modi_mask |= MODI_LNK;
2772 change_code[1] = 'L';
2773 TPT ((0, FIL__, __LINE__, _("mod=<link>")));
2774 }
2775 }
2776
2777 if ( theFile->owner != (uid_t) p->theFile.owner &&
2778 (theFile->check_mask & MODI_USR) != 0)
2779 {
2780 modi_mask |= MODI_USR;
2781 change_code[6] = 'U';
2782 TPT ((0, FIL__, __LINE__, _("mod=<user>")));
2783 }
2784
2785 if ( theFile->group != (gid_t) p->theFile.group &&
2786 (theFile->check_mask & MODI_GRP) != 0)
2787 {
2788 modi_mask |= MODI_GRP;
2789 change_code[7] = 'G';
2790 TPT ((0, FIL__, __LINE__, _("mod=<group>")));
2791 }
2792
2793
2794 if ( theFile->mtime != (time_t) p->theFile.mtime &&
2795 (theFile->check_mask & MODI_MTM) != 0)
2796 {
2797 modi_mask |= MODI_MTM;
2798 change_code[8] = 'T';
2799 TPT ((0, FIL__, __LINE__, _("mod=<mtime>")));
2800 }
2801
2802 if ( (theFile->check_mask & MODI_ATM) != 0 &&
2803 theFile->atime != (time_t) p->theFile.atime)
2804 {
2805 modi_mask |= MODI_ATM;
2806 change_code[8] = 'T';
2807 TPT ((0, FIL__, __LINE__, _("mod=<atime>")));
2808 }
2809
2810
2811 /* Resetting the access time will set a new ctime. Thus, either we ignore
2812 * the access time or the ctime for NOIGNORE
2813 */
2814 if ( theFile->ctime != (time_t) p->theFile.ctime &&
2815 (theFile->check_mask & MODI_CTM) != 0)
2816 {
2817 modi_mask |= MODI_CTM;
2818 change_code[8] = 'T';
2819 TPT ((0, FIL__, __LINE__, _("mod=<ctime>")));
2820 }
2821
2822 if ( theFile->size != (off_t) p->theFile.size &&
2823 (theFile->check_mask & MODI_SIZ) != 0)
2824 {
2825 if ((theFile->check_mask & MODI_SGROW) == 0 ||
2826 theFile->size < (off_t) p->theFile.size)
2827 {
2828 modi_mask |= MODI_SIZ;
2829 change_code[9] = 'S';
2830 TPT ((0, FIL__, __LINE__, _("mod=<size>")));
2831 }
2832 }
2833 change_code[10] = '\0';
2834
2835 /* --- Report full details. ---
2836 */
2837 if (modi_mask != 0 && sh.flag.fulldetail == S_TRUE)
2838 {
2839 if ((theFile->check_mask & MODI_ATM) == 0)
2840 modi_mask = MASK_READONLY_;
2841 else
2842 modi_mask = MASK_NOIGNORE_;
2843 }
2844
2845 /* --- Report on modified files. ---
2846 */
2847 if (modi_mask != 0 && (!SH_FFLAG_REPORTED_SET(p->fflags)))
2848 {
2849 tmp = SH_ALLOC(SH_BUFSIZE);
2850 msg = SH_ALLOC(SH_BUFSIZE);
2851 msg[0] = '\0';
2852
2853 if ( ((modi_mask & MODI_MOD) != 0)
2854#if defined(HAVE_LIBPRELUDE) && defined(HAVE_LIBPRELUDE_9)
2855 || ((modi_mask & MODI_USR) != 0)
2856 || ((modi_mask & MODI_GRP) != 0)
2857#endif
2858 )
2859 {
2860#if defined(__linux__) || defined(HAVE_STAT_FLAGS)
2861 sl_snprintf(tmp, SH_BUFSIZE,
2862#ifdef SH_USE_XML
2863 _("mode_old=\"%s\" mode_new=\"%s\" attr_old=\"%s\" attr_new=\"%s\" imode_old=\"%ld\" imode_new=\"%ld\" iattr_old=\"%ld\" iattr_new=\"%ld\" "),
2864#else
2865 _("mode_old=<%s>, mode_new=<%s>, attr_old=<%s>, attr_new=<%s>, "),
2866#endif
2867 p->theFile.c_mode, theFile->c_mode,
2868 p->theFile.c_attributes, theFile->c_attributes
2869#ifdef SH_USE_XML
2870 , (long) p->theFile.mode, (long) theFile->mode,
2871 (long) p->theFile.attributes,
2872 (long) theFile->attributes
2873#endif
2874 );
2875#else
2876#ifdef SH_USE_XML
2877 sl_snprintf(tmp, SH_BUFSIZE,
2878 _("mode_old=\"%s\" mode_new=\"%s\" imode_old=\"%ld\" imode_new=\"%ld\" "),
2879 p->theFile.c_mode, theFile->c_mode,
2880 (long) p->theFile.mode, (long) theFile->mode);
2881#else
2882 sl_snprintf(tmp, SH_BUFSIZE, _("mode_old=<%s>, mode_new=<%s>, "),
2883 p->theFile.c_mode, theFile->c_mode);
2884#endif
2885#endif
2886 sl_strlcat(msg, tmp, SH_BUFSIZE);
2887
2888#if defined(USE_ACL) || defined(USE_XATTR)
2889 if (theFile->attr_string != NULL || p->attr_string != NULL)
2890 {
2891 sl_snprintf(tmp, SH_BUFSIZE,
2892#ifdef SH_USE_XML
2893 _("acl_old=\"%s\" acl_new=\"%s\" "),
2894#else
2895 _("acl_old=<%s>, acl_new=<%s>, "),
2896#endif
2897 (p->attr_string) ? p->attr_string : _("none"),
2898 (theFile->attr_string) ? theFile->attr_string : _("none"));
2899
2900 sl_strlcat(msg, tmp, SH_BUFSIZE);
2901 }
2902#endif
2903
2904#ifdef REPLACE_OLD
2905 if ((modi_mask & MODI_MOD) != 0)
2906 {
2907 /*
2908 * We postpone update if sh.flag.update == S_TRUE because
2909 * in interactive mode the user may not accept the change.
2910 */
2911 if (sh.flag.reportonce == S_TRUE && sh.flag.update == S_FALSE)
2912 {
2913 sl_strlcpy(p->theFile.c_mode, theFile->c_mode, 11);
2914 p->theFile.mode = theFile->mode;
2915#if defined(__linux__) || defined(HAVE_STAT_FLAGS)
2916 sl_strlcpy(p->theFile.c_attributes,theFile->c_attributes,16);
2917 p->theFile.attributes = theFile->attributes;
2918#endif
2919#if defined(USE_ACL) || defined(USE_XATTR)
2920 if (p->attr_string == NULL && theFile->attr_string != NULL)
2921 { p->attr_string = sh_util_strdup (theFile->attr_string); }
2922 else if (p->attr_string != NULL && theFile->attr_string == NULL)
2923 { SH_FREE(p->attr_string); p->attr_string = NULL; }
2924 else if (theFile->attr_string != NULL && p->attr_string != NULL)
2925 {
2926 if (0 != strcmp(theFile->attr_string, p->attr_string))
2927 {
2928 SH_FREE(p->attr_string);
2929 p->attr_string = sh_util_strdup (theFile->attr_string);
2930 }
2931 }
2932#endif
2933 }
2934 }
2935#endif
2936 }
2937
2938 if ((modi_mask & MODI_HLN) != 0)
2939 {
2940 sl_snprintf(tmp, SH_BUFSIZE,
2941#ifdef SH_USE_XML
2942 _("hardlinks_old=\"%lu\" hardlinks_new=\"%lu\" "),
2943#else
2944 _("hardlinks_old=<%lu>, hardlinks_new=<%lu>, "),
2945#endif
2946 (unsigned long) p->theFile.hardlinks,
2947 (unsigned long) theFile->hardlinks);
2948 sl_strlcat(msg, tmp, SH_BUFSIZE);
2949#ifdef REPLACE_OLD
2950 if (sh.flag.reportonce == S_TRUE && sh.flag.update == S_FALSE)
2951 p->theFile.hardlinks = theFile->hardlinks;
2952#endif
2953 }
2954
2955 if ((modi_mask & MODI_RDEV) != 0)
2956 {
2957 sl_snprintf(tmp, SH_BUFSIZE,
2958#ifdef SH_USE_XML
2959 _("device_old=\"%lu,%lu\" device_new=\"%lu,%lu\" idevice_old=\"%lu\" idevice_new=\"%lu\" "),
2960#else
2961 _("device_old=<%lu,%lu>, device_new=<%lu,%lu>, "),
2962#endif
2963 (unsigned long) major(p->theFile.rdev),
2964 (unsigned long) minor(p->theFile.rdev),
2965 (unsigned long) major(theFile->rdev),
2966 (unsigned long) minor(theFile->rdev)
2967#ifdef SH_USE_XML
2968 , (unsigned long) p->theFile.rdev,
2969 (unsigned long) theFile->rdev
2970#endif
2971 );
2972 sl_strlcat(msg, tmp, SH_BUFSIZE);
2973#ifdef REPLACE_OLD
2974 if (sh.flag.reportonce == S_TRUE && sh.flag.update == S_FALSE)
2975 p->theFile.rdev = theFile->rdev;
2976#endif
2977 }
2978
2979 if ((modi_mask & MODI_INO) != 0)
2980 {
2981 sl_snprintf(tmp, SH_BUFSIZE,
2982#ifdef SH_USE_XML
2983 _("inode_old=\"%lu\" inode_new=\"%lu\" "),
2984#else
2985 _("inode_old=<%lu>, inode_new=<%lu>, "),
2986#endif
2987 (unsigned long) p->theFile.ino,
2988 (unsigned long) theFile->ino);
2989 sl_strlcat(msg, tmp, SH_BUFSIZE);
2990#ifdef REPLACE_OLD
2991 if (sh.flag.reportonce == S_TRUE && sh.flag.update == S_FALSE)
2992 {
2993 p->theFile.ino = theFile->ino;
2994 p->theFile.dev = theFile->dev;
2995 }
2996#endif
2997 }
2998
2999
3000 /*
3001 * also report device for prelude
3002 */
3003#if defined(HAVE_LIBPRELUDE) && defined(HAVE_LIBPRELUDE_9)
3004 if ((modi_mask & MODI_INO) != 0)
3005 {
3006 sl_snprintf(tmp, SH_BUFSIZE,
3007#ifdef SH_USE_XML
3008 _("dev_old=\"%lu,%lu\" dev_new=\"%lu,%lu\" "),
3009#else
3010 _("dev_old=<%lu,%lu>, dev_new=<%lu,%lu>, "),
3011#endif
3012 (unsigned long) major(p->theFile.dev),
3013 (unsigned long) minor(p->theFile.dev),
3014 (unsigned long) major(theFile->dev),
3015 (unsigned long) minor(theFile->dev)
3016 );
3017 sl_strlcat(msg, tmp, SH_BUFSIZE);
3018#ifdef REPLACE_OLD
3019 if (sh.flag.reportonce == S_TRUE && sh.flag.update == S_FALSE)
3020 p->theFile.dev = theFile->dev;
3021#endif
3022 }
3023#endif
3024
3025 if ( ((modi_mask & MODI_USR) != 0)
3026#if defined(HAVE_LIBPRELUDE) && defined(HAVE_LIBPRELUDE_9)
3027 || ((modi_mask & MODI_MOD) != 0)
3028#endif
3029 )
3030 {
3031#ifdef SH_USE_XML
3032 sl_snprintf(tmp, SH_BUFSIZE,
3033 _("owner_old=\"%s\" owner_new=\"%s\" iowner_old=\"%ld\" iowner_new=\"%ld\" "),
3034#else
3035 sl_snprintf(tmp, SH_BUFSIZE,
3036 _("owner_old=<%s>, owner_new=<%s>, iowner_old=<%ld>, iowner_new=<%ld>, "),
3037#endif
3038 p->theFile.c_owner, theFile->c_owner,
3039 (long) p->theFile.owner, (long) theFile->owner
3040 );
3041 sl_strlcat(msg, tmp, SH_BUFSIZE);
3042#ifdef REPLACE_OLD
3043 if ((modi_mask & MODI_USR) != 0) {
3044 if (sh.flag.reportonce == S_TRUE && sh.flag.update == S_FALSE)
3045 {
3046 sl_strlcpy(p->theFile.c_owner, theFile->c_owner, USER_MAX+2);
3047 p->theFile.owner = theFile->owner;
3048 }
3049 }
3050#endif
3051 }
3052
3053 if ( ((modi_mask & MODI_GRP) != 0)
3054#if defined(HAVE_LIBPRELUDE) && defined(HAVE_LIBPRELUDE_9)
3055 || ((modi_mask & MODI_MOD) != 0)
3056#endif
3057 )
3058 {
3059#ifdef SH_USE_XML
3060 sl_snprintf(tmp, SH_BUFSIZE,
3061 _("group_old=\"%s\" group_new=\"%s\" igroup_old=\"%ld\" igroup_new=\"%ld\" "),
3062 p->theFile.c_group, theFile->c_group,
3063 (long) p->theFile.group, (long) theFile->group);
3064#else
3065 sl_snprintf(tmp, SH_BUFSIZE,
3066 _("group_old=<%s>, group_new=<%s>, igroup_old=<%ld>, igroup_new=<%ld>, "),
3067 p->theFile.c_group, theFile->c_group,
3068 (long) p->theFile.group, (long) theFile->group);
3069#endif
3070
3071 sl_strlcat(msg, tmp, SH_BUFSIZE);
3072#ifdef REPLACE_OLD
3073 if ((modi_mask & MODI_GRP) != 0) {
3074 if (sh.flag.reportonce == S_TRUE && sh.flag.update == S_FALSE)
3075 {
3076 sl_strlcpy(p->theFile.c_group, theFile->c_group, GROUP_MAX+2);
3077 p->theFile.group = theFile->group;
3078 }
3079 }
3080#endif
3081 }
3082
3083 if ((modi_mask & MODI_SIZ) != 0)
3084 {
3085 sl_snprintf(tmp, SH_BUFSIZE, sh_hash_size_format(),
3086 (UINT64) p->theFile.size,
3087 (UINT64) theFile->size);
3088 sl_strlcat(msg, tmp, SH_BUFSIZE);
3089#ifdef REPLACE_OLD
3090 if (sh.flag.reportonce == S_TRUE && sh.flag.update == S_FALSE)
3091 p->theFile.size = theFile->size;
3092#endif
3093 }
3094
3095 if ((modi_mask & MODI_CTM) != 0)
3096 {
3097 sl_strlcpy (timstr1c, sh_unix_gmttime (p->theFile.ctime), 32);
3098 sl_strlcpy (timstr2c, sh_unix_gmttime (theFile->ctime), 32);
3099#ifdef SH_USE_XML
3100 sl_snprintf(tmp, SH_BUFSIZE, _("ctime_old=\"%s\" ctime_new=\"%s\" "),
3101 timstr1c, timstr2c);
3102#else
3103 sl_snprintf(tmp, SH_BUFSIZE, _("ctime_old=<%s>, ctime_new=<%s>, "),
3104 timstr1c, timstr2c);
3105#endif
3106 sl_strlcat(msg, tmp, SH_BUFSIZE);
3107#ifdef REPLACE_OLD
3108 if (sh.flag.reportonce == S_TRUE && sh.flag.update == S_FALSE)
3109 p->theFile.ctime = theFile->ctime;
3110#endif
3111 }
3112
3113 if ((modi_mask & MODI_ATM) != 0)
3114 {
3115 sl_strlcpy (timstr1a, sh_unix_gmttime (p->theFile.atime), 32);
3116 sl_strlcpy (timstr2a, sh_unix_gmttime (theFile->atime), 32);
3117#ifdef SH_USE_XML
3118 sl_snprintf(tmp, SH_BUFSIZE, _("atime_old=\"%s\" atime_new=\"%s\" "),
3119 timstr1a, timstr2a);
3120#else
3121 sl_snprintf(tmp, SH_BUFSIZE, _("atime_old=<%s>, atime_new=<%s>, "),
3122 timstr1a, timstr2a);
3123#endif
3124 sl_strlcat(msg, tmp, SH_BUFSIZE);
3125#ifdef REPLACE_OLD
3126 if (sh.flag.reportonce == S_TRUE && sh.flag.update == S_FALSE)
3127 p->theFile.atime = theFile->atime;
3128#endif
3129 }
3130
3131 if ((modi_mask & MODI_MTM) != 0)
3132 {
3133 sl_strlcpy (timstr1m, sh_unix_gmttime (p->theFile.mtime), 32);
3134 sl_strlcpy (timstr2m, sh_unix_gmttime (theFile->mtime), 32);
3135#ifdef SH_USE_XML
3136 sl_snprintf(tmp, SH_BUFSIZE, _("mtime_old=\"%s\" mtime_new=\"%s\" "),
3137 timstr1m, timstr2m);
3138#else
3139 sl_snprintf(tmp, SH_BUFSIZE, _("mtime_old=<%s>, mtime_new=<%s>, "),
3140 timstr1m, timstr2m);
3141#endif
3142 sl_strlcat(msg, tmp, SH_BUFSIZE);
3143#ifdef REPLACE_OLD
3144 if (sh.flag.reportonce == S_TRUE && sh.flag.update == S_FALSE)
3145 p->theFile.mtime = theFile->mtime;
3146#endif
3147 }
3148
3149
3150 if ((modi_mask & MODI_CHK) != 0)
3151 {
3152 sl_snprintf(tmp, SH_BUFSIZE,
3153#ifdef SH_USE_XML
3154 _("chksum_old=\"%s\" chksum_new=\"%s\" "),
3155#else
3156 _("chksum_old=<%s>, chksum_new=<%s>, "),
3157#endif
3158 p->theFile.checksum, fileHash);
3159 sl_strlcat(msg, tmp, SH_BUFSIZE);
3160#ifdef REPLACE_OLD
3161 if (sh.flag.reportonce == S_TRUE && sh.flag.update == S_FALSE)
3162 {
3163 sl_strlcpy(p->theFile.checksum, fileHash, KEY_LEN+1);
3164 if ((theFile->check_mask & MODI_SGROW) != 0)
3165 p->theFile.size = theFile->size;
3166 }
3167#endif
3168 }
3169
3170
3171 if ((modi_mask & MODI_LNK) != 0 && theFile->c_mode[0] == 'l')
3172 {
3173 tmp_lnk = sh_util_safe_name(theFile->linkpath);
3174 tmp_lnk_old = sh_util_safe_name(p->linkpath);
3175#ifdef SH_USE_XML
3176 sl_snprintf(tmp, SH_BUFSIZE, _("link_old=\"%s\" link_new=\"%s\" "),
3177 tmp_lnk_old, tmp_lnk);
3178#else
3179 sl_snprintf(tmp, SH_BUFSIZE, _("link_old=<%s>, link_new=<%s>"),
3180 tmp_lnk_old, tmp_lnk);
3181#endif
3182 SH_FREE(tmp_lnk);
3183 SH_FREE(tmp_lnk_old);
3184 sl_strlcat(msg, tmp, SH_BUFSIZE);
3185#ifdef REPLACE_OLD
3186 if (sh.flag.reportonce == S_TRUE && sh.flag.update == S_FALSE)
3187 {
3188 if (p->linkpath != NULL)
3189 SH_FREE(p->linkpath);
3190 p->linkpath = sh_util_strdup(theFile->linkpath);
3191 }
3192#endif
3193 }
3194
3195
3196 tmp_path = sh_util_safe_name(theFile->fullpath);
3197 sh_error_handle(log_severity, FIL__, __LINE__,
3198 (long) modi_mask, MSG_FI_CHAN,
3199 (policy_override == NULL) ? _(policy[class]):log_policy,
3200 change_code, tmp_path, msg);
3201
3202 SH_FREE(tmp_path);
3203 SH_FREE(tmp);
3204 SH_FREE(msg);
3205
3206#ifndef REPLACE_OLD
3207 SET_SH_FFLAG_REPORTED(p->fflags);
3208#endif
3209
3210 if (S_TRUE == sh.flag.update)
3211 {
3212 if (S_FALSE == sh_util_ask_update(theFile->fullpath))
3213 {
3214 /* user does not want to update, thus we replace
3215 * with data from the baseline database
3216 */
3217 sl_strlcpy(theFile->c_mode, p->theFile.c_mode, 11);
3218 theFile->mode = p->theFile.mode;
3219#if defined(__linux__) || defined(HAVE_STAT_FLAGS)
3220 sl_strlcpy(theFile->c_attributes, p->theFile.c_attributes, 16);
3221 theFile->attributes = p->theFile.attributes;
3222#endif
3223#if defined(USE_ACL) || defined(USE_XATTR)
3224 if (theFile->attr_string == NULL && p->attr_string != NULL)
3225 { theFile->attr_string = sh_util_strdup (p->attr_string); }
3226 else if (theFile->attr_string != NULL && p->attr_string == NULL)
3227 { SH_FREE(theFile->attr_string); theFile->attr_string = NULL; }
3228 else if (theFile->attr_string != NULL && p->attr_string != NULL)
3229 {
3230 if (0 != strcmp(theFile->attr_string, p->attr_string))
3231 {
3232 SH_FREE(theFile->attr_string);
3233 theFile->attr_string = sh_util_strdup (p->attr_string);
3234 }
3235 }
3236#endif
3237
3238 if (theFile->c_mode[0] == 'l') /* c_mode is already copied */
3239 {
3240 sl_strlcpy(theFile->linkpath, p->linkpath, PATH_MAX);
3241 }
3242 else
3243 {
3244 theFile->linkpath[0] = '-';
3245 theFile->linkpath[1] = '\0';
3246 }
3247
3248 sl_strlcpy(fileHash, p->theFile.checksum, KEY_LEN+1);
3249
3250 theFile->mtime = p->theFile.mtime;
3251 theFile->ctime = p->theFile.ctime;
3252 theFile->atime = p->theFile.atime;
3253
3254 theFile->size = p->theFile.size;
3255
3256 sl_strlcpy(theFile->c_group, p->theFile.c_group, GROUP_MAX+2);
3257 theFile->group = p->theFile.group;
3258 sl_strlcpy(theFile->c_owner, p->theFile.c_owner, USER_MAX+2);
3259 theFile->owner = p->theFile.owner;
3260
3261 theFile->ino = p->theFile.ino;
3262 theFile->rdev = p->theFile.rdev;
3263 theFile->dev = p->theFile.dev;
3264 theFile->hardlinks = p->theFile.hardlinks;
3265
3266 SET_SH_FFLAG_VISITED(p->fflags);
3267 CLEAR_SH_FFLAG_CHECKED(p->fflags);
3268 SL_RETURN(1, _("sh_hash_compdata"));
3269 }
3270 else /* if (sh.flag.reportonce == S_TRUE) */
3271 {
3272 /* we replace the data in the in-memory copy of the
3273 * baseline database, because otherwise we would get
3274 * another warning if the suidcheck runs
3275 */
3276 sl_strlcpy(p->theFile.c_mode, theFile->c_mode, 11);
3277 p->theFile.mode = theFile->mode;
3278#if defined(__linux__) || defined(HAVE_STAT_FLAGS)
3279 sl_strlcpy(p->theFile.c_attributes, theFile->c_attributes, 16);
3280 p->theFile.attributes = theFile->attributes;
3281#endif
3282#if defined(USE_ACL) || defined(USE_XATTR)
3283 if (p->attr_string == NULL && theFile->attr_string != NULL)
3284 { p->attr_string = sh_util_strdup (theFile->attr_string); }
3285 else if (p->attr_string != NULL && theFile->attr_string == NULL)
3286 { SH_FREE(p->attr_string); p->attr_string = NULL; }
3287 else if (theFile->attr_string != NULL && p->attr_string != NULL)
3288 {
3289 if (0 != strcmp(theFile->attr_string, p->attr_string))
3290 {
3291 SH_FREE(p->attr_string);
3292 p->attr_string = sh_util_strdup (theFile->attr_string);
3293 }
3294 }
3295#endif
3296
3297 if (theFile->c_mode[0] == 'l')
3298 {
3299 if (p->linkpath != NULL)
3300 SH_FREE(p->linkpath);
3301 p->linkpath = sh_util_strdup(theFile->linkpath);
3302 }
3303 else
3304 {
3305 if (p->linkpath != NULL) {
3306 p->linkpath[0] = '-';
3307 p->linkpath[1] = '\0';
3308 } else {
3309 p->linkpath = SH_ALLOC(2);
3310 p->linkpath[0] = '-';
3311 p->linkpath[1] = '\0';
3312 }
3313 }
3314
3315 sl_strlcpy(p->theFile.checksum, fileHash, KEY_LEN+1);
3316
3317 p->theFile.mtime = theFile->mtime;
3318 p->theFile.ctime = theFile->ctime;
3319 p->theFile.atime = theFile->atime;
3320
3321 p->theFile.size = theFile->size;
3322
3323 sl_strlcpy(p->theFile.c_group, theFile->c_group, GROUP_MAX+2);
3324 p->theFile.group = theFile->group;
3325 sl_strlcpy(p->theFile.c_owner, theFile->c_owner, USER_MAX+2);
3326 p->theFile.owner = theFile->owner;
3327
3328 p->theFile.ino = theFile->ino;
3329 p->theFile.rdev = theFile->rdev;
3330 p->theFile.dev = theFile->dev;
3331 p->theFile.hardlinks = theFile->hardlinks;
3332 }
3333 }
3334 }
3335
3336 SET_SH_FFLAG_VISITED(p->fflags);
3337 CLEAR_SH_FFLAG_CHECKED(p->fflags);
3338
3339 SL_RETURN(0, _("sh_hash_compdata"));
3340}
3341
3342int hash_full_tree ()
3343{
3344 sh_file_t * p;
3345 int i;
3346
3347 SL_ENTER(_("sh_hash_compdata"));
3348
3349 if (IsInit != 1)
3350 SL_RETURN(0, _("sh_hash_compdata"));
3351
3352 for (i = 0; i < TABSIZE; ++i)
3353 {
3354 for (p = tab[i]; p; p = p->next)
3355 CLEAR_SH_FFLAG_ALLIGNORE(p->fflags);
3356 }
3357 SL_RETURN (0, _("sh_hash_compdata"));
3358}
3359
3360
3361int hash_remove_tree (char * s)
3362{
3363 sh_file_t * p;
3364 size_t len;
3365 unsigned int i;
3366
3367 SL_ENTER(_("hash_remove_tree"));
3368
3369 if (!s || *s == '\0')
3370 SL_RETURN ((-1), _("hash_remove_tree"));
3371
3372 len = sl_strlen(s);
3373
3374 if (IsInit != 1)
3375 sh_hash_init();
3376
3377 for (i = 0; i < TABSIZE; ++i)
3378 {
3379 for (p = tab[i]; p; p = p->next)
3380 {
3381 if (p->fullpath && 0 == strncmp(s, p->fullpath, len))
3382 {
3383 SET_SH_FFLAG_ALLIGNORE(p->fflags);
3384 }
3385 }
3386 }
3387 SL_RETURN ((0), _("hash_remove_tree"));
3388}
3389
3390#if TIME_WITH_SYS_TIME
3391#include <sys/time.h>
3392#include <time.h>
3393#else
3394#if HAVE_SYS_TIME_H
3395#include <sys/time.h>
3396#else
3397#include <time.h>
3398#endif
3399#endif
3400
3401static int ListFullDetail = S_FALSE;
3402static int ListWithDelimiter = S_FALSE;
3403
3404int set_full_detail (const char * c)
3405{
3406 ListFullDetail = S_TRUE;
3407 /* warning: unused parameter `c' */
3408 if (c)
3409 return 0;
3410 else
3411 return 0;
3412}
3413
3414int set_list_delimited (const char * c)
3415{
3416 ListFullDetail = S_TRUE;
3417 ListWithDelimiter = S_TRUE;
3418 /* warning: unused parameter `c' */
3419 if (c)
3420 return 0;
3421 else
3422 return 0;
3423}
3424
3425/* Always quote the string, except if it is empty. Qoute quotes by
3426 * doubling them.
3427 */
3428char * csv_escape(const char * str)
3429{
3430 const char * p = str;
3431 const char * q;
3432
3433 size_t size = 0;
3434 size_t flag_quote = 0;
3435 int flag_comma = 0;
3436 char * new;
3437 char * pnew;
3438
3439 if (p)
3440 {
3441
3442 while (*p)
3443 {
3444 if (*p == ',')
3445 flag_comma = 1;
3446 else if (*p == '"')
3447 ++flag_quote;
3448
3449 ++size; ++p;
3450 }
3451
3452 if (sl_ok_adds(size, flag_quote))
3453 size += flag_quote; /* double each quote */
3454 else
3455 return NULL;
3456
3457 if (sl_ok_adds(size, 3))
3458 size += 3; /* two quotes and terminating null */
3459 else
3460 return NULL;
3461
3462 new = SH_ALLOC(size);
3463
3464 if (flag_quote != 0)
3465 {
3466 new[0] = '"';
3467 pnew = &new[1];
3468 q = str;
3469 while (*q)
3470 {
3471 *pnew = *q;
3472 if (*pnew == '"')
3473 {
3474 ++pnew; *pnew = '"';
3475 }
3476 ++pnew; ++q;
3477 }
3478 *pnew = '"'; ++pnew;
3479 *pnew = '\0';
3480 }
3481 else
3482 {
3483 if (size > 3)
3484 {
3485 new[0] = '"';
3486 sl_strlcpy (&new[1], str, size-1);
3487 new[size-2] = '"';
3488 new[size-1] = '\0';
3489 }
3490 else
3491 {
3492 new[0] = '\0';
3493 }
3494 }
3495
3496 return new;
3497 }
3498 return NULL;
3499}
3500
3501
3502
3503void sh_hash_list_db_entry_full_detail (sh_file_t * p)
3504{
3505 char * tmp;
3506 char * esc;
3507 char str[81];
3508
3509 if (ListWithDelimiter == S_TRUE)
3510 {
3511 printf(_("%7ld, %7ld, %10s, %5d, %12s, %5d, %3d, %-8s, %5d, %-8s, %5d, "),
3512 (unsigned long) p->theFile.ino, (unsigned long) p->theFile.dev,
3513 p->theFile.c_mode, (int) p->theFile.mode,
3514 p->theFile.c_attributes, (int) p->theFile.attributes,
3515 (int) p->theFile.hardlinks,
3516 p->theFile.c_owner, (int) p->theFile.owner,
3517 p->theFile.c_group, (int) p->theFile.group);
3518 }
3519 else
3520 {
3521 printf(_("%7ld %7ld %10s %5d %12s %5d %3d %-8s %5d %-8s %5d "),
3522 (unsigned long) p->theFile.ino, (unsigned long) p->theFile.dev,
3523 p->theFile.c_mode, (int) p->theFile.mode,
3524 p->theFile.c_attributes, (int) p->theFile.attributes,
3525 (int) p->theFile.hardlinks,
3526 p->theFile.c_owner, (int) p->theFile.owner,
3527 p->theFile.c_group, (int) p->theFile.group);
3528 }
3529
3530 if ('c' == p->theFile.c_mode[0] || 'b' == p->theFile.c_mode[0])
3531 sl_snprintf(str, 80, "%"PRIu64, p->theFile.rdev);
3532 else
3533 sl_snprintf(str, 80, "%"PRIu64, p->theFile.size);
3534
3535 printf( _(" %8s"), str);
3536 if (ListWithDelimiter == S_TRUE)
3537 putchar(',');
3538
3539 printf( _(" %s"), sh_unix_gmttime (p->theFile.ctime));
3540 if (ListWithDelimiter == S_TRUE)
3541 putchar(',');
3542 printf( _(" %s"), sh_unix_gmttime (p->theFile.mtime));
3543 if (ListWithDelimiter == S_TRUE)
3544 putchar(',');
3545 printf( _(" %s"), sh_unix_gmttime (p->theFile.atime));
3546 if (ListWithDelimiter == S_TRUE)
3547 putchar(',');
3548 printf( _(" %s"), p->theFile.checksum);
3549 if (ListWithDelimiter == S_TRUE)
3550 putchar(',');
3551
3552 tmp = sh_util_safe_name(p->fullpath);
3553 if (ListWithDelimiter != S_TRUE)
3554 {
3555 printf( _(" %s"), tmp);
3556 }
3557 else
3558 {
3559 esc = csv_escape(tmp);
3560 printf( _(" %s,"), (esc != NULL) ? esc : _("(null)"));
3561 if (esc)
3562 SH_FREE(esc);
3563 }
3564 SH_FREE(tmp);
3565
3566 if ('l' == p->theFile.c_mode[0])
3567 {
3568 tmp = sh_util_safe_name(p->linkpath);
3569 if (ListWithDelimiter != S_TRUE)
3570 {
3571 printf(_(" -> %s"), tmp);
3572 }
3573 else
3574 {
3575 esc = csv_escape(tmp);
3576 printf( _(" %s,"), (esc != NULL) ? esc : _("(null)"));
3577 if (esc)
3578 SH_FREE(esc);
3579 }
3580 SH_FREE(tmp);
3581 }
3582
3583 if (p->attr_string)
3584 {
3585 tmp = sh_util_safe_name(p->attr_string);
3586 if (ListWithDelimiter != S_TRUE)
3587 {
3588 printf(_(" %s"), tmp);
3589 }
3590 else
3591 {
3592 esc = csv_escape(tmp);
3593 printf( _(" %s"), (esc != NULL) ? esc : _("(null)"));
3594 if (esc)
3595 SH_FREE(esc);
3596 }
3597 SH_FREE(tmp);
3598 }
3599 else
3600 {
3601 if (ListWithDelimiter == S_TRUE)
3602 printf(_(" no_attr"));
3603 }
3604 putchar('\n');
3605
3606 return;
3607}
3608
3609void sh_hash_list_db_entry (sh_file_t * p)
3610{
3611 char nowtime[128];
3612 char thetime[128];
3613 char * tmp;
3614 time_t now = time(NULL);
3615 time_t then = (time_t) p->theFile.mtime;
3616
3617 strftime(thetime, 127, _("%b %d %Y"), gmtime(&then));
3618 strftime(nowtime, 127, _("%b %d %Y"), gmtime(&now));
3619 if (0 == strncmp(&nowtime[7], &thetime[7], 4))
3620 strftime(thetime, 127, _("%b %d %H:%M"), gmtime(&then));
3621
3622 tmp = sh_util_safe_name(p->fullpath);
3623 if ('c' == p->theFile.c_mode[0] || 'b' == p->theFile.c_mode[0])
3624 printf(_("%10s %3d %-8s %-8s %3d,%4d %s %s"),
3625 p->theFile.c_mode, (int) p->theFile.hardlinks,
3626 p->theFile.c_owner, p->theFile.c_group,
3627 (int) major((dev_t)p->theFile.rdev),
3628 (int) minor((dev_t)p->theFile.rdev),
3629 thetime,
3630 tmp);
3631 else
3632 printf(_("%10s %3d %-8s %-8s %8ld %s %s"),
3633 p->theFile.c_mode, (int) p->theFile.hardlinks,
3634 p->theFile.c_owner, p->theFile.c_group, (long) p->theFile.size,
3635 thetime,
3636 tmp);
3637 SH_FREE(tmp);
3638
3639 if ('l' == p->theFile.c_mode[0])
3640 {
3641 tmp = sh_util_safe_name(p->linkpath);
3642 printf(_(" -> %s\n"), tmp);
3643 SH_FREE(tmp);
3644 }
3645 else
3646 printf("\n");
3647
3648 return;
3649}
3650
3651int sh_hash_list_db (const char * db_file)
3652{
3653 sh_file_t * p;
3654 SL_TICKET fd;
3655 char * line;
3656
3657 if (!db_file)
3658 {
3659 _exit(EXIT_FAILURE);
3660 return -1;
3661 }
3662 if (sl_is_suid())
3663 {
3664 fprintf(stderr, _("ERROR: insufficient privilege\n"));
3665 _exit (EXIT_FAILURE);
3666 return -1; /* for Mac OSX compiler */
3667 }
3668 if (0 == strcmp(db_file, _("default")))
3669 db_file = file_path('D', 'W');
3670 if (!db_file)
3671 {
3672 _exit(EXIT_FAILURE);
3673 return -1;
3674 }
3675
3676 line = SH_ALLOC(MAX_PATH_STORE+1);
3677
3678 if ( SL_ISERROR(fd = sl_open_read(db_file, SL_YESPRIV)))
3679 {
3680 fprintf(stderr, _("ERROR: can't open %s for read (errnum = %ld)\n"),
3681 db_file, fd);
3682 _exit(EXIT_FAILURE);
3683 return -1;
3684 }
3685
3686 /* fast forward to start of data
3687 */
3688 sh_hash_setdataent(fd, line, MAX_PATH_STORE, db_file);
3689
3690 while (1)
3691 {
3692 p = sh_hash_getdataent (fd, line, MAX_PATH_STORE);
3693 if ((p != NULL) && (p->fullpath[0] != 'K'))
3694 {
3695 if (ListFullDetail == S_FALSE)
3696 sh_hash_list_db_entry (p);
3697 else
3698 sh_hash_list_db_entry_full_detail (p);
3699 }
3700 else if (p == NULL)
3701 {
3702 break;
3703 }
3704 }
3705
3706 if (line != NULL)
3707 SH_FREE(line);
3708 sl_close (fd);
3709
3710 fflush(NULL);
3711
3712 _exit(EXIT_SUCCESS);
3713 return 0;
3714}
3715
3716/* if defined(SH_WITH_CLIENT) || defined(SH_STANDALONE) */
3717#endif
Note: See TracBrowser for help on using the repository browser.