source: trunk/src/sh_files.c@ 43

Last change on this file since 43 was 40, checked in by rainer, 19 years ago

Fix for tickets #13, #14, #15, #16, #17

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