Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
att
GitHub Repository: att/ast
Path: blob/master/src/lib/libast/path/pathexists.c
1810 views
1
/***********************************************************************
2
* *
3
* This software is part of the ast package *
4
* Copyright (c) 1985-2011 AT&T Intellectual Property *
5
* and is licensed under the *
6
* Eclipse Public License, Version 1.0 *
7
* by AT&T Intellectual Property *
8
* *
9
* A copy of the License is available at *
10
* http://www.eclipse.org/org/documents/epl-v10.html *
11
* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
12
* *
13
* Information and Software Systems Research *
14
* AT&T Research *
15
* Florham Park NJ *
16
* *
17
* Glenn Fowler <[email protected]> *
18
* David Korn <[email protected]> *
19
* Phong Vo <[email protected]> *
20
* *
21
***********************************************************************/
22
#pragma prototyped
23
/*
24
* Glenn Fowler
25
* AT&T Research
26
*
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
33
*/
34
35
#include "lclib.h"
36
37
#include <ls.h>
38
#include <error.h>
39
40
typedef struct Tree_s
41
{
42
struct Tree_s* next;
43
struct Tree_s* tree;
44
int mode;
45
char name[1];
46
} Tree_t;
47
48
int
49
pathexists(char* path, int mode)
50
{
51
register char* s;
52
register char* e;
53
register Tree_t* p;
54
register Tree_t* t;
55
register int c;
56
char* ee;
57
int cc;
58
int x;
59
struct stat st;
60
int (*cmp)(const char*, const char*);
61
62
static Tree_t tree;
63
64
t = &tree;
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);
69
while (c)
70
{
71
p = t;
72
for (s = e; *e && *e != '/'; e++);
73
c = *e;
74
*e = 0;
75
for (t = p->tree; t && (*cmp)(s, t->name); t = t->next);
76
if (!t)
77
{
78
if (!(t = newof(0, Tree_t, 1, strlen(s))))
79
{
80
*e = c;
81
return 0;
82
}
83
strcpy(t->name, s);
84
t->next = p->tree;
85
p->tree = t;
86
if (c)
87
{
88
*e = c;
89
for (s = ee = e + 1; *ee && *ee != '/'; ee++);
90
cc = *ee;
91
*ee = 0;
92
}
93
else
94
ee = 0;
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);
97
x = stat(path, &st);
98
if (ee)
99
{
100
e = ee;
101
c = cc;
102
if (!x || errno == ENOENT)
103
t->mode = PATH_READ|PATH_EXECUTE;
104
if (!(p = newof(0, Tree_t, 1, strlen(s))))
105
{
106
*e = c;
107
return 0;
108
}
109
strcpy(p->name, s);
110
p->next = t->tree;
111
t->tree = p;
112
t = p;
113
}
114
if (x)
115
{
116
*e = c;
117
return 0;
118
}
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;
127
}
128
*e++ = c;
129
if (!t->mode || c && (t->mode & PATH_REGULAR))
130
return 0;
131
}
132
mode &= (PATH_READ|PATH_WRITE|PATH_EXECUTE|PATH_REGULAR);
133
return (t->mode & mode) == mode;
134
}
135
136