source: branches/samhain-2_2-branch/src/sh_files.c@ 570

Last change on this file since 570 was 61, checked in by rainer, 18 years ago

Fix for MacOX X problems and Cygwin compile problem, resolves tickets #33, #34, #35.

File size: 53.4 KB
Line 
1/* SAMHAIN file system integrity testing */
2/* Copyright (C) 1999 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#include <stdio.h>
23#include <stdlib.h>
24#include <string.h>
25#include <limits.h>
26
27#include <errno.h>
28
29/* Must be before <utime.h> on FreeBSD
30 */
31#include <sys/types.h>
32#include <unistd.h>
33
34#include <utime.h>
35
36
37#ifdef HAVE_DIRENT_H
38#include <dirent.h>
39#define NAMLEN(dirent) sl_strlen((dirent)->d_name)
40#else
41#define dirent direct
42#define NAMLEN(dirent) (dirent)->d_namlen
43#ifdef HAVE_SYS_NDIR_H
44#include <sys/ndir.h>
45#endif
46#ifdef HAVE_SYS_DIR_H
47#include <sys/dir.h>
48#endif
49#ifdef HAVE_NDIR_H
50#include <ndir.h>
51#endif
52#endif
53
54#ifdef HAVE_GLOB_H
55#include <glob.h>
56#endif
57
58#include "samhain.h"
59
60#if (defined (SH_WITH_CLIENT) || defined (SH_STANDALONE))
61
62#include "sh_error.h"
63#include "sh_utils.h"
64#include "sh_unix.h"
65#include "sh_files.h"
66#include "sh_tiger.h"
67#include "sh_hash.h"
68#include "sh_ignore.h"
69#include "zAVLTree.h"
70
71#undef FIL__
72#define FIL__ _("sh_files.c")
73
74extern int flag_err_debug;
75extern int flag_err_info;
76
77int sh_files_reportonce(const char * c)
78{
79 int i;
80 SL_ENTER(_("sh_files_reportonce"));
81 i = sh_util_flagval(c, &(sh.flag.reportonce));
82
83 SL_RETURN(i, _("sh_files_reportonce"));
84}
85
86int sh_files_fulldetail(const char * c)
87{
88 int i;
89 SL_ENTER(_("sh_files_fulldetail"));
90 i = sh_util_flagval(c, &(sh.flag.fulldetail));
91
92 SL_RETURN((i), _("sh_files_fulldetail"));
93}
94
95
96typedef struct dir_struct {
97 long NumRegular;
98 long NumDirs;
99 long NumSymlinks;
100 long NumFifos;
101 long NumSockets;
102 long NumCDev;
103 long NumBDev;
104 long NumDoor;
105 long NumPort;
106 long NumAll;
107 long TotalBytes;
108 char DirPath[PATH_MAX];
109} dir_type;
110
111typedef struct dirstack_entry {
112 char * name;
113 int class;
114 unsigned long check_mask;
115 int rdepth;
116 short checked;
117 short childs_checked;
118 short reported;
119 /* struct dirstack_entry * next; */
120} dirstack_t;
121
122
123/* the destructor
124 */
125void free_dirstack (void * inptr)
126{
127 dirstack_t * here;
128
129 SL_ENTER(_("free_dirstack"));
130 if (inptr == NULL)
131 SL_RET0(_("free_dirstack"));
132 else
133 here = (dirstack_t *) inptr;
134
135 if (here->name != NULL)
136 SH_FREE(here->name);
137 SH_FREE(here);
138 SL_RET0(_("free_dirstack"));
139}
140
141/* Function to return the key for indexing
142 * the argument
143 */
144zAVLKey zdirstack_key (void const * arg)
145{
146 const dirstack_t * sa = (const dirstack_t *) arg;
147 return (zAVLKey) sa->name;
148}
149
150
151static zAVLTree * zdirListOne = NULL;
152static zAVLTree * zdirListTwo = NULL;
153static zAVLTree * zfileList = NULL;
154
155
156static int sh_files_fullpath (char * testdir, char * d_name,
157 char * statpath);
158static int sh_files_pushdir (int class, const char * str_s);
159static int sh_files_pushfile (int class, const char * str_s);
160static int sh_files_checkdir (int class, int rdepth, char * dirName,
161 char * relativeName);
162static ShFileType sh_files_filecheck (int class, char * dirName,
163 char * fileName, int * reported,
164 int rsrcflag);
165
166static long MaxRecursionLevel = 0;
167
168/* set default recursion level
169 */
170int sh_files_setrecursion (const char * flag_s)
171{
172 long flag = 0;
173 static int reject = 0;
174
175 SL_ENTER( _("sh_files_setrecursion"));
176
177 if (reject == 1)
178 SL_RETURN((-1), _("sh_files_setrecursion"));
179
180 if (sh.flag.opts == 1)
181 reject = 1;
182
183 if (flag_s != NULL)
184 flag = (int)(atof(flag_s));
185
186 if (flag >= 0 && flag <= 99)
187 MaxRecursionLevel = flag;
188 else
189 SL_RETURN((-1), _("sh_files_setrecursion"));
190
191 SL_RETURN((0), _("sh_files_setrecursion"));
192}
193
194
195unsigned long sh_files_chk ()
196{
197 zAVLCursor cursor;
198 ShFileType status;
199 unsigned long fcount = 0;
200
201 char * tmp = NULL;
202
203 dirstack_t * ptr;
204 char * dir;
205 char * file;
206 int tmp_reported;
207
208 SL_ENTER(_("sh_files_chk"));
209
210 for (ptr = (dirstack_t *) zAVLFirst(&cursor, zfileList); ptr;
211 ptr = (dirstack_t *) zAVLNext(&cursor))
212 {
213
214 if (sig_urgent > 0) {
215 SL_RETURN(fcount, _("sh_files_chk"));
216 }
217
218 if (ptr->checked == S_FALSE)
219 {
220 dir = sh_util_dirname (ptr->name);
221 file = sh_util_basename (ptr->name);
222#if defined(WITH_TPT)
223 tmp = sh_util_safe_name (ptr->name);
224#endif
225
226
227 if (flag_err_info == SL_TRUE)
228 {
229#if !defined(WITH_TPT)
230 tmp = sh_util_safe_name (ptr->name);
231#endif
232 sh_error_handle ((-1), FIL__, __LINE__, 0, MSG_FI_CHK, tmp);
233 }
234
235 BREAKEXIT(sh_files_filecheck);
236 tmp_reported = ptr->reported; /* fix aliasing warning */
237 status = sh_files_filecheck (ptr->class, dir, file,
238 &tmp_reported, 0);
239 ptr->reported = tmp_reported;
240
241 TPT(( 0, FIL__, __LINE__,
242 _("msg=<filecheck complete: %s> status=<%d> reported=<%d>\n"),
243 tmp, status, ptr->reported));
244
245 if (status == SH_FILE_UNKNOWN && ptr->reported == S_FALSE)
246 {
247 TPT(( 0, FIL__, __LINE__, _("msg=<file: %s> status=<%d>\n"),
248 tmp, status));
249
250 if ( sh.flag.checkSum == SH_CHECK_INIT ||
251 sh_hash_have_it (ptr->name) >= 0)
252 {
253 if (S_FALSE == sh_ignore_chk_del(ptr->name))
254 {
255 if (0 != hashreport_missing(ptr->name,
256 (ptr->class == SH_LEVEL_ALLIGNORE) ?
257 ShDFLevel[ptr->class] :
258 ShDFLevel[SH_ERR_T_FILE])) {
259 if (tmp == NULL)
260 tmp = sh_util_safe_name (ptr->name);
261 sh_error_handle ((ptr->class == SH_LEVEL_ALLIGNORE) ?
262 ShDFLevel[ptr->class] :
263 ShDFLevel[SH_ERR_T_FILE],
264 FIL__, __LINE__, 0, MSG_FI_MISS,
265 tmp);
266 }
267 }
268 }
269 else /* not there at init, and still missing */
270 {
271 if (tmp == NULL)
272 tmp = sh_util_safe_name (ptr->name);
273 sh_error_handle (SH_ERR_NOTICE,
274 FIL__, __LINE__, 0,
275 MSG_FI_FAIL,
276 tmp);
277 }
278#ifndef REPLACE_OLD
279 /* this will tell that we have seen the file, and thus prevent
280 * deletion from the database, resulting in an incomplete
281 * message when the file reappears
282 */
283 if (sh.flag.checkSum != SH_CHECK_INIT)
284 sh_hash_set_visited_true(ptr->name);
285#else
286 if (sh.flag.checkSum != SH_CHECK_INIT)
287 sh_hash_set_missing(ptr->name);
288#endif
289 if (sh.flag.reportonce == S_TRUE)
290 ptr->reported = S_TRUE;
291 }
292 else
293 {
294 /* exists (status >= 0), but was missing (reported == TRUE)
295 */
296 if (status != SH_FILE_UNKNOWN && ptr->reported == S_TRUE)
297 {
298 ptr->reported = S_FALSE;
299 }
300 /* Catchall
301 */
302 else if (status == SH_FILE_UNKNOWN)
303 {
304 /* Thu Mar 7 15:09:40 CET 2002 Make sure missing file
305 * is reported if ptr->reported == S_TRUE because the
306 * file has been added.
307 */
308 if (sh_hash_have_it (ptr->name) >= 0)
309 {
310 if (S_FALSE == sh_ignore_chk_del(ptr->name))
311 {
312 if (0 != hashreport_missing(ptr->name,
313 (ptr->class == SH_LEVEL_ALLIGNORE) ?
314 ShDFLevel[ptr->class] :
315 ShDFLevel[SH_ERR_T_FILE])) {
316 if (tmp == NULL)
317 tmp = sh_util_safe_name (ptr->name);
318 sh_error_handle ((ptr->class == SH_LEVEL_ALLIGNORE)?
319 ShDFLevel[ptr->class] :
320 ShDFLevel[SH_ERR_T_FILE],
321 FIL__, __LINE__, 0, MSG_FI_MISS,
322 tmp);
323 }
324 }
325#ifndef REPLACE_OLD
326 if (sh.flag.checkSum != SH_CHECK_INIT)
327 sh_hash_set_visited_true(ptr->name);
328#else
329 /* delete from database
330 */
331 if (sh.flag.checkSum != SH_CHECK_INIT)
332 sh_hash_set_missing(ptr->name);
333#endif
334 }
335 else
336 {
337 if (tmp == NULL)
338 tmp = sh_util_safe_name (ptr->name);
339 sh_error_handle (SH_ERR_INFO, FIL__, __LINE__, 0,
340 MSG_FI_FAIL,
341 tmp);
342 if (sh.flag.checkSum != SH_CHECK_INIT)
343 sh_hash_set_visited_true(ptr->name);
344 }
345 }
346 ++fcount;
347 }
348
349 if (tmp != NULL)
350 {
351 SH_FREE(tmp);
352 tmp = NULL;
353 }
354 SH_FREE(file);
355 SH_FREE(dir);
356
357 ptr->checked = S_TRUE;
358 }
359 }
360
361 SL_RETURN(fcount, _("sh_files_chk"));
362}
363
364int sh_files_delfilestack ()
365{
366 SL_ENTER(_("sh_files_delfilestack"));
367
368 zAVLFreeTree (zfileList, free_dirstack);
369 zfileList = NULL;
370
371 SL_RETURN(0, _("sh_files_delfilestack"));
372}
373
374int sh_files_setrec_int (zAVLTree * tree)
375{
376 dirstack_t * ptr;
377 zAVLCursor avlcursor;
378
379 SL_ENTER(_("sh_files_setrec"));
380 if (tree != NULL) {
381 for (ptr = (dirstack_t *) zAVLFirst(&avlcursor, tree); ptr;
382 ptr = (dirstack_t *) zAVLNext(&avlcursor))
383 {
384 if (ptr->rdepth < (-1) || ptr->rdepth > 99)
385 {
386 ptr->rdepth = MaxRecursionLevel;
387 }
388 if (ptr->rdepth == (-1) && sh.flag.checkSum != SH_CHECK_INIT)
389 hash_remove_tree (ptr->name);
390 }
391 }
392 SL_RETURN(0, _("sh_files_setrec"));
393}
394
395int sh_files_setrec ()
396{
397 sh_files_setrec_int(zdirListOne);
398 return sh_files_setrec_int(zdirListTwo);
399}
400
401zAVLTree * sh_files_deldirstack_int (zAVLTree * ptr)
402{
403 SL_ENTER(_("sh_files_deldirstack"));
404
405 zAVLFreeTree (ptr, free_dirstack);
406
407 SL_RETURN(NULL, _("sh_files_deldirstack"));
408}
409
410int sh_files_deldirstack ()
411{
412 zdirListOne = sh_files_deldirstack_int(zdirListOne);
413 zdirListTwo = sh_files_deldirstack_int(zdirListTwo);
414 return 0;
415}
416
417void sh_files_reset()
418{
419 dirstack_t * ptr;
420 zAVLCursor avlcursor;
421
422 SL_ENTER(_("sh_files_reset"));
423
424 for (ptr = (dirstack_t *) zAVLFirst(&avlcursor, zfileList); ptr;
425 ptr = (dirstack_t *) zAVLNext(&avlcursor))
426 ptr->checked = 0;
427
428 SL_RET0(_("sh_files_reset"));
429}
430
431void sh_dirs_reset()
432{
433 dirstack_t * ptr;
434 zAVLCursor avlcursor1;
435 zAVLCursor avlcursor2;
436
437 SL_ENTER(_("sh_dirs_reset"));
438
439 for (ptr = (dirstack_t *) zAVLFirst(&avlcursor1, zdirListOne); ptr;
440 ptr = (dirstack_t *) zAVLNext(&avlcursor1))
441 ptr->checked = 0;
442
443 for (ptr = (dirstack_t *) zAVLFirst(&avlcursor2, zdirListTwo); ptr;
444 ptr = (dirstack_t *) zAVLNext(&avlcursor2))
445 ptr->checked = 0;
446
447 SL_RET0(_("sh_dirs_reset"));
448}
449
450
451int sh_files_pushfile_prelink (const char * str_s)
452{
453 return (sh_files_pushfile (SH_LEVEL_PRELINK, str_s));
454}
455
456int sh_files_pushfile_user0 (const char * str_s)
457{
458 return (sh_files_pushfile (SH_LEVEL_USER0, str_s));
459}
460
461int sh_files_pushfile_user1 (const char * str_s)
462{
463 return (sh_files_pushfile (SH_LEVEL_USER1, str_s));
464}
465
466int sh_files_pushfile_user2 (const char * str_s)
467{
468 return (sh_files_pushfile (SH_LEVEL_USER2, str_s));
469}
470
471int sh_files_pushfile_user3 (const char * str_s)
472{
473 return (sh_files_pushfile (SH_LEVEL_USER3, str_s));
474}
475
476int sh_files_pushfile_user4 (const char * str_s)
477{
478 return (sh_files_pushfile (SH_LEVEL_USER4, str_s));
479}
480
481
482int sh_files_pushfile_ro (const char * str_s)
483{
484 return (sh_files_pushfile (SH_LEVEL_READONLY, str_s));
485}
486
487int sh_files_pushfile_attr (const char * str_s)
488{
489 return (sh_files_pushfile (SH_LEVEL_ATTRIBUTES, str_s));
490}
491
492int sh_files_pushfile_log (const char * str_s)
493{
494 return (sh_files_pushfile (SH_LEVEL_LOGFILES, str_s));
495}
496
497int sh_files_pushfile_glog (const char * str_s)
498{
499 return (sh_files_pushfile (SH_LEVEL_LOGGROW, str_s));
500}
501
502int sh_files_pushfile_noig (const char * str_s)
503{
504 return (sh_files_pushfile (SH_LEVEL_NOIGNORE, str_s));
505}
506
507int sh_files_pushfile_allig (const char * str_s)
508{
509 return (sh_files_pushfile (SH_LEVEL_ALLIGNORE, str_s));
510}
511
512
513static void sh_files_set_mask (unsigned long * mask,
514 unsigned long val, int act)
515{
516 SL_ENTER(_("sh_files_set_mask"));
517
518 if (act == 0)
519 (*mask) = val;
520 else if (act > 0)
521 (*mask) |= val;
522 else
523 (*mask) &= ~val;
524
525 SL_RET0(_("sh_files_set_mask"));
526}
527
528/* set mask(class)
529 */
530static int sh_files_parse_mask (unsigned long * mask, const char * str)
531{
532 int l, i = 0, act = 0, k = 0;
533 char myword[64];
534
535 SL_ENTER(_("sh_files_parse_mask"));
536
537 if (str == NULL)
538 {
539 SL_RETURN ( (-1), _("sh_files_parse_mask"));
540 }
541 else
542 l = sl_strlen(str);
543
544 while (i < l) {
545 if (str[i] == '\0')
546 break;
547 if (str[i] == ' ' || str[i] == '\t' || str[i] == ',')
548 {
549 ++i;
550 continue;
551 }
552
553 if (str[i] == '+')
554 {
555 act = +1; ++i;
556 continue;
557 }
558 else if (str[i] == '-')
559 {
560 act = -1; ++i;
561 continue;
562 }
563 else /* a word */
564 {
565 k = 0;
566 while (k < 63 && str[i] != ' ' && str[i] != '\t' && str[i] != ','
567 && str[i] != '+' && str[i] != '-' && str[i] != '\0') {
568 myword[k] = str[i];
569 ++i; ++k;
570 }
571 myword[k] = '\0';
572
573/* checksum */
574 if (0 == strncmp(myword, _("CHK"), 3))
575 sh_files_set_mask (mask, MODI_CHK, act);
576/* link */
577 if (0 == strncmp(myword, _("LNK"), 3))
578 sh_files_set_mask (mask, MODI_LNK, act);
579/* inode */
580 if (0 == strncmp(myword, _("RDEV"), 3))
581 sh_files_set_mask (mask, MODI_RDEV, act);
582/* inode */
583 if (0 == strncmp(myword, _("INO"), 3))
584 sh_files_set_mask (mask, MODI_INO, act);
585/* user */
586 if (0 == strncmp(myword, _("USR"), 3))
587 sh_files_set_mask (mask, MODI_USR, act);
588/* group */
589 if (0 == strncmp(myword, _("GRP"), 3))
590 sh_files_set_mask (mask, MODI_GRP, act);
591/* mtime */
592 if (0 == strncmp(myword, _("MTM"), 3))
593 sh_files_set_mask (mask, MODI_MTM, act);
594/* ctime */
595 if (0 == strncmp(myword, _("CTM"), 3))
596 sh_files_set_mask (mask, MODI_CTM, act);
597/* atime */
598 if (0 == strncmp(myword, _("ATM"), 3))
599 sh_files_set_mask (mask, MODI_ATM, act);
600/* size */
601 if (0 == strncmp(myword, _("SIZ"), 3))
602 sh_files_set_mask (mask, MODI_SIZ, act);
603/* file mode */
604 if (0 == strncmp(myword, _("MOD"), 3))
605 sh_files_set_mask (mask, MODI_MOD, act);
606/* hardlinks */
607 if (0 == strncmp(myword, _("HLN"), 3))
608 sh_files_set_mask (mask, MODI_HLN, act);
609/* size may grow */
610 if (0 == strncmp(myword, _("GROW"), 3))
611 sh_files_set_mask (mask, MODI_SGROW, act);
612/* use prelink */
613 if (0 == strncmp(myword, _("PRE"), 3))
614 sh_files_set_mask (mask, MODI_PREL, act);
615
616 }
617 }
618 SL_RETURN ( (0), _("sh_files_parse_mask"));
619}
620
621int sh_files_redef_prelink(const char * str)
622{
623 return (sh_files_parse_mask(&mask_PRELINK, str));
624}
625int sh_files_redef_user0(const char * str)
626{
627 return (sh_files_parse_mask(&mask_USER0, str));
628}
629int sh_files_redef_user1(const char * str)
630{
631 return (sh_files_parse_mask(&mask_USER1, str));
632}
633int sh_files_redef_user2(const char * str)
634{
635 return (sh_files_parse_mask(&mask_USER2, str));
636}
637int sh_files_redef_user3(const char * str)
638{
639 return (sh_files_parse_mask(&mask_USER3, str));
640}
641int sh_files_redef_user4(const char * str)
642{
643 return (sh_files_parse_mask(&mask_USER4, str));
644}
645int sh_files_redef_readonly(const char * str)
646{
647 return (sh_files_parse_mask(&mask_READONLY, str));
648}
649int sh_files_redef_loggrow(const char * str)
650{
651 return (sh_files_parse_mask(&mask_LOGGROW, str));
652}
653int sh_files_redef_logfiles(const char * str)
654{
655 return (sh_files_parse_mask(&mask_LOGFILES, str));
656}
657int sh_files_redef_attributes(const char * str)
658{
659 return (sh_files_parse_mask(&mask_ATTRIBUTES, str));
660}
661int sh_files_redef_noignore(const char * str)
662{
663 return (sh_files_parse_mask(&mask_NOIGNORE, str));
664}
665int sh_files_redef_allignore(const char * str)
666{
667 return (sh_files_parse_mask(&mask_ALLIGNORE, str));
668}
669
670unsigned long sh_files_maskof (int class)
671{
672 switch (class)
673 {
674 case SH_LEVEL_READONLY:
675 return (unsigned long) mask_READONLY;
676 case SH_LEVEL_ATTRIBUTES:
677 return (unsigned long) mask_ATTRIBUTES;
678 case SH_LEVEL_LOGFILES:
679 return (unsigned long) mask_LOGFILES;
680 case SH_LEVEL_LOGGROW:
681 return (unsigned long) mask_LOGGROW;
682 case SH_LEVEL_ALLIGNORE:
683 return (unsigned long) mask_ALLIGNORE;
684 case SH_LEVEL_NOIGNORE:
685 return (unsigned long) mask_NOIGNORE;
686 case SH_LEVEL_USER0:
687 return (unsigned long) mask_USER0;
688 case SH_LEVEL_USER1:
689 return (unsigned long) mask_USER1;
690 case SH_LEVEL_USER2:
691 return (unsigned long) mask_USER2;
692 case SH_LEVEL_USER3:
693 return (unsigned long) mask_USER3;
694 case SH_LEVEL_USER4:
695 return (unsigned long) mask_USER4;
696 case SH_LEVEL_PRELINK:
697 return (unsigned long) mask_PRELINK;
698 default:
699 return (unsigned long) 0;
700 }
701}
702
703#ifdef HAVE_GLOB_H
704int sh_files_has_metachar (const char * str)
705{
706 SL_ENTER(_("sh_files_has_metachar"));
707 if (NULL != strchr(str, '*'))
708 SL_RETURN(1, _("sh_files_has_metachar"));
709 else if (NULL != strchr(str, '?'))
710 SL_RETURN(1, _("sh_files_has_metachar"));
711 else if (NULL != (strchr(str, '[')))
712 SL_RETURN(1, _("sh_files_has_metachar"));
713 else
714 SL_RETURN(0, _("sh_files_has_metachar"));
715}
716
717
718int sh_files_globerr (const char * epath, int errnum)
719{
720 char * p;
721
722 SL_ENTER(_("sh_files_globerr"));
723
724 if (errnum == ENOTDIR || errnum == ENOENT)
725 {
726 SL_RETURN(0, _("sh_files_globerr"));
727 }
728
729 p = sh_util_safe_name (epath);
730 sh_error_handle (SH_ERR_ERR, FIL__, __LINE__, errnum, MSG_FI_GLOB,
731 sh_error_message (errnum), p);
732 SH_FREE(p);
733
734 SL_RETURN(0, _("sh_files_globerr"));
735}
736
737/* #ifdef HAVE_GLOB_H
738 */
739#endif
740
741int sh_files_push_file_int (int class, const char * str_s, size_t len)
742{
743 dirstack_t * new_item_ptr;
744 char * fileName;
745 int ret;
746
747 SL_ENTER(_("sh_files_push_file_int"));
748
749 fileName = SH_ALLOC(len+1);
750 sl_strlcpy(fileName, str_s, len+1);
751
752 new_item_ptr = (dirstack_t *) SH_ALLOC (sizeof(dirstack_t));
753
754 new_item_ptr->name = fileName;
755 new_item_ptr->class = class;
756 new_item_ptr->check_mask = sh_files_maskof(class);
757 new_item_ptr->rdepth = 0;
758 new_item_ptr->checked = S_FALSE;
759 new_item_ptr->reported = S_FALSE;
760 new_item_ptr->childs_checked = S_FALSE;
761
762 if (zfileList == NULL)
763 {
764 zfileList = zAVLAllocTree (zdirstack_key);
765 if (zfileList == NULL)
766 {
767 (void) safe_logger (0, 0, NULL);
768 aud__exit(FIL__, __LINE__, EXIT_FAILURE);
769 }
770 }
771
772 ret = zAVLInsert (zfileList, new_item_ptr);
773
774 if (-1 == ret)
775 {
776 (void) safe_logger (0, 0, NULL);
777 aud__exit(FIL__, __LINE__, EXIT_FAILURE);
778 }
779 if (3 == ret)
780 sh_error_handle ((-1), FIL__, __LINE__, 0, MSG_FI_DOUBLE,
781 fileName);
782
783 SL_RETURN(0, _("sh_files_push_file_int"));
784}
785
786
787static int sh_files_pushfile (int class, const char * str_s)
788{
789 size_t len;
790 char * tmp;
791 char * p;
792#ifdef HAVE_GLOB_H
793 int globstatus = -1;
794 unsigned int gloop;
795 glob_t pglob;
796#endif
797
798 static int reject = 0;
799
800 SL_ENTER(_("sh_files_pushfile"));
801
802 if (reject == 1)
803 SL_RETURN((-1),_("sh_files_pushfile"));
804
805 /* if we push a filename from the command line, make sure it
806 * is the only one -- and will stay the only one
807 */
808 if (sh.flag.opts == 1)
809 {
810 sh_files_delfilestack ();
811 sh_files_deldirstack ();
812 reject = 1;
813 }
814
815 if (str_s == NULL)
816 SL_RETURN((-1),_("sh_files_pushfile"));
817
818 len = sl_strlen(str_s);
819
820 if (len >= PATH_MAX)
821 {
822 /* Name too long
823 */
824 tmp = sh_util_safe_name (str_s);
825 sh_error_handle ((-1), FIL__, __LINE__, 0, MSG_FI_2LONG,
826 tmp);
827 SH_FREE(tmp);
828 SL_RETURN((-1),_("sh_files_pushfile"));
829 }
830 else if (len < 1)
831 {
832 /* Should not happen (str_s == NULL caught further above)
833 */
834 SL_RETURN((-1),_("sh_files_pushfile"));
835 }
836 else if (str_s[0] != '/')
837 {
838 /* Not an absolute path
839 */
840 tmp = sh_util_safe_name (str_s);
841 sh_error_handle ((-1), FIL__, __LINE__, 0, MSG_FI_NOPATH,
842 tmp);
843 SH_FREE(tmp);
844 SL_RETURN((-1),_("sh_files_pushfile"));
845 }
846 else
847 {
848 /* remove a terminating '/', take care of the
849 * special case of the root directory.
850 */
851 p = sh_util_strdup (str_s);
852 if (p[len-1] == '/' && len > 1)
853 {
854 p[len-1] = '\0';
855 --len;
856 }
857
858 }
859
860#ifdef HAVE_GLOB_H
861 if (0 == sh_files_has_metachar(p))
862 {
863 sh_files_push_file_int (class, p, len);
864 }
865 else
866 {
867 pglob.gl_offs = 0;
868 globstatus = glob (p, 0, sh_files_globerr, &pglob);
869
870 if (globstatus == 0 && pglob.gl_pathc > 0)
871 {
872 for (gloop = 0; gloop < (unsigned int) pglob.gl_pathc; ++gloop)
873 sh_files_push_file_int (class, pglob.gl_pathv[gloop],
874 sl_strlen(pglob.gl_pathv[gloop]));
875 }
876 else
877 {
878 tmp = sh_util_safe_name (p);
879
880 if (pglob.gl_pathc == 0
881#ifdef GLOB_NOMATCH
882 || globstatus == GLOB_NOMATCH
883#endif
884 )
885 sh_error_handle (SH_ERR_ERR, FIL__, __LINE__,
886 globstatus, MSG_FI_GLOB,
887 _("No matches found"), tmp);
888#ifdef GLOB_NOSPACE
889 else if (globstatus == GLOB_NOSPACE)
890 sh_error_handle (SH_ERR_ERR, FIL__, __LINE__,
891 globstatus, MSG_FI_GLOB,
892 _("Out of memory"), tmp);
893#endif
894#ifdef GLOB_ABORTED
895 else if (globstatus == GLOB_ABORTED)
896 sh_error_handle (SH_ERR_ERR, FIL__, __LINE__,
897 globstatus, MSG_FI_GLOB,
898 _("Read error"), tmp);
899#endif
900 else
901 sh_error_handle (SH_ERR_ERR, FIL__, __LINE__,
902 globstatus, MSG_FI_GLOB,
903 _("Unknown error"), tmp);
904
905 SH_FREE(tmp);
906
907 }
908
909 globfree(&pglob);
910 }
911
912#else
913 sh_files_push_file_int (class, p, len);
914#endif
915
916 SH_FREE(p);
917 SL_RETURN((0),_("sh_files_pushfile"));
918}
919
920
921/* ------ directories ----- */
922
923int sh_files_is_allignore_int (char * str, zAVLTree * tree)
924{
925 dirstack_t * ptr;
926
927 SL_ENTER(_("sh_files_is_allignore"));
928
929 if (tree)
930 {
931 ptr = zAVLSearch(tree, str);
932 if (ptr)
933 {
934 if (ptr->class == SH_LEVEL_ALLIGNORE)
935 SL_RETURN( 1, _("sh_files_is_allignore"));
936 else
937 SL_RETURN( 0, _("sh_files_is_allignore"));
938 }
939 }
940 SL_RETURN( 0, _("sh_files_is_allignore"));
941}
942
943int sh_files_is_allignore (char * str)
944{
945 if (1 == sh_files_is_allignore_int(str, zdirListOne))
946 return 1;
947 if (NULL == zdirListTwo)
948 return 0;
949 return sh_files_is_allignore_int(str, zdirListTwo);
950}
951
952unsigned long sh_dirs_chk (int which)
953{
954 zAVLTree * tree;
955 zAVLCursor cursor;
956 dirstack_t * ptr;
957 dirstack_t * dst_ptr;
958 int status;
959 unsigned long dcount = 0;
960 char * tmp;
961
962 SL_ENTER(_("sh_dirs_chk"));
963
964 if (which == 1)
965 tree = zdirListOne;
966 else
967 tree = zdirListTwo;
968
969 for (ptr = (dirstack_t *) zAVLFirst(&cursor, tree); ptr;
970 ptr = (dirstack_t *) zAVLNext(&cursor))
971 {
972 if (sig_urgent > 0) {
973 SL_RETURN(dcount, _("sh_dirs_chk"));
974 }
975
976 if (ptr->checked == S_FALSE)
977 {
978 /* 28 Aug 2001 check the top level directory
979 */
980 status = S_FALSE;
981 dst_ptr = zAVLSearch(zfileList, ptr->name);
982 if (dst_ptr)
983 {
984 if (dst_ptr->checked == S_FALSE)
985 {
986 BREAKEXIT(sh_files_filecheck);
987 sh_files_filecheck (dst_ptr->class, ptr->name,
988 NULL, &status, 0);
989 dst_ptr->checked = S_TRUE;
990 status = S_TRUE;
991 }
992 else
993 {
994 status = S_TRUE;
995 }
996 }
997
998 if (status == S_FALSE)
999 sh_files_filecheck (ptr->class, ptr->name, NULL, &status, 0);
1000
1001 BREAKEXIT(sh_files_checkdir);
1002 status = sh_files_checkdir (ptr->class, ptr->rdepth, ptr->name,
1003 ptr->name);
1004
1005 if (status < 0 && ptr->reported == S_FALSE)
1006 {
1007 /* directory is missing
1008 */
1009 if (S_FALSE == sh_ignore_chk_del(ptr->name))
1010 {
1011 if (0 != hashreport_missing(ptr->name,
1012 (ptr->class == SH_LEVEL_ALLIGNORE) ?
1013 ShDFLevel[ptr->class] :
1014 ShDFLevel[SH_ERR_T_DIR])) {
1015 tmp = sh_util_safe_name (ptr->name);
1016 sh_error_handle ((ptr->class == SH_LEVEL_ALLIGNORE) ?
1017 ShDFLevel[ptr->class] :
1018 ShDFLevel[SH_ERR_T_DIR], FIL__, __LINE__,
1019 0, MSG_FI_MISS, tmp);
1020 SH_FREE(tmp);
1021 }
1022 }
1023 if (sh.flag.reportonce == S_TRUE)
1024 ptr->reported = S_TRUE;
1025 }
1026 else
1027 {
1028 /* exists (status >= 0), but was missing (reported == TRUE)
1029 */
1030 if (status >= 0 && ptr->reported == S_TRUE)
1031 {
1032 ptr->reported = S_FALSE;
1033#if 0
1034 /* obsoleted (really?) by the mandatory sh_files_filecheck()
1035 * above, which will catch missing directories anyway
1036 */
1037 tmp = sh_util_safe_name (ptr->name);
1038 sh_error_handle ((ptr->class == SH_LEVEL_ALLIGNORE) ?
1039 ShDFLevel[ptr->class] :
1040 ShDFLevel[SH_ERR_T_DIR],
1041 FIL__, __LINE__, 0, MSG_FI_ADD,
1042 tmp);
1043 SH_FREE(tmp);
1044#endif
1045 }
1046 else if (status == SH_FILE_UNKNOWN)
1047 {
1048 /* catchall
1049 */
1050 tmp = sh_util_safe_name (ptr->name);
1051 sh_error_handle (SH_ERR_INFO, FIL__, __LINE__, 0,
1052 MSG_FI_FAIL,
1053 tmp);
1054 SH_FREE(tmp);
1055 if (sh.flag.checkSum != SH_CHECK_INIT)
1056 sh_hash_set_visited_true(ptr->name);
1057 }
1058
1059 ++dcount;
1060 }
1061 ptr->checked = S_TRUE;
1062 ptr->childs_checked = S_TRUE;
1063 }
1064
1065 if (sig_urgent > 0) {
1066 SL_RETURN(dcount, _("sh_dirs_chk"));
1067 }
1068
1069 }
1070 SL_RETURN(dcount, _("sh_dirs_chk"));
1071}
1072
1073int sh_files_pushdir_prelink (const char * str_s)
1074{
1075 return (sh_files_pushdir (SH_LEVEL_PRELINK, str_s));
1076}
1077
1078int sh_files_pushdir_user0 (const char * str_s)
1079{
1080 return (sh_files_pushdir (SH_LEVEL_USER0, str_s));
1081}
1082
1083int sh_files_pushdir_user1 (const char * str_s)
1084{
1085 return (sh_files_pushdir (SH_LEVEL_USER1, str_s));
1086}
1087
1088int sh_files_pushdir_user2 (const char * str_s)
1089{
1090 return (sh_files_pushdir (SH_LEVEL_USER2, str_s));
1091}
1092
1093int sh_files_pushdir_user3 (const char * str_s)
1094{
1095 return (sh_files_pushdir (SH_LEVEL_USER3, str_s));
1096}
1097
1098int sh_files_pushdir_user4 (const char * str_s)
1099{
1100 return (sh_files_pushdir (SH_LEVEL_USER4, str_s));
1101}
1102
1103int sh_files_pushdir_attr (const char * str_s)
1104{
1105 return (sh_files_pushdir (SH_LEVEL_ATTRIBUTES, str_s));
1106}
1107
1108int sh_files_pushdir_ro (const char * str_s)
1109{
1110 return (sh_files_pushdir (SH_LEVEL_READONLY, str_s));
1111}
1112
1113int sh_files_pushdir_log (const char * str_s)
1114{
1115 return (sh_files_pushdir (SH_LEVEL_LOGFILES, str_s));
1116}
1117
1118int sh_files_pushdir_glog (const char * str_s)
1119{
1120 return (sh_files_pushdir (SH_LEVEL_LOGGROW, str_s));
1121}
1122
1123int sh_files_pushdir_noig (const char * str_s)
1124{
1125 return (sh_files_pushdir (SH_LEVEL_NOIGNORE, str_s));
1126}
1127
1128int sh_files_pushdir_allig (const char * str_s)
1129{
1130 return (sh_files_pushdir (SH_LEVEL_ALLIGNORE, str_s));
1131}
1132
1133static int which_dirList = 1;
1134
1135int set_dirList (int which)
1136{
1137 if (which == 2)
1138 which_dirList = 2;
1139 else
1140 which_dirList = 1;
1141 return 0;
1142}
1143
1144int sh_files_push_dir_int (int class, char * tail, size_t len, int rdepth)
1145{
1146 zAVLTree * tree;
1147 dirstack_t * new_item_ptr;
1148 char * dirName;
1149 int ret;
1150
1151 SL_ENTER(_("sh_files_push_dir_int"));
1152
1153 dirName = SH_ALLOC(len+1);
1154 sl_strlcpy(dirName, tail, len+1);
1155
1156 new_item_ptr = (dirstack_t * ) SH_ALLOC (sizeof(dirstack_t));
1157
1158 new_item_ptr->name = dirName;
1159 new_item_ptr->class = class;
1160 new_item_ptr->check_mask = sh_files_maskof(class);
1161 new_item_ptr->rdepth = rdepth;
1162 new_item_ptr->checked = S_FALSE;
1163 new_item_ptr->reported = S_FALSE;
1164 new_item_ptr->childs_checked = S_FALSE;
1165
1166 if (which_dirList == 1)
1167 {
1168 tree = zdirListOne;
1169 }
1170 else
1171 {
1172 tree = zdirListTwo;
1173 }
1174
1175 if (tree == NULL)
1176 {
1177 tree = zAVLAllocTree (zdirstack_key);
1178 if (tree == NULL)
1179 {
1180 (void) safe_logger (0, 0, NULL);
1181 aud__exit(FIL__, __LINE__, EXIT_FAILURE);
1182 }
1183 if (which_dirList == 1)
1184 zdirListOne = tree;
1185 else
1186 zdirListTwo = tree;
1187 }
1188
1189 ret = zAVLInsert (tree, new_item_ptr);
1190
1191 if (-1 == ret)
1192 {
1193 (void) safe_logger (0, 0, NULL);
1194 aud__exit(FIL__, __LINE__, EXIT_FAILURE);
1195 }
1196 if (3 == ret)
1197 sh_error_handle ((-1), FIL__, __LINE__, 0, MSG_FI_DOUBLE,
1198 dirName);
1199
1200 SL_RETURN(0, _("sh_files_push_dir_int"));
1201}
1202
1203static int sh_files_pushdir (int class, const char * str_s)
1204{
1205 char * tmp;
1206 size_t len;
1207 int rdepth = 0;
1208 char * tail = NULL;
1209 char * p;
1210
1211#ifdef HAVE_GLOB_H
1212 glob_t pglob;
1213 int globstatus = -1;
1214 unsigned int gloop;
1215#endif
1216
1217 SL_ENTER(_("sh_files_pushdir"));
1218
1219 if (sh.flag.opts == 1) {
1220 sh_files_delfilestack ();
1221 sh_files_deldirstack ();
1222 }
1223
1224 if (str_s == NULL)
1225 SL_RETURN((-1), _("sh_files_pushdir"));
1226
1227 p = sh_util_strdup (str_s);
1228
1229 if (p[0] != '/')
1230 {
1231 rdepth = strtol(p, &tail, 10);
1232 if (tail == p)
1233 {
1234 SH_FREE(p);
1235 SL_RETURN((-1), _("sh_files_pushdir"));
1236 }
1237 }
1238 else
1239 tail = p;
1240
1241
1242 if (rdepth < (-1) || tail == p || rdepth > 99)
1243 rdepth = (-2);
1244
1245 len = sl_strlen(tail);
1246
1247 if (len >= PATH_MAX)
1248 {
1249 tmp = sh_util_safe_name (tail);
1250 sh_error_handle ((-1), FIL__, __LINE__, 0, MSG_FI_2LONG,
1251 tmp);
1252 SH_FREE(tmp);
1253 SH_FREE(p);
1254 SL_RETURN((-1), _("sh_files_pushdir"));
1255 }
1256 else if (len < 1)
1257 {
1258 SH_FREE(p);
1259 SL_RETURN((-1), _("sh_files_pushdir"));
1260 }
1261 else if (tail[0] != '/')
1262 {
1263 tmp = sh_util_safe_name (tail);
1264 sh_error_handle ((-1), FIL__, __LINE__, 0, MSG_FI_NOPATH,
1265 tmp);
1266 SH_FREE(tmp);
1267 SH_FREE(p);
1268 SL_RETURN((-1), _("sh_files_pushdir"));
1269 }
1270 else
1271 {
1272
1273 if (tail[len-1] == '/' && len > 1)
1274 {
1275 tail[len-1] = '\0';
1276 --len;
1277 }
1278
1279 }
1280
1281#ifdef HAVE_GLOB_H
1282 if (0 == sh_files_has_metachar(tail))
1283 {
1284 sh_files_push_dir_int (class, tail, len, rdepth);
1285 }
1286 else
1287 {
1288 pglob.gl_offs = 0;
1289 globstatus = glob (tail, 0, sh_files_globerr, &pglob);
1290
1291 if (globstatus == 0 && pglob.gl_pathc > 0)
1292 {
1293 for (gloop = 0; gloop < (unsigned int) pglob.gl_pathc; ++gloop)
1294 sh_files_push_dir_int (class,
1295 pglob.gl_pathv[gloop],
1296 sl_strlen(pglob.gl_pathv[gloop]),
1297 rdepth);
1298 }
1299 else
1300 {
1301 tmp = sh_util_safe_name (tail);
1302
1303 if (pglob.gl_pathc == 0
1304#ifdef GLOB_NOMATCH
1305 || globstatus == GLOB_NOMATCH
1306#endif
1307 )
1308 sh_error_handle (SH_ERR_ERR, FIL__, __LINE__,
1309 globstatus, MSG_FI_GLOB,
1310 _("No matches found"), tmp);
1311#ifdef GLOB_NOSPACE
1312 else if (globstatus == GLOB_NOSPACE)
1313 sh_error_handle (SH_ERR_ERR, FIL__, __LINE__,
1314 globstatus, MSG_FI_GLOB,
1315 _("Out of memory"), tmp);
1316#endif
1317#ifdef GLOB_ABORTED
1318 else if (globstatus == GLOB_ABORTED)
1319 sh_error_handle (SH_ERR_ERR, FIL__, __LINE__,
1320 globstatus, MSG_FI_GLOB,
1321 _("Read error"), tmp);
1322#endif
1323 else
1324 sh_error_handle (SH_ERR_ERR, FIL__, __LINE__,
1325 globstatus, MSG_FI_GLOB,
1326 _("Unknown error"), tmp);
1327 SH_FREE(tmp);
1328 }
1329
1330 globfree(&pglob);
1331 }
1332#else
1333 sh_files_push_dir_int (class, tail, len, rdepth);
1334#endif
1335
1336 SH_FREE(p);
1337 SL_RETURN((0), _("sh_files_pushdir"));
1338}
1339
1340struct sh_dirent {
1341 /* char sh_d_name[NAME_MAX + 2]; */
1342 char * sh_d_name;
1343 struct sh_dirent * next;
1344};
1345
1346static void kill_sh_dirlist (struct sh_dirent * dirlist)
1347{
1348 struct sh_dirent * this;
1349
1350 while (dirlist)
1351 {
1352 this = dirlist->next;
1353 SH_FREE(dirlist->sh_d_name);
1354 SH_FREE(dirlist);
1355 dirlist = this;
1356 }
1357 return;
1358}
1359
1360/* -- add an entry to a directory listing
1361 */
1362static struct sh_dirent * addto_sh_dirlist (struct dirent * thisEntry,
1363 struct sh_dirent * dirlist)
1364{
1365 struct sh_dirent * this;
1366 size_t len;
1367
1368 if (thisEntry == NULL)
1369 return dirlist;
1370
1371 len = sl_strlen(thisEntry->d_name);
1372 if (len == 0)
1373 return dirlist;
1374 ++len;
1375
1376 this = SH_ALLOC(sizeof(struct sh_dirent));
1377 if (!this)
1378 return dirlist;
1379
1380 this->sh_d_name = SH_ALLOC(len);
1381 sl_strlcpy(this->sh_d_name, thisEntry->d_name, len);
1382
1383 this->next = dirlist;
1384 return this;
1385}
1386
1387static int sh_check_hardlinks = S_TRUE;
1388
1389/* Simply sets our boolean as to whether this check is active
1390 */
1391int sh_files_check_hardlinks (const char * opt)
1392{
1393 int i;
1394 SL_ENTER(_("sh_files_check_hardlinks"));
1395 i = sh_util_flagval(opt, &sh_check_hardlinks);
1396 SL_RETURN(i, _("sh_files_check_hardlinks"));
1397}
1398
1399struct sh_hle_struct {
1400 long offset;
1401 char * path;
1402 struct sh_hle_struct * next;
1403};
1404
1405static struct sh_hle_struct * sh_hl_exc = NULL;
1406
1407int sh_files_hle_reg (const char * str)
1408{
1409 long offset;
1410 size_t len;
1411 char * path;
1412
1413 struct sh_hle_struct * tmp = sh_hl_exc;
1414
1415 SL_ENTER(_("sh_files_hle_reg"));
1416
1417 /* Free the linked list if called with NULL argument
1418 */
1419 if (str == NULL)
1420 {
1421 while (tmp)
1422 {
1423 sh_hl_exc = tmp->next;
1424 SH_FREE(tmp->path);
1425 SH_FREE(tmp);
1426 tmp = sh_hl_exc;
1427 }
1428 sh_hl_exc = NULL;
1429 SL_RETURN(0, _("sh_files_hle_reg"));
1430 }
1431
1432 /* We expect 'offset:/path'
1433 */
1434 offset = strtol(str, &path, 0);
1435 if ((path == NULL) || (*path == '\0') || (*path != ':') || (path[1] != '/'))
1436 {
1437 SL_RETURN(-1, _("sh_files_hle_reg"));
1438 }
1439 ++path;
1440 len = 1 + sl_strlen(path);
1441
1442 tmp = SH_ALLOC(sizeof(struct sh_hle_struct));
1443 tmp->path = SH_ALLOC(len);
1444 sl_strlcpy (tmp->path, path, len);
1445 tmp->offset = offset;
1446 tmp->next = sh_hl_exc;
1447 sh_hl_exc = tmp;
1448
1449 SL_RETURN(0, _("sh_files_hle_reg"));
1450}
1451
1452#if !defined(HOST_IS_DARWIN)
1453static int sh_files_hle_test (int offset, char * path)
1454{
1455 struct sh_hle_struct * tmp = sh_hl_exc;
1456
1457 SL_ENTER(_("sh_files_hle_reg"));
1458
1459 while(tmp)
1460 {
1461 if ((offset == tmp->offset) && (0 == strcmp(path, tmp->path)))
1462 {
1463 SL_RETURN(0, _("sh_files_hle_test"));
1464 }
1465 tmp = tmp->next;
1466 }
1467 SL_RETURN(-1, _("sh_files_hle_test"));
1468}
1469#endif
1470
1471/* -- check a single directory and its content
1472 */
1473static int sh_files_checkdir (int iclass, int idepth, char * iname,
1474 char * relativeName)
1475{
1476 struct sh_dirent * dirlist = NULL;
1477 struct sh_dirent * dirlist_orig = NULL;
1478
1479 DIR * thisDir = NULL;
1480 struct dirent * thisEntry;
1481 int status;
1482 int dummy = S_FALSE;
1483 dir_type theDir;
1484 ShFileType checkit;
1485
1486
1487 file_type theFile;
1488 char * tmpname;
1489 char * tmpcat;
1490
1491 int rdepth = 0;
1492 int class = 0;
1493 int rdepth_next;
1494 int class_next;
1495 int file_class_next;
1496
1497 int checked_flag = S_FALSE;
1498 int cchecked_flag = S_FALSE;
1499
1500 dirstack_t * dst_ptr;
1501 dirstack_t * tmp_ptr;
1502
1503 int hardlink_num = 0;
1504#if !defined(HOST_IS_DARWIN)
1505 size_t len;
1506#endif
1507
1508 SL_ENTER(_("sh_files_checkdir"));
1509
1510 if (sig_urgent > 0) {
1511 SL_RETURN((0), _("sh_files_checkdir"));
1512 }
1513
1514 if (iname == NULL || idepth < (-1))
1515 SL_RETURN((-1), _("sh_files_checkdir"));
1516
1517 if (idepth < 0)
1518 {
1519 /* hash_remove_tree (iname); */
1520 SL_RETURN((0), _("sh_files_checkdir"));
1521 }
1522
1523 rdepth = idepth;
1524 class = iclass;
1525
1526 tmpname = sh_util_safe_name (iname);
1527
1528 /* ---- check for obscure name ----
1529 */
1530 if (iclass != SH_LEVEL_ALLIGNORE)
1531 {
1532 sh_util_obscurename (ShDFLevel[SH_ERR_T_NAME], iname, S_TRUE);
1533 }
1534
1535 if (flag_err_info == SL_TRUE)
1536 {
1537 sh_error_handle ((-1), FIL__, __LINE__, 0, MSG_FI_CHK, tmpname);
1538 }
1539
1540 /* ---- check input ----
1541 */
1542 if ( sl_strlen(iname) >= PATH_MAX)
1543 {
1544 sh_error_handle (ShDFLevel[SH_ERR_T_DIR], FIL__, __LINE__, 0,
1545 MSG_FI_2LONG,
1546 tmpname);
1547 SH_FREE(tmpname);
1548 SL_RETURN((-1), _("sh_files_checkdir"));
1549 }
1550
1551 /* ---- check for absolute path ---- */
1552 if ( iname[0] != '/')
1553 {
1554 sh_error_handle (ShDFLevel[SH_ERR_T_DIR], FIL__, __LINE__, 0,
1555 MSG_FI_NOPATH,
1556 tmpname);
1557 SH_FREE(tmpname);
1558 SL_RETURN((-1), _("sh_files_checkdir"));
1559 }
1560
1561
1562 /* ---- stat the directory ----
1563 */
1564 sl_strlcpy (theFile.fullpath, iname, PATH_MAX);
1565
1566 (void) relativeName;
1567 status = sh_unix_getinfo (ShDFLevel[SH_ERR_T_DIR],
1568 iname,
1569 &theFile, NULL, iclass);
1570
1571 if ((sig_termfast == 1) || (sig_terminate == 1))
1572 {
1573 SL_RETURN((0), _("sh_files_checkdir"));
1574 }
1575
1576 if (status == -1)
1577 {
1578 SH_FREE(tmpname);
1579 SL_RETURN((-1), _("sh_files_checkdir"));
1580 }
1581
1582 if (theFile.c_mode[0] != 'd')
1583 {
1584 sh_error_handle (ShDFLevel[SH_ERR_T_DIR], FIL__, __LINE__, 0,
1585 MSG_FI_NODIR,
1586 tmpname);
1587 SH_FREE(tmpname);
1588 SL_RETURN((-1), _("sh_files_checkdir"));
1589 }
1590
1591 hardlink_num = theFile.hardlinks;
1592
1593
1594 /* ---- open directory for reading ----
1595 *
1596 * opendir() will fail with ENOTDIR if the path has been changed
1597 * to a non-directory in between lstat() and opendir().
1598 */
1599 thisDir = opendir (iname);
1600
1601 if (thisDir == NULL)
1602 {
1603 status = errno;
1604 sh_error_handle (ShDFLevel[SH_ERR_T_DIR], FIL__, __LINE__, 0,
1605 MSG_E_OPENDIR,
1606 sh_error_message (status), tmpname);
1607 SH_FREE(tmpname);
1608
1609 SL_RETURN((-1), _("sh_files_checkdir"));
1610 }
1611
1612 theDir.NumRegular = 0;
1613 theDir.NumDirs = 0;
1614 theDir.NumSymlinks = 0;
1615 theDir.NumFifos = 0;
1616 theDir.NumSockets = 0;
1617 theDir.NumCDev = 0;
1618 theDir.NumBDev = 0;
1619 theDir.NumDoor = 0;
1620 theDir.NumPort = 0;
1621 theDir.NumAll = 0;
1622 theDir.TotalBytes = 0;
1623 sl_strlcpy (theDir.DirPath, iname, PATH_MAX);
1624
1625
1626 /* ---- read ----
1627 */
1628 do {
1629 thisEntry = readdir (thisDir);
1630 if (thisEntry != NULL)
1631 {
1632 ++theDir.NumAll;
1633 if (sl_strcmp (thisEntry->d_name, ".") == 0)
1634 {
1635 ++theDir.NumDirs;
1636 continue;
1637 }
1638 if (sl_strcmp (thisEntry->d_name, "..") == 0)
1639 {
1640 ++theDir.NumDirs;
1641 continue;
1642 }
1643 dirlist = addto_sh_dirlist (thisEntry, dirlist);
1644 }
1645 } while (thisEntry != NULL);
1646
1647 closedir (thisDir);
1648
1649 ++sh.statistics.dirs_checked;
1650
1651 dirlist_orig = dirlist;
1652
1653 do {
1654
1655 /* If the directory is empty, dirlist = NULL
1656 */
1657 if (!dirlist)
1658 break;
1659
1660 if (sig_termfast == 1)
1661 {
1662 SL_RETURN((0), _("sh_files_checkdir"));
1663 }
1664
1665 BREAKEXIT(sh_derr);
1666 if (0 == (rand() % 5))
1667 (void) sh_derr();
1668
1669 /* ---- Check the file. ----
1670 */
1671 tmpcat = SH_ALLOC(PATH_MAX);
1672 sl_strlcpy(tmpcat, iname, PATH_MAX);
1673 if (sl_strlen(tmpcat) > 1 || tmpcat[0] != '/')
1674 sl_strlcat(tmpcat, "/", PATH_MAX);
1675 sl_strlcat(tmpcat, dirlist->sh_d_name, PATH_MAX);
1676
1677 rdepth_next = rdepth - 1;
1678 class_next = class;
1679 file_class_next = class;
1680 checked_flag = -1;
1681 cchecked_flag = -1;
1682
1683 /* Wed Aug 24 2005 compare against dirListOne, dirListTwo
1684 * this fixes the problem that the directory special file
1685 * is checked with the policy of the parent directory
1686 */
1687 dst_ptr = (dirstack_t *) zAVLSearch(zdirListOne, tmpcat);
1688
1689 if (dst_ptr)
1690 {
1691 /* Tue Aug 6 22:13:27 CEST 2002 introduce file_class_next
1692 * this fixes the problem that a policy for the directory
1693 * inode erroneously becomes a policy for the directory itself.
1694 */
1695 file_class_next = dst_ptr->class;
1696 checked_flag = dst_ptr->checked;
1697 cchecked_flag = dst_ptr->childs_checked;
1698 }
1699
1700 if (checked_flag == -1)
1701 {
1702 dst_ptr = (dirstack_t *) zAVLSearch(zdirListTwo, tmpcat);
1703
1704 if (dst_ptr)
1705 {
1706 /* Tue Aug 6 22:13:27 CEST 2002 introduce file_class_next
1707 * this fixes the problem that a policy for the directory
1708 * inode erroneously becomes a policy for the directory itself.
1709 */
1710 file_class_next = dst_ptr->class;
1711 checked_flag = dst_ptr->checked;
1712 cchecked_flag = dst_ptr->childs_checked;
1713 }
1714 }
1715
1716 dst_ptr = (dirstack_t *) zAVLSearch(zfileList, tmpcat);
1717
1718 if (dst_ptr)
1719 {
1720 /* Tue Aug 6 22:13:27 CEST 2002 introduce file_class_next
1721 * this fixes the problem that a policy for the directory
1722 * inode erroneously becomes a policy for the directory itself.
1723 */
1724 file_class_next = dst_ptr->class;
1725 checked_flag = dst_ptr->checked;
1726 /* not set, hence always FALSE */
1727 /* cchecked_flag = dst_ptr->childs_checked; */
1728 }
1729
1730 /* ---- Has been checked already. ----
1731 */
1732 if (checked_flag == S_TRUE && cchecked_flag == S_TRUE)
1733 {
1734 /* Mar 11 2004 get ftype for complete directory count
1735 */
1736 checkit = sh_unix_get_ftype(tmpcat);
1737 if (checkit == SH_FILE_DIRECTORY)
1738 {
1739 ++theDir.NumDirs;
1740 }
1741 SH_FREE(tmpcat);
1742 dirlist = dirlist->next;
1743 continue;
1744 }
1745
1746 /* --- May be true, false, or not found. ---
1747 */
1748 if (checked_flag == S_TRUE)
1749 {
1750 /* -- need only the file type --
1751 */
1752 checkit = sh_unix_get_ftype(tmpcat);
1753 }
1754 else
1755 {
1756 /* -- need to check the file itself --
1757 */
1758 if (dst_ptr && sh.flag.reportonce == S_TRUE)
1759 dummy = dst_ptr->reported;
1760
1761 checkit = sh_files_filecheck (file_class_next,
1762 iname,
1763 dirlist->sh_d_name,
1764 &dummy, 0);
1765
1766 if (dst_ptr && checked_flag == S_FALSE)
1767 dst_ptr->checked = S_TRUE;
1768 /* Thu Mar 7 15:09:40 CET 2002 Propagate the 'reported' flag
1769 */
1770 if (dst_ptr && sh.flag.reportonce == S_TRUE)
1771 dst_ptr->reported = dummy;
1772 }
1773
1774 if (checkit == SH_FILE_REGULAR)
1775 ++theDir.NumRegular;
1776
1777 else if (checkit == SH_FILE_DIRECTORY)
1778 {
1779 ++theDir.NumDirs;
1780 if (rdepth_next >= 0 && cchecked_flag != S_TRUE)
1781 {
1782 rdepth_next = rdepth - 1;
1783
1784 /* check whether the new directory is in the
1785 * list with a recursion depth already defined
1786 */
1787 checked_flag = -1;
1788 cchecked_flag = -1;
1789
1790 tmp_ptr = (dirstack_t *) zAVLSearch(zdirListOne, tmpcat);
1791
1792 if (tmp_ptr)
1793 {
1794 TPT((0, FIL__, __LINE__,
1795 _("msg=<%s -> recursion depth %d\n>"),
1796 tmp_ptr->name, tmp_ptr->rdepth));
1797 rdepth_next = tmp_ptr->rdepth;
1798 class_next = tmp_ptr->class;
1799 /* 28. Aug 2001 reversed
1800 */
1801 cchecked_flag = tmp_ptr->childs_checked;
1802 checked_flag = tmp_ptr->checked;
1803 }
1804
1805 if (checked_flag == -1)
1806 {
1807 tmp_ptr = (dirstack_t *) zAVLSearch(zdirListTwo, tmpcat);
1808
1809 if (tmp_ptr)
1810 {
1811 TPT((0, FIL__, __LINE__,
1812 _("msg=<%s -> recursion depth %d\n>"),
1813 tmp_ptr->name, tmp_ptr->rdepth));
1814 rdepth_next = tmp_ptr->rdepth;
1815 class_next = tmp_ptr->class;
1816 /* 28. Aug 2001 reversed
1817 */
1818 cchecked_flag = tmp_ptr->childs_checked;
1819 checked_flag = tmp_ptr->checked;
1820 }
1821 }
1822
1823 if (cchecked_flag == S_FALSE)
1824 {
1825 sh_files_checkdir (class_next, rdepth_next, tmpcat,
1826 dirlist->sh_d_name);
1827 tmp_ptr->childs_checked = S_TRUE;
1828 /*
1829 * 04. Feb 2006 avoid double checking
1830 */
1831 tmp_ptr->checked = S_TRUE;
1832 }
1833 else if (checked_flag == -1)
1834 sh_files_checkdir (class_next, rdepth_next, tmpcat,
1835 dirlist->sh_d_name);
1836
1837 }
1838 }
1839
1840 else if (checkit == SH_FILE_SYMLINK) ++theDir.NumSymlinks;
1841 else if (checkit == SH_FILE_FIFO) ++theDir.NumFifos;
1842 else if (checkit == SH_FILE_SOCKET) ++theDir.NumSockets;
1843 else if (checkit == SH_FILE_CDEV) ++theDir.NumCDev;
1844 else if (checkit == SH_FILE_BDEV) ++theDir.NumBDev;
1845 else if (checkit == SH_FILE_DOOR) ++theDir.NumDoor;
1846 else if (checkit == SH_FILE_PORT) ++theDir.NumPort;
1847
1848 SH_FREE(tmpcat);
1849
1850 if ((sig_termfast == 1) || (sig_terminate == 1))
1851 {
1852 SL_RETURN((0), _("sh_files_checkdir"));
1853 }
1854
1855 dirlist = dirlist->next;
1856
1857 if (dst_ptr)
1858 dst_ptr->childs_checked = S_TRUE;
1859
1860 } while (dirlist != NULL);
1861
1862 if (flag_err_info == SL_TRUE)
1863 {
1864 sh_error_handle ((-1), FIL__, __LINE__, 0, MSG_FI_DSUM,
1865 theDir.NumDirs,
1866 theDir.NumRegular,
1867 theDir.NumSymlinks,
1868 theDir.NumFifos,
1869 theDir.NumSockets,
1870 theDir.NumCDev,
1871 theDir.NumBDev);
1872 }
1873
1874 kill_sh_dirlist (dirlist_orig);
1875
1876#if !defined(HOST_IS_DARWIN)
1877 /*
1878 * Hardlink check; not done on MacOS X because of resource forks
1879 */
1880 if ((sh_check_hardlinks == S_TRUE) && (hardlink_num != theDir.NumDirs))
1881 {
1882 if (0 != sh_files_hle_test(hardlink_num-theDir.NumDirs, iname))
1883 {
1884 len = strlen(tmpname);
1885 if (sl_ok_adds(len, 256))
1886 len += 256;
1887 tmpcat = SH_ALLOC(len);
1888 sl_snprintf(tmpcat, len,
1889 _("%s: subdirectory count (%d) != hardlinks (%d)"),
1890 tmpname, theDir.NumDirs, hardlink_num);
1891 sh_error_handle (ShDFLevel[SH_ERR_T_DIR], FIL__, __LINE__, 0,
1892 MSG_E_SUBGEN, tmpcat, _("sh_files_checkdir"));
1893 SH_FREE(tmpcat);
1894 }
1895 }
1896#endif
1897
1898 SH_FREE(tmpname);
1899
1900 SL_RETURN((0), _("sh_files_checkdir"));
1901}
1902
1903int get_the_fd (SL_TICKET ticket);
1904
1905
1906static ShFileType sh_files_filecheck (int class, char * dirName,
1907 char * infileName,
1908 int * reported,
1909 int rsrcflag)
1910{
1911 /* 28 Aug 2001 allow NULL fileName
1912 */
1913 char fullpath[PATH_MAX];
1914 char fileHash[2*(KEY_LEN + 1)];
1915 int status;
1916 file_type theFile;
1917 char * tmpdir;
1918 char * tmpname;
1919 char * fileName;
1920 struct utimbuf utime_buf;
1921
1922 SL_ENTER(_("sh_files_filecheck"));
1923
1924 BREAKEXIT(sh_derr);
1925 if (0 == (rand() % 2))
1926 (void) sh_derr();
1927
1928 if (dirName && infileName && (dirName[0] == '/') && (dirName[1] == '\0')
1929 && (infileName[0] == '/') && (infileName[1] == '\0'))
1930 {
1931 fileName = NULL;
1932 }
1933 else
1934 {
1935 fileName = infileName;
1936 }
1937
1938 /* fileName may be NULL if this is a directory
1939 */
1940 if (dirName == NULL /* || fileName == NULL */)
1941 {
1942 sh_error_handle ((-1), FIL__, __LINE__, 0, MSG_FI_NULL);
1943 SL_RETURN(SH_FILE_UNKNOWN, _("sh_files_filecheck"));
1944 }
1945
1946 if ((fileName != NULL) && (class != SH_LEVEL_ALLIGNORE) &&
1947 (0 != sh_util_obscurename (ShDFLevel[SH_ERR_T_NAME],
1948 fileName, S_FALSE)))
1949 {
1950 if ((dirName != NULL) && (dirName[0] == '/') && (dirName[1] == '\0'))
1951 {
1952 tmpname = sh_util_safe_name (fileName);
1953 sh_error_handle (ShDFLevel[SH_ERR_T_NAME], FIL__, __LINE__, 0,
1954 MSG_FI_OBSC2,
1955 "", tmpname);
1956 SH_FREE(tmpname);
1957 }
1958 else
1959 {
1960 tmpdir = sh_util_safe_name (dirName);
1961 tmpname = sh_util_safe_name (fileName);
1962 sh_error_handle (ShDFLevel[SH_ERR_T_NAME], FIL__, __LINE__, 0,
1963 MSG_FI_OBSC2,
1964 tmpdir, tmpname);
1965 SH_FREE(tmpname);
1966 SH_FREE(tmpdir);
1967 }
1968 }
1969
1970 /* sh_files_fullpath accepts NULL fileName
1971 */
1972 if (0 != sh_files_fullpath (dirName, fileName, fullpath))
1973 {
1974 tmpdir = sh_util_safe_name (dirName);
1975 tmpname = sh_util_safe_name (fileName);
1976 sh_error_handle (ShDFLevel[SH_ERR_T_FILE], FIL__, __LINE__, 0,
1977 MSG_FI_2LONG2,
1978 tmpdir, tmpname);
1979 SH_FREE(tmpname);
1980 SH_FREE(tmpdir);
1981 SL_RETURN(SH_FILE_UNKNOWN, _("sh_files_filecheck"));
1982 }
1983
1984
1985 /* stat the file and determine checksum (if a regular file)
1986 */
1987 sl_strlcpy (theFile.fullpath, fullpath, PATH_MAX);
1988 theFile.check_mask = sh_files_maskof(class);
1989 theFile.reported = (*reported);
1990
1991 TPT(( 0, FIL__, __LINE__, _("msg=<checking file: %s>\n"), fullpath));
1992
1993 status = sh_unix_getinfo ( (class == SH_LEVEL_ALLIGNORE) ?
1994 ShDFLevel[class] : ShDFLevel[SH_ERR_T_FILE],
1995 fileName,
1996 &theFile, fileHash, class);
1997
1998 if (status != 0)
1999 {
2000 TPT(( 0, FIL__, __LINE__, _("msg=<file: %s> status=<%d>\n"),
2001 fullpath, status));
2002 if (class == SH_LEVEL_ALLIGNORE && sh.flag.checkSum != SH_CHECK_INIT)
2003 sh_hash_set_visited_true (fullpath);
2004 SL_RETURN(SH_FILE_UNKNOWN, _("sh_files_filecheck"));
2005 }
2006
2007 if (sig_termfast == 1) {
2008 goto ret_point;
2009 }
2010
2011 /* report
2012 */
2013 if ((flag_err_debug == SL_TRUE) && (theFile.c_mode[0] == '-'))
2014 {
2015 tmpname = sh_util_safe_name (fullpath); /* fixed in 1.5.4 */
2016 sh_error_handle ((-1), FIL__, __LINE__, 0, MSG_FI_CSUM,
2017 fileHash, tmpname);
2018 SH_FREE(tmpname);
2019 }
2020 ++sh.statistics.files_checked;
2021
2022 if ( sh.flag.checkSum == SH_CHECK_INIT && sh.flag.update == S_FALSE )
2023 {
2024 sh_hash_pushdata (&theFile, fileHash);
2025 }
2026 else if (sh.flag.checkSum == SH_CHECK_INIT && sh.flag.update == S_TRUE )
2027 {
2028 if (0 == sh_hash_compdata (class, &theFile, fileHash, NULL, -1))
2029 {
2030 sh_hash_pushdata (&theFile, fileHash);
2031 }
2032 }
2033 else if (sh.flag.checkSum == SH_CHECK_CHECK
2034 /* && theFile.c_mode[0] == '-' */
2035 /* && class != SH_LEVEL_ALLIGNORE */
2036 )
2037 {
2038 sh_hash_compdata (class, &theFile, fileHash, NULL, -1);
2039 }
2040
2041 (*reported) = theFile.reported;
2042
2043 /* reset the access time
2044 */
2045 if (class == SH_LEVEL_NOIGNORE && (theFile.check_mask & MODI_ATM) != 0)
2046 {
2047 utime_buf.actime = (time_t) theFile.atime;
2048 utime_buf.modtime = (time_t) theFile.mtime;
2049#if !defined(O_NOATIME)
2050 retry_aud_utime (FIL__, __LINE__, fullpath, &utime_buf);
2051#endif
2052 }
2053
2054#ifdef HOST_IS_DARWIN
2055 /*
2056 * Check for resource fork
2057 */
2058 if ( (theFile.c_mode[0] != 'd') && (rsrcflag == 0) )
2059 {
2060 int dummy;
2061 static int rsrc_init = 0;
2062 static char rsrc[17];
2063 char testpath[PATH_MAX];
2064
2065 if (rsrc_init == 0) {
2066 sl_strlcpy(rsrc, _("..namedfork/rsrc"), 17);
2067 rsrc_init = 1;
2068 }
2069 sl_strlcpy (testpath, fullpath, PATH_MAX);
2070 sl_strlcat (testpath, "/", PATH_MAX);
2071 sl_strlcat (testpath, rsrc, PATH_MAX);
2072
2073 if (sl_strlen(testpath) == (17 + sl_strlen(fullpath)))
2074 {
2075 if (0 != sh_unix_file_stat (testpath))
2076 {
2077 sh_files_filecheck (class, fullpath, rsrc, &dummy, 1);
2078 }
2079 }
2080 }
2081#else
2082 (void) rsrcflag; /* avoid compiler warning */
2083#endif
2084
2085 ret_point:
2086
2087 switch (theFile.c_mode[0])
2088 {
2089 case '-': SL_RETURN(SH_FILE_REGULAR, _("sh_files_filecheck"));
2090 case 'l': SL_RETURN(SH_FILE_SYMLINK, _("sh_files_filecheck"));
2091 case 'd': SL_RETURN(SH_FILE_DIRECTORY, _("sh_files_filecheck"));
2092 case 'c': SL_RETURN(SH_FILE_CDEV, _("sh_files_filecheck"));
2093 case 'b': SL_RETURN(SH_FILE_BDEV, _("sh_files_filecheck"));
2094 case '|': SL_RETURN(SH_FILE_FIFO, _("sh_files_filecheck"));
2095 case 'D': SL_RETURN(SH_FILE_DOOR, _("sh_files_filecheck"));
2096 case 'P': SL_RETURN(SH_FILE_PORT, _("sh_files_filecheck"));
2097 case 's': SL_RETURN(SH_FILE_SOCKET, _("sh_files_filecheck"));
2098 default: SL_RETURN(SH_FILE_UNKNOWN, _("sh_files_filecheck"));
2099 }
2100
2101 /* notreached */
2102}
2103
2104/* concatenate statpath = testdir"/"d_name
2105 */
2106static int sh_files_fullpath (char * testdir, char * d_name, char * statpath)
2107{
2108 int llen = 0;
2109
2110 SL_ENTER(_("sh_files_fullpath"));
2111
2112 if (testdir != NULL)
2113 {
2114 if ( (llen = sl_strlen(testdir)) > (PATH_MAX-2) )
2115 SL_RETURN((-1),_("sh_files_fullpath"));
2116 sl_strlcpy(statpath, testdir, PATH_MAX - 1);
2117 }
2118 if (d_name != NULL)
2119 {
2120 if (llen > 1 || statpath[0] != '/')
2121 sl_strlcat(statpath, "/", PATH_MAX);
2122 if ((sl_strlen(d_name) + sl_strlen(statpath)) >= PATH_MAX)
2123 SL_RETURN((-1),_("sh_files_fullpath"));
2124 sl_strlcat(statpath, d_name, PATH_MAX);
2125 }
2126 if (statpath == NULL)
2127 SL_RETURN((-1),_("sh_files_fullpath"));
2128 SL_RETURN((0),_("sh_files_fullpath"));
2129}
2130
2131
2132/* -----------------------------------
2133 *
2134 * The following two routines serve to
2135 * verify that the user has selected
2136 * a proper setup for file policies.
2137 *
2138 * -----------------------------------
2139 */
2140static int check_file(char * name)
2141{
2142 dirstack_t * pfilL;
2143 zAVLCursor cursor;
2144
2145 SL_ENTER(_("check_file"));
2146
2147 if (SH_FILE_DIRECTORY == sh_unix_get_ftype(name))
2148 SL_RETURN(0, _("check_file"));
2149
2150 for (pfilL = (dirstack_t *) zAVLFirst (&cursor, zfileList); pfilL;
2151 pfilL = (dirstack_t *) zAVLNext (&cursor))
2152 {
2153 if (0 == strcmp(name, pfilL->name) &&
2154 (pfilL->check_mask & MODI_ATM) == 0 &&
2155 (pfilL->check_mask & MODI_CTM) == 0 &&
2156 (pfilL->check_mask & MODI_MTM) == 0)
2157 SL_RETURN(0, _("check_file"));
2158 }
2159 SL_RETURN((-1), _("check_file"));
2160}
2161
2162int sh_files_test_setup_int (zAVLTree * tree)
2163{
2164 int dlen, flen;
2165 zAVLCursor cursor1;
2166 zAVLCursor cursor2;
2167
2168 dirstack_t * pdirL;
2169 dirstack_t * pfilL;
2170
2171 SL_ENTER(_("sh_files_test_setup"));
2172
2173 for (pdirL = (dirstack_t *) zAVLFirst (&cursor1, tree); pdirL;
2174 pdirL = (dirstack_t *) zAVLNext (&cursor1))
2175 {
2176 dlen = strlen(pdirL->name);
2177
2178 for (pfilL = (dirstack_t *) zAVLFirst (&cursor2, zfileList); pfilL;
2179 pfilL = (dirstack_t *) zAVLNext (&cursor2))
2180 {
2181 flen = strlen(pfilL->name);
2182
2183 /* check whether file is in tree of dir
2184 */
2185 if ((pfilL->class == SH_LEVEL_READONLY) ||
2186 (pfilL->class == SH_LEVEL_NOIGNORE))
2187 {
2188 ; /* do nothing */
2189 }
2190 else
2191 {
2192 if ((flen > (dlen+1)) &&
2193 (pfilL->name[dlen] == '/') &&
2194 (NULL == strchr(&(pfilL->name[dlen+1]), '/')) && /*30-5-01*/
2195 (0 == strncmp(pfilL->name, pdirL->name, dlen)))
2196 {
2197 if ((pdirL->check_mask & MODI_ATM) != 0 ||
2198 (pdirL->check_mask & MODI_MTM) != 0 ||
2199 (pdirL->check_mask & MODI_CTM) != 0)
2200 {
2201 if (check_file (pdirL->name) != 0)
2202 sh_error_handle ((-1), FIL__, __LINE__, 0, MSG_FI_COLL,
2203 pdirL->name, pfilL->name);
2204 }
2205 }
2206 }
2207 }
2208 }
2209
2210 SL_RETURN((0), _("sh_files_test_setup"));
2211}
2212
2213int sh_files_test_double (zAVLTree * firstList, zAVLTree * secondList)
2214{
2215 int count;
2216 int retval = 0;
2217
2218 zAVLCursor cursor;
2219
2220 dirstack_t * first;
2221
2222 for (first = (dirstack_t *) zAVLFirst (&cursor, firstList); first;
2223 first = (dirstack_t *) zAVLNext (&cursor))
2224 {
2225
2226 if (NULL != zAVLSearch(secondList, first->name))
2227 {
2228 ++count;
2229 sh_error_handle ((-1), FIL__, __LINE__, 0, MSG_FI_DOUBLE,
2230 first->name);
2231 retval = 1;
2232 }
2233 }
2234 return retval;
2235}
2236
2237extern void aud_exit (char * file, int line, int fd);
2238
2239int sh_files_test_setup ()
2240{
2241 int retval = 0;
2242
2243 /* Test for modifications allowed in ReadOnly directory
2244 */
2245 sh_files_test_setup_int (zdirListOne);
2246 sh_files_test_setup_int (zdirListTwo);
2247
2248 /* Test for files/dirz defined twice
2249 */
2250 retval = sh_files_test_double (zdirListOne, zdirListTwo);
2251 if (retval != 0)
2252 aud_exit(FIL__, __LINE__, EXIT_FAILURE);
2253
2254 retval = sh_files_test_double (zdirListTwo, zdirListOne);
2255 if (retval != 0)
2256 aud_exit(FIL__, __LINE__, EXIT_FAILURE);
2257
2258
2259 /*
2260 retval = sh_files_test_double (zfileList, NULL);
2261 if (retval != 0)
2262 aud_exit(FIL__, __LINE__, EXIT_FAILURE);
2263 */
2264 return 0;
2265}
2266
2267#endif
Note: See TracBrowser for help on using the repository browser.