source: trunk/src/sh_files.c@ 131

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

Use thread-safe libc functions.

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