security/nss/coreconf/mkdepend/include.c

Thu, 22 Jan 2015 13:21:57 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Thu, 22 Jan 2015 13:21:57 +0100
branch
TOR_BUG_9701
changeset 15
b8a032363ba2
permissions
-rw-r--r--

Incorporate requested changes from Mozilla in review:
https://bugzilla.mozilla.org/show_bug.cgi?id=1123480#c6

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

mercurial