source: trunk/src/sh_files.c@ 27

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

Support for server-to-server relay and more user policies

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