]> git.sesse.net Git - rdpsrv/blob - Xserver/config/makedepend/include.c
Support RDP5 logon packets.
[rdpsrv] / Xserver / config / makedepend / include.c
1 /* $XConsortium: include.c /main/20 1996/12/04 10:11:18 swick $ */
2 /*
3
4 Copyright (c) 1993, 1994  X Consortium
5
6 Permission is hereby granted, free of charge, to any person obtaining a copy
7 of this software and associated documentation files (the "Software"), to deal
8 in the Software without restriction, including without limitation the rights
9 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 copies of the Software, and to permit persons to whom the Software is
11 furnished to do so, subject to the following conditions:
12
13 The above copyright notice and this permission notice shall be included in
14 all copies or substantial portions of the Software.
15
16 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
19 X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
20 AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
21 CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22
23 Except as contained in this notice, the name of the X Consortium shall not be
24 used in advertising or otherwise to promote the sale, use or other dealings
25 in this Software without prior written authorization from the X Consortium.
26
27 */
28
29
30 #include "def.h"
31
32 extern struct   inclist inclist[ MAXFILES ],
33                         *inclistp;
34 extern char     *includedirs[ ];
35 extern char     *notdotdot[ ];
36 extern boolean show_where_not;
37 extern boolean warn_multiple;
38
39 boolean
40 isdot(p)
41         register char   *p;
42 {
43         if(p && *p++ == '.' && *p++ == '\0')
44                 return(TRUE);
45         return(FALSE);
46 }
47
48 boolean
49 isdotdot(p)
50         register char   *p;
51 {
52         if(p && *p++ == '.' && *p++ == '.' && *p++ == '\0')
53                 return(TRUE);
54         return(FALSE);
55 }
56
57 boolean
58 issymbolic(dir, component)
59         register char   *dir, *component;
60 {
61 #ifdef S_IFLNK
62         struct stat     st;
63         char    buf[ BUFSIZ ], **pp;
64
65         sprintf(buf, "%s%s%s", dir, *dir ? "/" : "", component);
66         for (pp=notdotdot; *pp; pp++)
67                 if (strcmp(*pp, buf) == 0)
68                         return (TRUE);
69         if (lstat(buf, &st) == 0
70         && (st.st_mode & S_IFMT) == S_IFLNK) {
71                 *pp++ = copy(buf);
72                 if (pp >= &notdotdot[ MAXDIRS ])
73                         fatalerr("out of .. dirs, increase MAXDIRS\n");
74                 return(TRUE);
75         }
76 #endif
77         return(FALSE);
78 }
79
80 /*
81  * Occasionally, pathnames are created that look like .../x/../y
82  * Any of the 'x/..' sequences within the name can be eliminated.
83  * (but only if 'x' is not a symbolic link!!)
84  */
85 void
86 remove_dotdot(path)
87         char    *path;
88 {
89         register char   *end, *from, *to, **cp;
90         char            *components[ MAXFILES ],
91                         newpath[ BUFSIZ ];
92         boolean         component_copied;
93
94         /*
95          * slice path up into components.
96          */
97         to = newpath;
98         if (*path == '/')
99                 *to++ = '/';
100         *to = '\0';
101         cp = components;
102         for (from=end=path; *end; end++)
103                 if (*end == '/') {
104                         while (*end == '/')
105                                 *end++ = '\0';
106                         if (*from)
107                                 *cp++ = from;
108                         from = end;
109                 }
110         *cp++ = from;
111         *cp = NULL;
112
113         /*
114          * Recursively remove all 'x/..' component pairs.
115          */
116         cp = components;
117         while(*cp) {
118                 if (!isdot(*cp) && !isdotdot(*cp) && isdotdot(*(cp+1))
119                     && !issymbolic(newpath, *cp))
120                 {
121                     char **fp = cp + 2;
122                     char **tp = cp;
123
124                     do 
125                         *tp++ = *fp; /* move all the pointers down */
126                     while (*fp++);
127                     if (cp != components)
128                         cp--;   /* go back and check for nested ".." */
129                 } else {
130                     cp++;
131                 }
132         }
133         /*
134          * Concatenate the remaining path elements.
135          */
136         cp = components;
137         component_copied = FALSE;
138         while(*cp) {
139                 if (component_copied)
140                         *to++ = '/';
141                 component_copied = TRUE;
142                 for (from = *cp; *from; )
143                         *to++ = *from++;
144                 *to = '\0';
145                 cp++;
146         }
147         *to++ = '\0';
148
149         /*
150          * copy the reconstituted path back to our pointer.
151          */
152         strcpy(path, newpath);
153 }
154
155 /*
156  * Add an include file to the list of those included by 'file'.
157  */
158 struct inclist *newinclude(newfile, incstring)
159         register char   *newfile, *incstring;
160 {
161         register struct inclist *ip;
162
163         /*
164          * First, put this file on the global list of include files.
165          */
166         ip = inclistp++;
167         if (inclistp == inclist + MAXFILES - 1)
168                 fatalerr("out of space: increase MAXFILES\n");
169         ip->i_file = copy(newfile);
170
171         if (incstring == NULL)
172                 ip->i_incstring = ip->i_file;
173         else
174                 ip->i_incstring = copy(incstring);
175
176         return(ip);
177 }
178
179 void
180 included_by(ip, newfile)
181         register struct inclist *ip, *newfile;
182 {
183         register int i;
184
185         if (ip == NULL)
186                 return;
187         /*
188          * Put this include file (newfile) on the list of files included
189          * by 'file'.  If 'file' is NULL, then it is not an include
190          * file itself (i.e. was probably mentioned on the command line).
191          * If it is already on the list, don't stick it on again.
192          */
193         if (ip->i_list == NULL) {
194                 ip->i_list = (struct inclist **)
195                         malloc(sizeof(struct inclist *) * ++ip->i_listlen);
196                 ip->i_merged = (boolean *)
197                     malloc(sizeof(boolean) * ip->i_listlen);
198         } else {
199                 for (i=0; i<ip->i_listlen; i++)
200                         if (ip->i_list[ i ] == newfile) {
201                             i = strlen(newfile->i_file);
202                             if (!(ip->i_flags & INCLUDED_SYM) &&
203                                 !(i > 2 &&
204                                   newfile->i_file[i-1] == 'c' &&
205                                   newfile->i_file[i-2] == '.'))
206                             {
207                                 /* only bitch if ip has */
208                                 /* no #include SYMBOL lines  */
209                                 /* and is not a .c file */
210                                 if (warn_multiple)
211                                 {
212                                         warning("%s includes %s more than once!\n",
213                                                 ip->i_file, newfile->i_file);
214                                         warning1("Already have\n");
215                                         for (i=0; i<ip->i_listlen; i++)
216                                                 warning1("\t%s\n", ip->i_list[i]->i_file);
217                                 }
218                             }
219                             return;
220                         }
221                 ip->i_list = (struct inclist **) realloc(ip->i_list,
222                         sizeof(struct inclist *) * ++ip->i_listlen);
223                 ip->i_merged = (boolean *)
224                     realloc(ip->i_merged, sizeof(boolean) * ip->i_listlen);
225         }
226         ip->i_list[ ip->i_listlen-1 ] = newfile;
227         ip->i_merged[ ip->i_listlen-1 ] = FALSE;
228 }
229
230 void
231 inc_clean ()
232 {
233         register struct inclist *ip;
234
235         for (ip = inclist; ip < inclistp; ip++) {
236                 ip->i_flags &= ~MARKED;
237         }
238 }
239
240 struct inclist *inc_path(file, include, dot)
241         register char   *file,
242                         *include;
243         boolean dot;
244 {
245         static char     path[ BUFSIZ ];
246         register char           **pp, *p;
247         register struct inclist *ip;
248         struct stat     st;
249         boolean found = FALSE;
250
251         /*
252          * Check all previously found include files for a path that
253          * has already been expanded.
254          */
255         for (ip = inclist; ip->i_file; ip++)
256             if ((strcmp(ip->i_incstring, include) == 0) &&
257                 !(ip->i_flags & INCLUDED_SYM))
258             {
259                 found = TRUE;
260                 break;
261             }
262
263         /*
264          * If the path was surrounded by "" or is an absolute path,
265          * then check the exact path provided.
266          */
267         if (!found && (dot || *include == '/')) {
268                 if (stat(include, &st) == 0) {
269                         ip = newinclude(include, include);
270                         found = TRUE;
271                 }
272                 else if (show_where_not)
273                         warning1("\tnot in %s\n", include);
274         }
275
276         /*
277          * If the path was surrounded by "" see if this include file is in the
278          * directory of the file being parsed.
279          */
280         if (!found && dot) {
281                 for (p=file+strlen(file); p>file; p--)
282                         if (*p == '/')
283                                 break;
284                 if (p == file)
285                         strcpy(path, include);
286                 else {
287                         strncpy(path, file, (p-file) + 1);
288                         path[ (p-file) + 1 ] = '\0';
289                         strcpy(path + (p-file) + 1, include);
290                 }
291                 remove_dotdot(path);
292                 if (stat(path, &st) == 0) {
293                         ip = newinclude(path, include);
294                         found = TRUE;
295                 }
296                 else if (show_where_not)
297                         warning1("\tnot in %s\n", path);
298         }
299
300         /*
301          * Check the include directories specified. (standard include dir
302          * should be at the end.)
303          */
304         if (!found)
305                 for (pp = includedirs; *pp; pp++) {
306                         sprintf(path, "%s/%s", *pp, include);
307                         remove_dotdot(path);
308                         if (stat(path, &st) == 0) {
309                                 ip = newinclude(path, include);
310                                 found = TRUE;
311                                 break;
312                         }
313                         else if (show_where_not)
314                                 warning1("\tnot in %s\n", path);
315                 }
316
317         if (!found)
318                 ip = NULL;
319         return(ip);
320 }