source: trunk/src/sh_files.c@ 79

Last change on this file since 79 was 78, checked in by rainer, 18 years ago

Fix for ticket #41 (unable to deactivate processcheck), and minor code cleanup.

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