1 /***********************************************************************
3 * This software is part of the ast package *
4 * Copyright (c) 1985-2010 AT&T Intellectual Property *
5 * and is licensed under the *
6 * Common Public License, Version 1.0 *
7 * by AT&T Intellectual Property *
9 * A copy of the License is available at *
10 * http://www.opensource.org/licenses/cpl1.0.txt *
11 * (with md5 checksum 059e8cd6165cb4c31e351f2b69388fd9) *
13 * Information and Software Systems Research *
17 * Glenn Fowler <gsf@research.att.com> *
18 * David Korn <dgk@research.att.com> *
19 * Phong Vo <kpv@research.att.com> *
21 ***********************************************************************/
27 * return 1 if path exisis
28 * maintains a cache to minimize stat(2) calls
29 * path is modified in-place but restored on return
30 * path components checked in pairs to cut stat()'s
31 * in half by checking ENOTDIR vs. ENOENT
32 * case ignorance infection unavoidable here
49 pathexists(char* path
, int mode
)
60 int (*cmp
)(const char*, const char*);
65 e
= (c
= *path
) == '/' ? path
+ 1 : path
;
66 cmp
= strchr(astconf("PATH_ATTRIBUTES", path
, NiL
), 'c') ? strcasecmp
: strcmp
;
67 if ((ast
.locale
.set
& (AST_LC_debug
|AST_LC_find
)) == (AST_LC_debug
|AST_LC_find
))
68 sfprintf(sfstderr
, "locale test %s\n", path
);
72 for (s
= e
; *e
&& *e
!= '/'; e
++);
75 for (t
= p
->tree
; t
&& (*cmp
)(s
, t
->name
); t
= t
->next
);
78 if (!(t
= newof(0, Tree_t
, 1, strlen(s
))))
89 for (s
= ee
= e
+ 1; *ee
&& *ee
!= '/'; ee
++);
95 if ((ast
.locale
.set
& (AST_LC_debug
|AST_LC_find
)) == (AST_LC_debug
|AST_LC_find
))
96 sfprintf(sfstderr
, "locale stat %s\n", path
);
102 if (!x
|| errno
== ENOENT
)
103 t
->mode
= PATH_READ
|PATH_EXECUTE
;
104 if (!(p
= newof(0, Tree_t
, 1, strlen(s
))))
119 if (st
.st_mode
& (S_IRUSR
|S_IRGRP
|S_IROTH
))
120 t
->mode
|= PATH_READ
;
121 if (st
.st_mode
& (S_IWUSR
|S_IWGRP
|S_IWOTH
))
122 t
->mode
|= PATH_WRITE
;
123 if (st
.st_mode
& (S_IXUSR
|S_IXGRP
|S_IXOTH
))
124 t
->mode
|= PATH_EXECUTE
;
125 if (!S_ISDIR(st
.st_mode
))
126 t
->mode
|= PATH_REGULAR
;
129 if (!t
->mode
|| c
&& (t
->mode
& PATH_REGULAR
))
132 mode
&= (PATH_READ
|PATH_WRITE
|PATH_EXECUTE
|PATH_REGULAR
);
133 return (t
->mode
& mode
) == mode
;