source: trunk/src/sh_files.c@ 47

Last change on this file since 47 was 46, checked in by rainer, 18 years ago

Fix x86_64 build failure with gcc 4.x (as well as some gcc 4.x warnings)

File size: 53.3 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 p = sh_util_safe_name (epath);
725 sh_error_handle (SH_ERR_ERR, FIL__, __LINE__, errnum, MSG_FI_GLOB,
726 sh_error_message (errnum), p);
727 SH_FREE(p);
728
729 SL_RETURN(0, _("sh_files_globerr"));
730}
731
732/* #ifdef HAVE_GLOB_H
733 */
734#endif
735
736int sh_files_push_file_int (int class, const char * str_s, size_t len)
737{
738 dirstack_t * new_item_ptr;
739 char * fileName;
740 int ret;
741
742 SL_ENTER(_("sh_files_push_file_int"));
743
744 fileName = SH_ALLOC(len+1);
745 sl_strlcpy(fileName, str_s, len+1);
746
747 new_item_ptr = (dirstack_t *) SH_ALLOC (sizeof(dirstack_t));
748
749 new_item_ptr->name = fileName;
750 new_item_ptr->class = class;
751 new_item_ptr->check_mask = sh_files_maskof(class);
752 new_item_ptr->rdepth = 0;
753 new_item_ptr->checked = S_FALSE;
754 new_item_ptr->reported = S_FALSE;
755 new_item_ptr->childs_checked = S_FALSE;
756
757 if (zfileList == NULL)
758 {
759 zfileList = zAVLAllocTree (zdirstack_key);
760 if (zfileList == NULL)
761 {
762 (void) safe_logger (0, 0, NULL);
763 aud__exit(FIL__, __LINE__, EXIT_FAILURE);
764 }
765 }
766
767 ret = zAVLInsert (zfileList, new_item_ptr);
768
769 if (-1 == ret)
770 {
771 (void) safe_logger (0, 0, NULL);
772 aud__exit(FIL__, __LINE__, EXIT_FAILURE);
773 }
774 if (3 == ret)
775 sh_error_handle ((-1), FIL__, __LINE__, 0, MSG_FI_DOUBLE,
776 fileName);
777
778 SL_RETURN(0, _("sh_files_push_file_int"));
779}
780
781
782static int sh_files_pushfile (int class, const char * str_s)
783{
784 size_t len;
785 char * tmp;
786 char * p;
787#ifdef HAVE_GLOB_H
788 int globstatus = -1;
789 unsigned int gloop;
790 glob_t pglob;
791#endif
792
793 static int reject = 0;
794
795 SL_ENTER(_("sh_files_pushfile"));
796
797 if (reject == 1)
798 SL_RETURN((-1),_("sh_files_pushfile"));
799
800 /* if we push a filename from the command line, make sure it
801 * is the only one -- and will stay the only one
802 */
803 if (sh.flag.opts == 1)
804 {
805 sh_files_delfilestack ();
806 sh_files_deldirstack ();
807 reject = 1;
808 }
809
810 if (str_s == NULL)
811 SL_RETURN((-1),_("sh_files_pushfile"));
812
813 len = sl_strlen(str_s);
814
815 if (len >= PATH_MAX)
816 {
817 /* Name too long
818 */
819 tmp = sh_util_safe_name (str_s);
820 sh_error_handle ((-1), FIL__, __LINE__, 0, MSG_FI_2LONG,
821 tmp);
822 SH_FREE(tmp);
823 SL_RETURN((-1),_("sh_files_pushfile"));
824 }
825 else if (len < 1)
826 {
827 /* Should not happen (str_s == NULL caught further above)
828 */
829 SL_RETURN((-1),_("sh_files_pushfile"));
830 }
831 else if (str_s[0] != '/')
832 {
833 /* Not an absolute path
834 */
835 tmp = sh_util_safe_name (str_s);
836 sh_error_handle ((-1), FIL__, __LINE__, 0, MSG_FI_NOPATH,
837 tmp);
838 SH_FREE(tmp);
839 SL_RETURN((-1),_("sh_files_pushfile"));
840 }
841 else
842 {
843 /* remove a terminating '/', take care of the
844 * special case of the root directory.
845 */
846 p = sh_util_strdup (str_s);
847 if (p[len-1] == '/' && len > 1)
848 {
849 p[len-1] = '\0';
850 --len;
851 }
852
853 }
854
855#ifdef HAVE_GLOB_H
856 if (0 == sh_files_has_metachar(p))
857 {
858 sh_files_push_file_int (class, p, len);
859 }
860 else
861 {
862 pglob.gl_offs = 0;
863 globstatus = glob (p, 0, sh_files_globerr, &pglob);
864
865 if (globstatus == 0 && pglob.gl_pathc > 0)
866 {
867 for (gloop = 0; gloop < (unsigned int) pglob.gl_pathc; ++gloop)
868 sh_files_push_file_int (class, pglob.gl_pathv[gloop],
869 sl_strlen(pglob.gl_pathv[gloop]));
870 }
871 else
872 {
873 tmp = sh_util_safe_name (p);
874
875 if (pglob.gl_pathc == 0
876#ifdef GLOB_NOMATCH
877 || globstatus == GLOB_NOMATCH
878#endif
879 )
880 sh_error_handle (SH_ERR_ERR, FIL__, __LINE__,
881 globstatus, MSG_FI_GLOB,
882 _("No matches found"), tmp);
883#ifdef GLOB_NOSPACE
884 else if (globstatus == GLOB_NOSPACE)
885 sh_error_handle (SH_ERR_ERR, FIL__, __LINE__,
886 globstatus, MSG_FI_GLOB,
887 _("Out of memory"), tmp);
888#endif
889#ifdef GLOB_ABORTED
890 else if (globstatus == GLOB_ABORTED)
891 sh_error_handle (SH_ERR_ERR, FIL__, __LINE__,
892 globstatus, MSG_FI_GLOB,
893 _("Read error"), tmp);
894#endif
895 else
896 sh_error_handle (SH_ERR_ERR, FIL__, __LINE__,
897 globstatus, MSG_FI_GLOB,
898 _("Unknown error"), tmp);
899
900 SH_FREE(tmp);
901
902 }
903
904 globfree(&pglob);
905 }
906
907#else
908 sh_files_push_file_int (class, p, len);
909#endif
910
911 SH_FREE(p);
912 SL_RETURN((0),_("sh_files_pushfile"));
913}
914
915
916/* ------ directories ----- */
917
918int sh_files_is_allignore_int (char * str, zAVLTree * tree)
919{
920 dirstack_t * ptr;
921
922 SL_ENTER(_("sh_files_is_allignore"));
923
924 if (tree)
925 {
926 ptr = zAVLSearch(tree, str);
927 if (ptr)
928 {
929 if (ptr->class == SH_LEVEL_ALLIGNORE)
930 SL_RETURN( 1, _("sh_files_is_allignore"));
931 else
932 SL_RETURN( 0, _("sh_files_is_allignore"));
933 }
934 }
935 SL_RETURN( 0, _("sh_files_is_allignore"));
936}
937
938int sh_files_is_allignore (char * str)
939{
940 if (1 == sh_files_is_allignore_int(str, zdirListOne))
941 return 1;
942 if (NULL == zdirListTwo)
943 return 0;
944 return sh_files_is_allignore_int(str, zdirListTwo);
945}
946
947unsigned long sh_dirs_chk (int which)
948{
949 zAVLTree * tree;
950 zAVLCursor cursor;
951 dirstack_t * ptr;
952 dirstack_t * dst_ptr;
953 int status;
954 unsigned long dcount = 0;
955 char * tmp;
956
957 SL_ENTER(_("sh_dirs_chk"));
958
959 if (which == 1)
960 tree = zdirListOne;
961 else
962 tree = zdirListTwo;
963
964 for (ptr = (dirstack_t *) zAVLFirst(&cursor, tree); ptr;
965 ptr = (dirstack_t *) zAVLNext(&cursor))
966 {
967 if (sig_urgent > 0) {
968 SL_RETURN(dcount, _("sh_dirs_chk"));
969 }
970
971 if (ptr->checked == S_FALSE)
972 {
973 /* 28 Aug 2001 check the top level directory
974 */
975 status = S_FALSE;
976 dst_ptr = zAVLSearch(zfileList, ptr->name);
977 if (dst_ptr)
978 {
979 if (dst_ptr->checked == S_FALSE)
980 {
981 BREAKEXIT(sh_files_filecheck);
982 sh_files_filecheck (dst_ptr->class, ptr->name,
983 NULL, &status, 0);
984 dst_ptr->checked = S_TRUE;
985 status = S_TRUE;
986 }
987 else
988 {
989 status = S_TRUE;
990 }
991 }
992
993 if (status == S_FALSE)
994 sh_files_filecheck (ptr->class, ptr->name, NULL, &status, 0);
995
996 BREAKEXIT(sh_files_checkdir);
997 status = sh_files_checkdir (ptr->class, ptr->rdepth, ptr->name,
998 ptr->name);
999
1000 if (status < 0 && ptr->reported == S_FALSE)
1001 {
1002 /* directory is missing
1003 */
1004 if (S_FALSE == sh_ignore_chk_del(ptr->name))
1005 {
1006 if (0 != hashreport_missing(ptr->name,
1007 (ptr->class == SH_LEVEL_ALLIGNORE) ?
1008 ShDFLevel[ptr->class] :
1009 ShDFLevel[SH_ERR_T_DIR])) {
1010 tmp = sh_util_safe_name (ptr->name);
1011 sh_error_handle ((ptr->class == SH_LEVEL_ALLIGNORE) ?
1012 ShDFLevel[ptr->class] :
1013 ShDFLevel[SH_ERR_T_DIR], FIL__, __LINE__,
1014 0, MSG_FI_MISS, tmp);
1015 SH_FREE(tmp);
1016 }
1017 }
1018 if (sh.flag.reportonce == S_TRUE)
1019 ptr->reported = S_TRUE;
1020 }
1021 else
1022 {
1023 /* exists (status >= 0), but was missing (reported == TRUE)
1024 */
1025 if (status >= 0 && ptr->reported == S_TRUE)
1026 {
1027 ptr->reported = S_FALSE;
1028#if 0
1029 /* obsoleted (really?) by the mandatory sh_files_filecheck()
1030 * above, which will catch missing directories anyway
1031 */
1032 tmp = sh_util_safe_name (ptr->name);
1033 sh_error_handle ((ptr->class == SH_LEVEL_ALLIGNORE) ?
1034 ShDFLevel[ptr->class] :
1035 ShDFLevel[SH_ERR_T_DIR],
1036 FIL__, __LINE__, 0, MSG_FI_ADD,
1037 tmp);
1038 SH_FREE(tmp);
1039#endif
1040 }
1041 else if (status == SH_FILE_UNKNOWN)
1042 {
1043 /* catchall
1044 */
1045 tmp = sh_util_safe_name (ptr->name);
1046 sh_error_handle (SH_ERR_INFO, FIL__, __LINE__, 0,
1047 MSG_FI_FAIL,
1048 tmp);
1049 SH_FREE(tmp);
1050 if (sh.flag.checkSum != SH_CHECK_INIT)
1051 sh_hash_set_visited_true(ptr->name);
1052 }
1053
1054 ++dcount;
1055 }
1056 ptr->checked = S_TRUE;
1057 ptr->childs_checked = S_TRUE;
1058 }
1059
1060 if (sig_urgent > 0) {
1061 SL_RETURN(dcount, _("sh_dirs_chk"));
1062 }
1063
1064 }
1065 SL_RETURN(dcount, _("sh_dirs_chk"));
1066}
1067
1068int sh_files_pushdir_prelink (const char * str_s)
1069{
1070 return (sh_files_pushdir (SH_LEVEL_PRELINK, str_s));
1071}
1072
1073int sh_files_pushdir_user0 (const char * str_s)
1074{
1075 return (sh_files_pushdir (SH_LEVEL_USER0, str_s));
1076}
1077
1078int sh_files_pushdir_user1 (const char * str_s)
1079{
1080 return (sh_files_pushdir (SH_LEVEL_USER1, str_s));
1081}
1082
1083int sh_files_pushdir_user2 (const char * str_s)
1084{
1085 return (sh_files_pushdir (SH_LEVEL_USER2, str_s));
1086}
1087
1088int sh_files_pushdir_user3 (const char * str_s)
1089{
1090 return (sh_files_pushdir (SH_LEVEL_USER3, str_s));
1091}
1092
1093int sh_files_pushdir_user4 (const char * str_s)
1094{
1095 return (sh_files_pushdir (SH_LEVEL_USER4, str_s));
1096}
1097
1098int sh_files_pushdir_attr (const char * str_s)
1099{
1100 return (sh_files_pushdir (SH_LEVEL_ATTRIBUTES, str_s));
1101}
1102
1103int sh_files_pushdir_ro (const char * str_s)
1104{
1105 return (sh_files_pushdir (SH_LEVEL_READONLY, str_s));
1106}
1107
1108int sh_files_pushdir_log (const char * str_s)
1109{
1110 return (sh_files_pushdir (SH_LEVEL_LOGFILES, str_s));
1111}
1112
1113int sh_files_pushdir_glog (const char * str_s)
1114{
1115 return (sh_files_pushdir (SH_LEVEL_LOGGROW, str_s));
1116}
1117
1118int sh_files_pushdir_noig (const char * str_s)
1119{
1120 return (sh_files_pushdir (SH_LEVEL_NOIGNORE, str_s));
1121}
1122
1123int sh_files_pushdir_allig (const char * str_s)
1124{
1125 return (sh_files_pushdir (SH_LEVEL_ALLIGNORE, str_s));
1126}
1127
1128static int which_dirList = 1;
1129
1130int set_dirList (int which)
1131{
1132 if (which == 2)
1133 which_dirList = 2;
1134 else
1135 which_dirList = 1;
1136 return 0;
1137}
1138
1139int sh_files_push_dir_int (int class, char * tail, size_t len, int rdepth)
1140{
1141 zAVLTree * tree;
1142 dirstack_t * new_item_ptr;
1143 char * dirName;
1144 int ret;
1145
1146 SL_ENTER(_("sh_files_push_dir_int"));
1147
1148 dirName = SH_ALLOC(len+1);
1149 sl_strlcpy(dirName, tail, len+1);
1150
1151 new_item_ptr = (dirstack_t * ) SH_ALLOC (sizeof(dirstack_t));
1152
1153 new_item_ptr->name = dirName;
1154 new_item_ptr->class = class;
1155 new_item_ptr->check_mask = sh_files_maskof(class);
1156 new_item_ptr->rdepth = rdepth;
1157 new_item_ptr->checked = S_FALSE;
1158 new_item_ptr->reported = S_FALSE;
1159 new_item_ptr->childs_checked = S_FALSE;
1160
1161 if (which_dirList == 1)
1162 {
1163 tree = zdirListOne;
1164 }
1165 else
1166 {
1167 tree = zdirListTwo;
1168 }
1169
1170 if (tree == NULL)
1171 {
1172 tree = zAVLAllocTree (zdirstack_key);
1173 if (tree == NULL)
1174 {
1175 (void) safe_logger (0, 0, NULL);
1176 aud__exit(FIL__, __LINE__, EXIT_FAILURE);
1177 }
1178 if (which_dirList == 1)
1179 zdirListOne = tree;
1180 else
1181 zdirListTwo = tree;
1182 }
1183
1184 ret = zAVLInsert (tree, new_item_ptr);
1185
1186 if (-1 == ret)
1187 {
1188 (void) safe_logger (0, 0, NULL);
1189 aud__exit(FIL__, __LINE__, EXIT_FAILURE);
1190 }
1191 if (3 == ret)
1192 sh_error_handle ((-1), FIL__, __LINE__, 0, MSG_FI_DOUBLE,
1193 dirName);
1194
1195 SL_RETURN(0, _("sh_files_push_dir_int"));
1196}
1197
1198static int sh_files_pushdir (int class, const char * str_s)
1199{
1200 char * tmp;
1201 size_t len;
1202 int rdepth = 0;
1203 char * tail = NULL;
1204 char * p;
1205
1206#ifdef HAVE_GLOB_H
1207 glob_t pglob;
1208 int globstatus = -1;
1209 unsigned int gloop;
1210#endif
1211
1212 SL_ENTER(_("sh_files_pushdir"));
1213
1214 if (sh.flag.opts == 1) {
1215 sh_files_delfilestack ();
1216 sh_files_deldirstack ();
1217 }
1218
1219 if (str_s == NULL)
1220 SL_RETURN((-1), _("sh_files_pushdir"));
1221
1222 p = sh_util_strdup (str_s);
1223
1224 if (p[0] != '/')
1225 {
1226 rdepth = strtol(p, &tail, 10);
1227 if (tail == p)
1228 {
1229 SH_FREE(p);
1230 SL_RETURN((-1), _("sh_files_pushdir"));
1231 }
1232 }
1233 else
1234 tail = p;
1235
1236
1237 if (rdepth < (-1) || tail == p || rdepth > 99)
1238 rdepth = (-2);
1239
1240 len = sl_strlen(tail);
1241
1242 if (len >= PATH_MAX)
1243 {
1244 tmp = sh_util_safe_name (tail);
1245 sh_error_handle ((-1), FIL__, __LINE__, 0, MSG_FI_2LONG,
1246 tmp);
1247 SH_FREE(tmp);
1248 SH_FREE(p);
1249 SL_RETURN((-1), _("sh_files_pushdir"));
1250 }
1251 else if (len < 1)
1252 {
1253 SH_FREE(p);
1254 SL_RETURN((-1), _("sh_files_pushdir"));
1255 }
1256 else if (tail[0] != '/')
1257 {
1258 tmp = sh_util_safe_name (tail);
1259 sh_error_handle ((-1), FIL__, __LINE__, 0, MSG_FI_NOPATH,
1260 tmp);
1261 SH_FREE(tmp);
1262 SH_FREE(p);
1263 SL_RETURN((-1), _("sh_files_pushdir"));
1264 }
1265 else
1266 {
1267
1268 if (tail[len-1] == '/' && len > 1)
1269 {
1270 tail[len-1] = '\0';
1271 --len;
1272 }
1273
1274 }
1275
1276#ifdef HAVE_GLOB_H
1277 if (0 == sh_files_has_metachar(tail))
1278 {
1279 sh_files_push_dir_int (class, tail, len, rdepth);
1280 }
1281 else
1282 {
1283 pglob.gl_offs = 0;
1284 globstatus = glob (tail, 0, sh_files_globerr, &pglob);
1285
1286 if (globstatus == 0 && pglob.gl_pathc > 0)
1287 {
1288 for (gloop = 0; gloop < (unsigned int) pglob.gl_pathc; ++gloop)
1289 sh_files_push_dir_int (class,
1290 pglob.gl_pathv[gloop],
1291 sl_strlen(pglob.gl_pathv[gloop]),
1292 rdepth);
1293 }
1294 else
1295 {
1296 tmp = sh_util_safe_name (tail);
1297
1298 if (pglob.gl_pathc == 0
1299#ifdef GLOB_NOMATCH
1300 || globstatus == GLOB_NOMATCH
1301#endif
1302 )
1303 sh_error_handle (SH_ERR_ERR, FIL__, __LINE__,
1304 globstatus, MSG_FI_GLOB,
1305 _("No matches found"), tmp);
1306#ifdef GLOB_NOSPACE
1307 else if (globstatus == GLOB_NOSPACE)
1308 sh_error_handle (SH_ERR_ERR, FIL__, __LINE__,
1309 globstatus, MSG_FI_GLOB,
1310 _("Out of memory"), tmp);
1311#endif
1312#ifdef GLOB_ABORTED
1313 else if (globstatus == GLOB_ABORTED)
1314 sh_error_handle (SH_ERR_ERR, FIL__, __LINE__,
1315 globstatus, MSG_FI_GLOB,
1316 _("Read error"), tmp);
1317#endif
1318 else
1319 sh_error_handle (SH_ERR_ERR, FIL__, __LINE__,
1320 globstatus, MSG_FI_GLOB,
1321 _("Unknown error"), tmp);
1322 SH_FREE(tmp);
1323 }
1324
1325 globfree(&pglob);
1326 }
1327#else
1328 sh_files_push_dir_int (class, tail, len, rdepth);
1329#endif
1330
1331 SH_FREE(p);
1332 SL_RETURN((0), _("sh_files_pushdir"));
1333}
1334
1335struct sh_dirent {
1336 /* char sh_d_name[NAME_MAX + 2]; */
1337 char * sh_d_name;
1338 struct sh_dirent * next;
1339};
1340
1341static void kill_sh_dirlist (struct sh_dirent * dirlist)
1342{
1343 struct sh_dirent * this;
1344
1345 while (dirlist)
1346 {
1347 this = dirlist->next;
1348 SH_FREE(dirlist->sh_d_name);
1349 SH_FREE(dirlist);
1350 dirlist = this;
1351 }
1352 return;
1353}
1354
1355/* -- add an entry to a directory listing
1356 */
1357static struct sh_dirent * addto_sh_dirlist (struct dirent * thisEntry,
1358 struct sh_dirent * dirlist)
1359{
1360 struct sh_dirent * this;
1361 size_t len;
1362
1363 if (thisEntry == NULL)
1364 return dirlist;
1365
1366 len = sl_strlen(thisEntry->d_name);
1367 if (len == 0)
1368 return dirlist;
1369 ++len;
1370
1371 this = SH_ALLOC(sizeof(struct sh_dirent));
1372 if (!this)
1373 return dirlist;
1374
1375 this->sh_d_name = SH_ALLOC(len);
1376 sl_strlcpy(this->sh_d_name, thisEntry->d_name, len);
1377
1378 this->next = dirlist;
1379 return this;
1380}
1381
1382static int sh_check_hardlinks = S_TRUE;
1383
1384/* Simply sets our boolean as to whether this check is active
1385 */
1386int sh_files_check_hardlinks (const char * opt)
1387{
1388 int i;
1389 SL_ENTER(_("sh_files_check_hardlinks"));
1390 i = sh_util_flagval(opt, &sh_check_hardlinks);
1391 SL_RETURN(i, _("sh_files_check_hardlinks"));
1392}
1393
1394struct sh_hle_struct {
1395 long offset;
1396 char * path;
1397 struct sh_hle_struct * next;
1398};
1399
1400static struct sh_hle_struct * sh_hl_exc = NULL;
1401
1402int sh_files_hle_reg (const char * str)
1403{
1404 long offset;
1405 size_t len;
1406 char * path;
1407
1408 struct sh_hle_struct * tmp = sh_hl_exc;
1409
1410 SL_ENTER(_("sh_files_hle_reg"));
1411
1412 /* Free the linked list if called with NULL argument
1413 */
1414 if (str == NULL)
1415 {
1416 while (tmp)
1417 {
1418 sh_hl_exc = tmp->next;
1419 SH_FREE(tmp->path);
1420 SH_FREE(tmp);
1421 tmp = sh_hl_exc;
1422 }
1423 sh_hl_exc = NULL;
1424 SL_RETURN(0, _("sh_files_hle_reg"));
1425 }
1426
1427 /* We expect 'offset:/path'
1428 */
1429 offset = strtol(str, &path, 0);
1430 if ((path == NULL) || (*path == '\0') || (*path != ':') || (path[1] != '/'))
1431 {
1432 SL_RETURN(-1, _("sh_files_hle_reg"));
1433 }
1434 ++path;
1435 len = 1 + sl_strlen(path);
1436
1437 tmp = SH_ALLOC(sizeof(struct sh_hle_struct));
1438 tmp->path = SH_ALLOC(len);
1439 sl_strlcpy (tmp->path, path, len);
1440 tmp->offset = offset;
1441 tmp->next = sh_hl_exc;
1442 sh_hl_exc = tmp;
1443
1444 SL_RETURN(0, _("sh_files_hle_reg"));
1445}
1446
1447#if !defined(HOST_IS_DARWIN)
1448static int sh_files_hle_test (int offset, char * path)
1449{
1450 struct sh_hle_struct * tmp = sh_hl_exc;
1451
1452 SL_ENTER(_("sh_files_hle_reg"));
1453
1454 while(tmp)
1455 {
1456 if ((offset == tmp->offset) && (0 == strcmp(path, tmp->path)))
1457 {
1458 SL_RETURN(0, _("sh_files_hle_test"));
1459 }
1460 tmp = tmp->next;
1461 }
1462 SL_RETURN(-1, _("sh_files_hle_test"));
1463}
1464#endif
1465
1466/* -- check a single directory and its content
1467 */
1468static int sh_files_checkdir (int iclass, int idepth, char * iname,
1469 char * relativeName)
1470{
1471 struct sh_dirent * dirlist = NULL;
1472 struct sh_dirent * dirlist_orig = NULL;
1473
1474 DIR * thisDir = NULL;
1475 struct dirent * thisEntry;
1476 int status;
1477 int dummy = S_FALSE;
1478 dir_type theDir;
1479 ShFileType checkit;
1480
1481
1482 file_type theFile;
1483 char * tmpname;
1484 char * tmpcat;
1485
1486 int rdepth = 0;
1487 int class = 0;
1488 int rdepth_next;
1489 int class_next;
1490 int file_class_next;
1491
1492 int checked_flag = S_FALSE;
1493 int cchecked_flag = S_FALSE;
1494
1495 dirstack_t * dst_ptr;
1496 dirstack_t * tmp_ptr;
1497
1498 int hardlink_num = 0;
1499#if !defined(HOST_IS_DARWIN)
1500 size_t len;
1501#endif
1502
1503 SL_ENTER(_("sh_files_checkdir"));
1504
1505 if (sig_urgent > 0) {
1506 SL_RETURN((0), _("sh_files_checkdir"));
1507 }
1508
1509 if (iname == NULL || idepth < (-1))
1510 SL_RETURN((-1), _("sh_files_checkdir"));
1511
1512 if (idepth < 0)
1513 {
1514 /* hash_remove_tree (iname); */
1515 SL_RETURN((0), _("sh_files_checkdir"));
1516 }
1517
1518 rdepth = idepth;
1519 class = iclass;
1520
1521 tmpname = sh_util_safe_name (iname);
1522
1523 /* ---- check for obscure name ----
1524 */
1525 if (iclass != SH_LEVEL_ALLIGNORE)
1526 {
1527 sh_util_obscurename (ShDFLevel[SH_ERR_T_NAME], iname, S_TRUE);
1528 }
1529
1530 if (flag_err_info == SL_TRUE)
1531 {
1532 sh_error_handle ((-1), FIL__, __LINE__, 0, MSG_FI_CHK, tmpname);
1533 }
1534
1535 /* ---- check input ----
1536 */
1537 if ( sl_strlen(iname) >= PATH_MAX)
1538 {
1539 sh_error_handle (ShDFLevel[SH_ERR_T_DIR], FIL__, __LINE__, 0,
1540 MSG_FI_2LONG,
1541 tmpname);
1542 SH_FREE(tmpname);
1543 SL_RETURN((-1), _("sh_files_checkdir"));
1544 }
1545
1546 /* ---- check for absolute path ---- */
1547 if ( iname[0] != '/')
1548 {
1549 sh_error_handle (ShDFLevel[SH_ERR_T_DIR], FIL__, __LINE__, 0,
1550 MSG_FI_NOPATH,
1551 tmpname);
1552 SH_FREE(tmpname);
1553 SL_RETURN((-1), _("sh_files_checkdir"));
1554 }
1555
1556
1557 /* ---- stat the directory ----
1558 */
1559 sl_strlcpy (theFile.fullpath, iname, PATH_MAX);
1560
1561 (void) relativeName;
1562 status = sh_unix_getinfo (ShDFLevel[SH_ERR_T_DIR],
1563 iname,
1564 &theFile, NULL, iclass);
1565
1566 if ((sig_termfast == 1) || (sig_terminate == 1))
1567 {
1568 SL_RETURN((0), _("sh_files_checkdir"));
1569 }
1570
1571 if (status == -1)
1572 {
1573 SH_FREE(tmpname);
1574 SL_RETURN((-1), _("sh_files_checkdir"));
1575 }
1576
1577 if (theFile.c_mode[0] != 'd')
1578 {
1579 sh_error_handle (ShDFLevel[SH_ERR_T_DIR], FIL__, __LINE__, 0,
1580 MSG_FI_NODIR,
1581 tmpname);
1582 SH_FREE(tmpname);
1583 SL_RETURN((-1), _("sh_files_checkdir"));
1584 }
1585
1586 hardlink_num = theFile.hardlinks;
1587
1588
1589 /* ---- open directory for reading ----
1590 *
1591 * opendir() will fail with ENOTDIR if the path has been changed
1592 * to a non-directory in between lstat() and opendir().
1593 */
1594 thisDir = opendir (iname);
1595
1596 if (thisDir == NULL)
1597 {
1598 status = errno;
1599 sh_error_handle (ShDFLevel[SH_ERR_T_DIR], FIL__, __LINE__, 0,
1600 MSG_E_OPENDIR,
1601 sh_error_message (status), tmpname);
1602 SH_FREE(tmpname);
1603
1604 SL_RETURN((-1), _("sh_files_checkdir"));
1605 }
1606
1607 theDir.NumRegular = 0;
1608 theDir.NumDirs = 0;
1609 theDir.NumSymlinks = 0;
1610 theDir.NumFifos = 0;
1611 theDir.NumSockets = 0;
1612 theDir.NumCDev = 0;
1613 theDir.NumBDev = 0;
1614 theDir.NumDoor = 0;
1615 theDir.NumPort = 0;
1616 theDir.NumAll = 0;
1617 theDir.TotalBytes = 0;
1618 sl_strlcpy (theDir.DirPath, iname, PATH_MAX);
1619
1620
1621 /* ---- read ----
1622 */
1623 do {
1624 thisEntry = readdir (thisDir);
1625 if (thisEntry != NULL)
1626 {
1627 ++theDir.NumAll;
1628 if (sl_strcmp (thisEntry->d_name, ".") == 0)
1629 {
1630 ++theDir.NumDirs;
1631 continue;
1632 }
1633 if (sl_strcmp (thisEntry->d_name, "..") == 0)
1634 {
1635 ++theDir.NumDirs;
1636 continue;
1637 }
1638 dirlist = addto_sh_dirlist (thisEntry, dirlist);
1639 }
1640 } while (thisEntry != NULL);
1641
1642 closedir (thisDir);
1643
1644 ++sh.statistics.dirs_checked;
1645
1646 dirlist_orig = dirlist;
1647
1648 do {
1649
1650 /* If the directory is empty, dirlist = NULL
1651 */
1652 if (!dirlist)
1653 break;
1654
1655 if (sig_termfast == 1)
1656 {
1657 SL_RETURN((0), _("sh_files_checkdir"));
1658 }
1659
1660 BREAKEXIT(sh_derr);
1661 if (0 == (rand() % 5))
1662 (void) sh_derr();
1663
1664 /* ---- Check the file. ----
1665 */
1666 tmpcat = SH_ALLOC(PATH_MAX);
1667 sl_strlcpy(tmpcat, iname, PATH_MAX);
1668 if (sl_strlen(tmpcat) > 1 || tmpcat[0] != '/')
1669 sl_strlcat(tmpcat, "/", PATH_MAX);
1670 sl_strlcat(tmpcat, dirlist->sh_d_name, PATH_MAX);
1671
1672 rdepth_next = rdepth - 1;
1673 class_next = class;
1674 file_class_next = class;
1675 checked_flag = -1;
1676 cchecked_flag = -1;
1677
1678 /* Wed Aug 24 2005 compare against dirListOne, dirListTwo
1679 * this fixes the problem that the directory special file
1680 * is checked with the policy of the parent directory
1681 */
1682 dst_ptr = (dirstack_t *) zAVLSearch(zdirListOne, tmpcat);
1683
1684 if (dst_ptr)
1685 {
1686 /* Tue Aug 6 22:13:27 CEST 2002 introduce file_class_next
1687 * this fixes the problem that a policy for the directory
1688 * inode erroneously becomes a policy for the directory itself.
1689 */
1690 file_class_next = dst_ptr->class;
1691 checked_flag = dst_ptr->checked;
1692 cchecked_flag = dst_ptr->childs_checked;
1693 }
1694
1695 if (checked_flag == -1)
1696 {
1697 dst_ptr = (dirstack_t *) zAVLSearch(zdirListTwo, tmpcat);
1698
1699 if (dst_ptr)
1700 {
1701 /* Tue Aug 6 22:13:27 CEST 2002 introduce file_class_next
1702 * this fixes the problem that a policy for the directory
1703 * inode erroneously becomes a policy for the directory itself.
1704 */
1705 file_class_next = dst_ptr->class;
1706 checked_flag = dst_ptr->checked;
1707 cchecked_flag = dst_ptr->childs_checked;
1708 }
1709 }
1710
1711 dst_ptr = (dirstack_t *) zAVLSearch(zfileList, tmpcat);
1712
1713 if (dst_ptr)
1714 {
1715 /* Tue Aug 6 22:13:27 CEST 2002 introduce file_class_next
1716 * this fixes the problem that a policy for the directory
1717 * inode erroneously becomes a policy for the directory itself.
1718 */
1719 file_class_next = dst_ptr->class;
1720 checked_flag = dst_ptr->checked;
1721 /* not set, hence always FALSE */
1722 /* cchecked_flag = dst_ptr->childs_checked; */
1723 }
1724
1725 /* ---- Has been checked already. ----
1726 */
1727 if (checked_flag == S_TRUE && cchecked_flag == S_TRUE)
1728 {
1729 /* Mar 11 2004 get ftype for complete directory count
1730 */
1731 checkit = sh_unix_get_ftype(tmpcat);
1732 if (checkit == SH_FILE_DIRECTORY)
1733 {
1734 ++theDir.NumDirs;
1735 }
1736 SH_FREE(tmpcat);
1737 dirlist = dirlist->next;
1738 continue;
1739 }
1740
1741 /* --- May be true, false, or not found. ---
1742 */
1743 if (checked_flag == S_TRUE)
1744 {
1745 /* -- need only the file type --
1746 */
1747 checkit = sh_unix_get_ftype(tmpcat);
1748 }
1749 else
1750 {
1751 /* -- need to check the file itself --
1752 */
1753 if (dst_ptr && sh.flag.reportonce == S_TRUE)
1754 dummy = dst_ptr->reported;
1755
1756 checkit = sh_files_filecheck (file_class_next,
1757 iname,
1758 dirlist->sh_d_name,
1759 &dummy, 0);
1760
1761 if (dst_ptr && checked_flag == S_FALSE)
1762 dst_ptr->checked = S_TRUE;
1763 /* Thu Mar 7 15:09:40 CET 2002 Propagate the 'reported' flag
1764 */
1765 if (dst_ptr && sh.flag.reportonce == S_TRUE)
1766 dst_ptr->reported = dummy;
1767 }
1768
1769 if (checkit == SH_FILE_REGULAR)
1770 ++theDir.NumRegular;
1771
1772 else if (checkit == SH_FILE_DIRECTORY)
1773 {
1774 ++theDir.NumDirs;
1775 if (rdepth_next >= 0 && cchecked_flag != S_TRUE)
1776 {
1777 rdepth_next = rdepth - 1;
1778
1779 /* check whether the new directory is in the
1780 * list with a recursion depth already defined
1781 */
1782 checked_flag = -1;
1783 cchecked_flag = -1;
1784
1785 tmp_ptr = (dirstack_t *) zAVLSearch(zdirListOne, tmpcat);
1786
1787 if (tmp_ptr)
1788 {
1789 TPT((0, FIL__, __LINE__,
1790 _("msg=<%s -> recursion depth %d\n>"),
1791 tmp_ptr->name, tmp_ptr->rdepth));
1792 rdepth_next = tmp_ptr->rdepth;
1793 class_next = tmp_ptr->class;
1794 /* 28. Aug 2001 reversed
1795 */
1796 cchecked_flag = tmp_ptr->childs_checked;
1797 checked_flag = tmp_ptr->checked;
1798 }
1799
1800 if (checked_flag == -1)
1801 {
1802 tmp_ptr = (dirstack_t *) zAVLSearch(zdirListTwo, tmpcat);
1803
1804 if (tmp_ptr)
1805 {
1806 TPT((0, FIL__, __LINE__,
1807 _("msg=<%s -> recursion depth %d\n>"),
1808 tmp_ptr->name, tmp_ptr->rdepth));
1809 rdepth_next = tmp_ptr->rdepth;
1810 class_next = tmp_ptr->class;
1811 /* 28. Aug 2001 reversed
1812 */
1813 cchecked_flag = tmp_ptr->childs_checked;
1814 checked_flag = tmp_ptr->checked;
1815 }
1816 }
1817
1818 if (cchecked_flag == S_FALSE)
1819 {
1820 sh_files_checkdir (class_next, rdepth_next, tmpcat,
1821 dirlist->sh_d_name);
1822 tmp_ptr->childs_checked = S_TRUE;
1823 /*
1824 * 04. Feb 2006 avoid double checking
1825 */
1826 tmp_ptr->checked = S_TRUE;
1827 }
1828 else if (checked_flag == -1)
1829 sh_files_checkdir (class_next, rdepth_next, tmpcat,
1830 dirlist->sh_d_name);
1831
1832 }
1833 }
1834
1835 else if (checkit == SH_FILE_SYMLINK) ++theDir.NumSymlinks;
1836 else if (checkit == SH_FILE_FIFO) ++theDir.NumFifos;
1837 else if (checkit == SH_FILE_SOCKET) ++theDir.NumSockets;
1838 else if (checkit == SH_FILE_CDEV) ++theDir.NumCDev;
1839 else if (checkit == SH_FILE_BDEV) ++theDir.NumBDev;
1840 else if (checkit == SH_FILE_DOOR) ++theDir.NumDoor;
1841 else if (checkit == SH_FILE_PORT) ++theDir.NumPort;
1842
1843 SH_FREE(tmpcat);
1844
1845 if ((sig_termfast == 1) || (sig_terminate == 1))
1846 {
1847 SL_RETURN((0), _("sh_files_checkdir"));
1848 }
1849
1850 dirlist = dirlist->next;
1851
1852 if (dst_ptr)
1853 dst_ptr->childs_checked = S_TRUE;
1854
1855 } while (dirlist != NULL);
1856
1857 if (flag_err_info == SL_TRUE)
1858 {
1859 sh_error_handle ((-1), FIL__, __LINE__, 0, MSG_FI_DSUM,
1860 theDir.NumDirs,
1861 theDir.NumRegular,
1862 theDir.NumSymlinks,
1863 theDir.NumFifos,
1864 theDir.NumSockets,
1865 theDir.NumCDev,
1866 theDir.NumBDev);
1867 }
1868
1869 kill_sh_dirlist (dirlist_orig);
1870
1871#if !defined(HOST_IS_DARWIN)
1872 /*
1873 * Hardlink check; not done on MacOS X because of resource forks
1874 */
1875 if ((sh_check_hardlinks == S_TRUE) && (hardlink_num != theDir.NumDirs))
1876 {
1877 if (0 != sh_files_hle_test(hardlink_num-theDir.NumDirs, iname))
1878 {
1879 len = strlen(tmpname);
1880 if (sl_ok_adds(len, 256))
1881 len += 256;
1882 tmpcat = SH_ALLOC(len);
1883 sl_snprintf(tmpcat, len,
1884 _("%s: subdirectory count (%d) != hardlinks (%d)"),
1885 tmpname, theDir.NumDirs, hardlink_num);
1886 sh_error_handle (ShDFLevel[SH_ERR_T_DIR], FIL__, __LINE__, 0,
1887 MSG_E_SUBGEN, tmpcat, _("sh_files_checkdir"));
1888 SH_FREE(tmpcat);
1889 }
1890 }
1891#endif
1892
1893 SH_FREE(tmpname);
1894
1895 SL_RETURN((0), _("sh_files_checkdir"));
1896}
1897
1898int get_the_fd (SL_TICKET ticket);
1899
1900
1901static ShFileType sh_files_filecheck (int class, char * dirName,
1902 char * infileName,
1903 int * reported,
1904 int rsrcflag)
1905{
1906 /* 28 Aug 2001 allow NULL fileName
1907 */
1908 char fullpath[PATH_MAX];
1909 char fileHash[2*(KEY_LEN + 1)];
1910 int status;
1911 file_type theFile;
1912 char * tmpdir;
1913 char * tmpname;
1914 char * fileName;
1915 struct utimbuf utime_buf;
1916
1917 SL_ENTER(_("sh_files_filecheck"));
1918
1919 BREAKEXIT(sh_derr);
1920 if (0 == (rand() % 2))
1921 (void) sh_derr();
1922
1923 if (dirName && infileName && (dirName[0] == '/') && (dirName[1] == '\0')
1924 && (infileName[0] == '/') && (infileName[1] == '\0'))
1925 {
1926 fileName = NULL;
1927 }
1928 else
1929 {
1930 fileName = infileName;
1931 }
1932
1933 /* fileName may be NULL if this is a directory
1934 */
1935 if (dirName == NULL /* || fileName == NULL */)
1936 {
1937 sh_error_handle ((-1), FIL__, __LINE__, 0, MSG_FI_NULL);
1938 SL_RETURN(SH_FILE_UNKNOWN, _("sh_files_filecheck"));
1939 }
1940
1941 if ((fileName != NULL) && (class != SH_LEVEL_ALLIGNORE) &&
1942 (0 != sh_util_obscurename (ShDFLevel[SH_ERR_T_NAME],
1943 fileName, S_FALSE)))
1944 {
1945 if ((dirName != NULL) && (dirName[0] == '/') && (dirName[1] == '\0'))
1946 {
1947 tmpname = sh_util_safe_name (fileName);
1948 sh_error_handle (ShDFLevel[SH_ERR_T_NAME], FIL__, __LINE__, 0,
1949 MSG_FI_OBSC2,
1950 "", tmpname);
1951 SH_FREE(tmpname);
1952 }
1953 else
1954 {
1955 tmpdir = sh_util_safe_name (dirName);
1956 tmpname = sh_util_safe_name (fileName);
1957 sh_error_handle (ShDFLevel[SH_ERR_T_NAME], FIL__, __LINE__, 0,
1958 MSG_FI_OBSC2,
1959 tmpdir, tmpname);
1960 SH_FREE(tmpname);
1961 SH_FREE(tmpdir);
1962 }
1963 }
1964
1965 /* sh_files_fullpath accepts NULL fileName
1966 */
1967 if (0 != sh_files_fullpath (dirName, fileName, fullpath))
1968 {
1969 tmpdir = sh_util_safe_name (dirName);
1970 tmpname = sh_util_safe_name (fileName);
1971 sh_error_handle (ShDFLevel[SH_ERR_T_FILE], FIL__, __LINE__, 0,
1972 MSG_FI_2LONG2,
1973 tmpdir, tmpname);
1974 SH_FREE(tmpname);
1975 SH_FREE(tmpdir);
1976 SL_RETURN(SH_FILE_UNKNOWN, _("sh_files_filecheck"));
1977 }
1978
1979
1980 /* stat the file and determine checksum (if a regular file)
1981 */
1982 sl_strlcpy (theFile.fullpath, fullpath, PATH_MAX);
1983 theFile.check_mask = sh_files_maskof(class);
1984 theFile.reported = (*reported);
1985
1986 TPT(( 0, FIL__, __LINE__, _("msg=<checking file: %s>\n"), fullpath));
1987
1988 status = sh_unix_getinfo ( (class == SH_LEVEL_ALLIGNORE) ?
1989 ShDFLevel[class] : ShDFLevel[SH_ERR_T_FILE],
1990 fileName,
1991 &theFile, fileHash, class);
1992
1993 if (status != 0)
1994 {
1995 TPT(( 0, FIL__, __LINE__, _("msg=<file: %s> status=<%d>\n"),
1996 fullpath, status));
1997 if (class == SH_LEVEL_ALLIGNORE && sh.flag.checkSum != SH_CHECK_INIT)
1998 sh_hash_set_visited_true (fullpath);
1999 SL_RETURN(SH_FILE_UNKNOWN, _("sh_files_filecheck"));
2000 }
2001
2002 if (sig_termfast == 1) {
2003 goto ret_point;
2004 }
2005
2006 /* report
2007 */
2008 if ((flag_err_debug == SL_TRUE) && (theFile.c_mode[0] == '-'))
2009 {
2010 tmpname = sh_util_safe_name (fullpath); /* fixed in 1.5.4 */
2011 sh_error_handle ((-1), FIL__, __LINE__, 0, MSG_FI_CSUM,
2012 fileHash, tmpname);
2013 SH_FREE(tmpname);
2014 }
2015 ++sh.statistics.files_checked;
2016
2017 if ( sh.flag.checkSum == SH_CHECK_INIT && sh.flag.update == S_FALSE )
2018 {
2019 sh_hash_pushdata (&theFile, fileHash);
2020 }
2021 else if (sh.flag.checkSum == SH_CHECK_INIT && sh.flag.update == S_TRUE )
2022 {
2023 if (0 == sh_hash_compdata (class, &theFile, fileHash, NULL, -1))
2024 {
2025 sh_hash_pushdata (&theFile, fileHash);
2026 }
2027 }
2028 else if (sh.flag.checkSum == SH_CHECK_CHECK
2029 /* && theFile.c_mode[0] == '-' */
2030 /* && class != SH_LEVEL_ALLIGNORE */
2031 )
2032 {
2033 sh_hash_compdata (class, &theFile, fileHash, NULL, -1);
2034 }
2035
2036 (*reported) = theFile.reported;
2037
2038 /* reset the access time
2039 */
2040 if (class == SH_LEVEL_NOIGNORE && (theFile.check_mask & MODI_ATM) != 0)
2041 {
2042 utime_buf.actime = (time_t) theFile.atime;
2043 utime_buf.modtime = (time_t) theFile.mtime;
2044#if !defined(O_NOATIME)
2045 retry_aud_utime (FIL__, __LINE__, fullpath, &utime_buf);
2046#endif
2047 }
2048
2049#ifdef HOST_IS_DARWIN
2050 /*
2051 * Check for resource fork
2052 */
2053 if ( (theFile.c_mode[0] != 'd') && (rsrcflag == 0) )
2054 {
2055 int dummy;
2056 static int rsrc_init = 0;
2057 static char rsrc[17];
2058 char testpath[PATH_MAX];
2059
2060 if (rsrc_init == 0) {
2061 sl_strlcpy(rsrc, _("..namedfork/rsrc"), 17);
2062 rsrc_init = 1;
2063 }
2064 sl_strlcpy (testpath, fullpath, PATH_MAX);
2065 sl_strlcat (testpath, "/", PATH_MAX);
2066 sl_strlcat (testpath, rsrc, PATH_MAX);
2067
2068 if (sl_strlen(testpath) == (17 + sl_strlen(fullpath)))
2069 {
2070 if (0 == sh_unix_file_stat (testpath))
2071 {
2072 sh_files_filecheck (class, fullpath, rsrc, &dummy, 1);
2073 }
2074 }
2075 }
2076#else
2077 (void) rsrcflag; /* avoid compiler warning */
2078#endif
2079
2080 ret_point:
2081
2082 switch (theFile.c_mode[0])
2083 {
2084 case '-': SL_RETURN(SH_FILE_REGULAR, _("sh_files_filecheck"));
2085 case 'l': SL_RETURN(SH_FILE_SYMLINK, _("sh_files_filecheck"));
2086 case 'd': SL_RETURN(SH_FILE_DIRECTORY, _("sh_files_filecheck"));
2087 case 'c': SL_RETURN(SH_FILE_CDEV, _("sh_files_filecheck"));
2088 case 'b': SL_RETURN(SH_FILE_BDEV, _("sh_files_filecheck"));
2089 case '|': SL_RETURN(SH_FILE_FIFO, _("sh_files_filecheck"));
2090 case 'D': SL_RETURN(SH_FILE_DOOR, _("sh_files_filecheck"));
2091 case 'P': SL_RETURN(SH_FILE_PORT, _("sh_files_filecheck"));
2092 case 's': SL_RETURN(SH_FILE_SOCKET, _("sh_files_filecheck"));
2093 default: SL_RETURN(SH_FILE_UNKNOWN, _("sh_files_filecheck"));
2094 }
2095
2096 /* notreached */
2097}
2098
2099/* concatenate statpath = testdir"/"d_name
2100 */
2101static int sh_files_fullpath (char * testdir, char * d_name, char * statpath)
2102{
2103 int llen = 0;
2104
2105 SL_ENTER(_("sh_files_fullpath"));
2106
2107 if (testdir != NULL)
2108 {
2109 if ( (llen = sl_strlen(testdir)) > (PATH_MAX-2) )
2110 SL_RETURN((-1),_("sh_files_fullpath"));
2111 sl_strlcpy(statpath, testdir, PATH_MAX - 1);
2112 }
2113 if (d_name != NULL)
2114 {
2115 if (llen > 1 || statpath[0] != '/')
2116 sl_strlcat(statpath, "/", PATH_MAX);
2117 if ((sl_strlen(d_name) + sl_strlen(statpath)) >= PATH_MAX)
2118 SL_RETURN((-1),_("sh_files_fullpath"));
2119 sl_strlcat(statpath, d_name, PATH_MAX);
2120 }
2121 if (statpath == NULL)
2122 SL_RETURN((-1),_("sh_files_fullpath"));
2123 SL_RETURN((0),_("sh_files_fullpath"));
2124}
2125
2126
2127/* -----------------------------------
2128 *
2129 * The following two routines serve to
2130 * verify that the user has selected
2131 * a proper setup for file policies.
2132 *
2133 * -----------------------------------
2134 */
2135static int check_file(char * name)
2136{
2137 dirstack_t * pfilL;
2138 zAVLCursor cursor;
2139
2140 SL_ENTER(_("check_file"));
2141
2142 if (SH_FILE_DIRECTORY == sh_unix_get_ftype(name))
2143 SL_RETURN(0, _("check_file"));
2144
2145 for (pfilL = (dirstack_t *) zAVLFirst (&cursor, zfileList); pfilL;
2146 pfilL = (dirstack_t *) zAVLNext (&cursor))
2147 {
2148 if (0 == strcmp(name, pfilL->name) &&
2149 (pfilL->check_mask & MODI_ATM) == 0 &&
2150 (pfilL->check_mask & MODI_CTM) == 0 &&
2151 (pfilL->check_mask & MODI_MTM) == 0)
2152 SL_RETURN(0, _("check_file"));
2153 }
2154 SL_RETURN((-1), _("check_file"));
2155}
2156
2157int sh_files_test_setup_int (zAVLTree * tree)
2158{
2159 int dlen, flen;
2160 zAVLCursor cursor1;
2161 zAVLCursor cursor2;
2162
2163 dirstack_t * pdirL;
2164 dirstack_t * pfilL;
2165
2166 SL_ENTER(_("sh_files_test_setup"));
2167
2168 for (pdirL = (dirstack_t *) zAVLFirst (&cursor1, tree); pdirL;
2169 pdirL = (dirstack_t *) zAVLNext (&cursor1))
2170 {
2171 dlen = strlen(pdirL->name);
2172
2173 for (pfilL = (dirstack_t *) zAVLFirst (&cursor2, zfileList); pfilL;
2174 pfilL = (dirstack_t *) zAVLNext (&cursor2))
2175 {
2176 flen = strlen(pfilL->name);
2177
2178 /* check whether file is in tree of dir
2179 */
2180 if ((pfilL->class == SH_LEVEL_READONLY) ||
2181 (pfilL->class == SH_LEVEL_NOIGNORE))
2182 {
2183 ; /* do nothing */
2184 }
2185 else
2186 {
2187 if ((flen > (dlen+1)) &&
2188 (pfilL->name[dlen] == '/') &&
2189 (NULL == strchr(&(pfilL->name[dlen+1]), '/')) && /*30-5-01*/
2190 (0 == strncmp(pfilL->name, pdirL->name, dlen)))
2191 {
2192 if ((pdirL->check_mask & MODI_ATM) != 0 ||
2193 (pdirL->check_mask & MODI_MTM) != 0 ||
2194 (pdirL->check_mask & MODI_CTM) != 0)
2195 {
2196 if (check_file (pdirL->name) != 0)
2197 sh_error_handle ((-1), FIL__, __LINE__, 0, MSG_FI_COLL,
2198 pdirL->name, pfilL->name);
2199 }
2200 }
2201 }
2202 }
2203 }
2204
2205 SL_RETURN((0), _("sh_files_test_setup"));
2206}
2207
2208int sh_files_test_double (zAVLTree * firstList, zAVLTree * secondList)
2209{
2210 int count;
2211 int retval = 0;
2212
2213 zAVLCursor cursor;
2214
2215 dirstack_t * first;
2216
2217 for (first = (dirstack_t *) zAVLFirst (&cursor, firstList); first;
2218 first = (dirstack_t *) zAVLNext (&cursor))
2219 {
2220
2221 if (NULL != zAVLSearch(secondList, first->name))
2222 {
2223 ++count;
2224 sh_error_handle ((-1), FIL__, __LINE__, 0, MSG_FI_DOUBLE,
2225 first->name);
2226 retval = 1;
2227 }
2228 }
2229 return retval;
2230}
2231
2232extern void aud_exit (char * file, int line, int fd);
2233
2234int sh_files_test_setup ()
2235{
2236 int retval = 0;
2237
2238 /* Test for modifications allowed in ReadOnly directory
2239 */
2240 sh_files_test_setup_int (zdirListOne);
2241 sh_files_test_setup_int (zdirListTwo);
2242
2243 /* Test for files/dirz defined twice
2244 */
2245 retval = sh_files_test_double (zdirListOne, zdirListTwo);
2246 if (retval != 0)
2247 aud_exit(FIL__, __LINE__, EXIT_FAILURE);
2248
2249 retval = sh_files_test_double (zdirListTwo, zdirListOne);
2250 if (retval != 0)
2251 aud_exit(FIL__, __LINE__, EXIT_FAILURE);
2252
2253
2254 /*
2255 retval = sh_files_test_double (zfileList, NULL);
2256 if (retval != 0)
2257 aud_exit(FIL__, __LINE__, EXIT_FAILURE);
2258 */
2259 return 0;
2260}
2261
2262#endif
Note: See TracBrowser for help on using the repository browser.