1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
7 | |
8 | |
9 | |
10 | |
11 | |
12 | |
13 | |
14 | |
15 | |
16 | |
17 | |
18 | |
19 | |
20 | |
21 | |
22 | |
23 | |
24 | |
25 | |
26 | |
27 | |
28 | #include "def.h" |
29 | |
30 | static boolean |
31 | isdot(const char *p) |
32 | { |
33 | if(p && *p++ == '.' && *p++ == '\0') |
34 | return(TRUE1); |
35 | return(FALSE0); |
36 | } |
37 | |
38 | static boolean |
39 | isdotdot(const char *p) |
40 | { |
41 | if(p && *p++ == '.' && *p++ == '.' && *p++ == '\0') |
42 | return(TRUE1); |
43 | return(FALSE0); |
44 | } |
45 | |
46 | static boolean |
47 | issymbolic(const char *dir, const char *component) |
48 | { |
49 | #ifdef S_IFLNK0120000 |
50 | struct stat st; |
51 | char buf[ BUFSIZ8192 ], **pp; |
52 | |
53 | sprintf(buf, "%s%s%s", dir, *dir ? "/" : "", component); |
54 | for (pp=notdotdot; *pp; pp++) |
55 | if (strcmp(*pp, buf) == 0) |
56 | return (TRUE1); |
57 | if (lstat(buf, &st) == 0 |
58 | && (st.st_mode & S_IFMT0170000) == S_IFLNK0120000) { |
59 | *pp++ = strdup(buf); |
60 | if (pp >= ¬dotdot[ MAXDIRS64 ]) |
61 | fatalerr("out of .. dirs, increase MAXDIRS\n"); |
62 | return(TRUE1); |
63 | } |
64 | #endif |
65 | return(FALSE0); |
66 | } |
67 | |
68 | |
69 | |
70 | |
71 | |
72 | |
73 | static void |
74 | remove_dotdot(char *path) |
75 | { |
76 | register char *end, *from, *to, **cp; |
77 | char *components[ MAXFILES2048 ], |
78 | newpath[ BUFSIZ8192 ]; |
79 | boolean component_copied; |
80 | |
81 | |
82 | |
83 | |
84 | to = newpath; |
85 | if (*path == '/') |
| |
86 | *to++ = '/'; |
87 | *to = '\0'; |
88 | cp = components; |
89 | for (from=end=path; *end; end++) |
| 2 | Loop condition is false. Execution continues on line 97 |
|
90 | if (*end == '/') { |
91 | while (*end == '/') |
92 | *end++ = '\0'; |
93 | if (*from) |
94 | *cp++ = from; |
95 | from = end; |
96 | } |
97 | *cp++ = from; |
98 | *cp = NULL((void*)0); |
99 | |
100 | |
101 | |
102 | |
103 | cp = components; |
104 | while(*cp) { |
| 3 | Loop condition is true. Entering loop body |
|
105 | if (!isdot(*cp) && !isdotdot(*cp) && isdotdot(*(cp+1)) |
| |
106 | && !issymbolic(newpath, *cp)) |
107 | { |
108 | char **fp = cp + 2; |
109 | char **tp = cp; |
110 | |
111 | do |
112 | *tp++ = *fp; |
| 5 | Assigned value is garbage or undefined |
|
113 | while (*fp++); |
114 | if (cp != components) |
115 | cp--; |
116 | } else { |
117 | cp++; |
118 | } |
119 | } |
120 | |
121 | |
122 | |
123 | cp = components; |
124 | component_copied = FALSE0; |
125 | while(*cp) { |
126 | if (component_copied) |
127 | *to++ = '/'; |
128 | component_copied = TRUE1; |
129 | for (from = *cp; *from; ) |
130 | *to++ = *from++; |
131 | *to = '\0'; |
132 | cp++; |
133 | } |
134 | *to++ = '\0'; |
135 | |
136 | |
137 | |
138 | |
139 | strcpy(path, newpath); |
140 | } |
141 | |
142 | |
143 | |
144 | |
145 | struct inclist * |
146 | newinclude(const char *newfile, const char *incstring) |
147 | { |
148 | register struct inclist *ip; |
149 | |
150 | |
151 | |
152 | |
153 | ip = inclistp++; |
154 | if (inclistp == inclist + MAXFILES2048 - 1) |
155 | fatalerr("out of space: increase MAXFILES\n"); |
156 | ip->i_file = strdup(newfile); |
157 | |
158 | if (incstring == NULL((void*)0)) |
159 | ip->i_incstring = ip->i_file; |
160 | else |
161 | ip->i_incstring = strdup(incstring); |
162 | |
163 | inclistnext = inclistp; |
164 | return(ip); |
165 | } |
166 | |
167 | void |
168 | included_by(struct inclist *ip, struct inclist *newfile) |
169 | { |
170 | register int i; |
171 | |
172 | if (ip == NULL((void*)0)) |
173 | return; |
174 | |
175 | |
176 | |
177 | |
178 | |
179 | |
180 | if (ip->i_list == NULL((void*)0)) { |
181 | ip->i_list = (struct inclist **) |
182 | malloc(sizeof(struct inclist *) * ++ip->i_listlen); |
183 | ip->i_merged = (boolean *) |
184 | malloc(sizeof(boolean) * ip->i_listlen); |
185 | } else { |
186 | for (i=0; i<ip->i_listlen; i++) |
187 | if (ip->i_list[ i ] == newfile) { |
188 | i = strlen(newfile->i_file); |
189 | if (!(ip->i_flags & INCLUDED_SYM(1<<5)) && |
190 | !(i > 2 && |
191 | newfile->i_file[i-1] == 'c' && |
192 | newfile->i_file[i-2] == '.')) |
193 | { |
194 | |
195 | |
196 | |
197 | if (warn_multiple) |
198 | { |
199 | warning("%s includes %s more than once!\n", |
200 | ip->i_file, newfile->i_file); |
201 | warning1("Already have\n"); |
202 | for (i=0; i<ip->i_listlen; i++) |
203 | warning1("\t%s\n", ip->i_list[i]->i_file); |
204 | } |
205 | } |
206 | return; |
207 | } |
208 | ip->i_list = (struct inclist **) realloc(ip->i_list, |
209 | sizeof(struct inclist *) * ++ip->i_listlen); |
210 | ip->i_merged = (boolean *) |
211 | realloc(ip->i_merged, sizeof(boolean) * ip->i_listlen); |
212 | } |
213 | ip->i_list[ ip->i_listlen-1 ] = newfile; |
214 | ip->i_merged[ ip->i_listlen-1 ] = FALSE0; |
215 | } |
216 | |
217 | void |
218 | inc_clean (void) |
219 | { |
220 | register struct inclist *ip; |
221 | |
222 | for (ip = inclist; ip < inclistp; ip++) { |
223 | ip->i_flags &= ~MARKED(1<<2); |
224 | } |
225 | } |
226 | |
227 | struct inclist * |
228 | inc_path(const char *file, const char *include, int type) |
229 | { |
230 | static char path[ BUFSIZ8192 ]; |
231 | register const char **pp, *p; |
232 | register struct inclist *ip; |
233 | struct stat st; |
234 | |
235 | |
236 | |
237 | |
238 | |
239 | if ((type == INCLUDE7) || (type == INCLUDEDOT19)) |
240 | inclistnext = inclist; |
241 | ip = inclistnext; |
242 | |
243 | for (; ip->i_file; ip++) { |
244 | if ((strcmp(ip->i_incstring, include) == 0) && |
245 | !(ip->i_flags & INCLUDED_SYM(1<<5))) { |
246 | inclistnext = ip + 1; |
247 | return ip; |
248 | } |
249 | } |
250 | |
251 | if (inclistnext == inclist) { |
252 | |
253 | |
254 | |
255 | |
256 | if ((type == INCLUDEDOT19) || |
257 | (type == INCLUDENEXTDOT22) || |
258 | (*include == '/')) { |
259 | if (stat(include, &st) == 0 && !S_ISDIR(st.st_mode)((((st.st_mode)) & 0170000) == (0040000))) |
260 | return newinclude(include, include); |
261 | if (show_where_not) |
262 | warning1("\tnot in %s\n", include); |
263 | } |
264 | |
265 | |
266 | |
267 | |
268 | |
269 | if ((type == INCLUDEDOT19) || (type == INCLUDENEXTDOT22)) { |
270 | for (p=file+strlen(file); p>file; p--) |
271 | if (*p == '/') |
272 | break; |
273 | if (p == file) { |
274 | strcpy(path, include); |
275 | } else { |
276 | strncpy(path, file, (p-file) + 1); |
277 | path[ (p-file) + 1 ] = '\0'; |
278 | strcpy(path + (p-file) + 1, include); |
279 | } |
280 | remove_dotdot(path); |
281 | if (stat(path, &st) == 0 && !S_ISDIR(st.st_mode)((((st.st_mode)) & 0170000) == (0040000))) |
282 | return newinclude(path, include); |
283 | if (show_where_not) |
284 | warning1("\tnot in %s\n", path); |
285 | } |
286 | } |
287 | |
288 | |
289 | |
290 | |
291 | |
292 | if ((type == INCLUDE7) || (type == INCLUDEDOT19)) |
293 | includedirsnext = includedirs; |
294 | pp = includedirsnext; |
295 | |
296 | for (; *pp; pp++) { |
297 | sprintf(path, "%s/%s", *pp, include); |
298 | remove_dotdot(path); |
299 | if (stat(path, &st) == 0 && !S_ISDIR(st.st_mode)((((st.st_mode)) & 0170000) == (0040000))) { |
300 | includedirsnext = pp + 1; |
301 | return newinclude(path, include); |
302 | } |
303 | if (show_where_not) |
304 | warning1("\tnot in %s\n", path); |
305 | } |
306 | |
307 | return NULL((void*)0); |
308 | } |