source: trunk/src/sh_files.c@ 38

Last change on this file since 38 was 34, checked in by rainer, 18 years ago

Code cleanup and minor fixes

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