Bug Summary

File:hw/xfree86/parser/scan.c
Location:line 421, column 13
Description:Value stored to 'i' is never read

Annotated Source Code

1/*
2 * Copyright (c) 1997 Metro Link Incorporated
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice shall be included in
12 * all copies or substantial portions of the Software.
13 *
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17 * THE X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
18 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
19 * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
20 * SOFTWARE.
21 *
22 * Except as contained in this notice, the name of the Metro Link shall not be
23 * used in advertising or otherwise to promote the sale, use or other dealings
24 * in this Software without prior written authorization from Metro Link.
25 *
26 */
27/*
28 * Copyright (c) 1997-2003 by The XFree86 Project, Inc.
29 *
30 * Permission is hereby granted, free of charge, to any person obtaining a
31 * copy of this software and associated documentation files (the "Software"),
32 * to deal in the Software without restriction, including without limitation
33 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
34 * and/or sell copies of the Software, and to permit persons to whom the
35 * Software is furnished to do so, subject to the following conditions:
36 *
37 * The above copyright notice and this permission notice shall be included in
38 * all copies or substantial portions of the Software.
39 *
40 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
41 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
42 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
43 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
44 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
45 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
46 * OTHER DEALINGS IN THE SOFTWARE.
47 *
48 * Except as contained in this notice, the name of the copyright holder(s)
49 * and author(s) shall not be used in advertising or otherwise to promote
50 * the sale, use or other dealings in this Software without prior written
51 * authorization from the copyright holder(s) and author(s).
52 */
53
54#ifdef HAVE_XORG_CONFIG_H1
55#include <xorg-config.h>
56#endif
57
58#include <ctype.h>
59#include <stdio.h>
60#include <stdlib.h>
61#include <string.h>
62#include <sys/types.h>
63#include <dirent.h>
64#include <unistd.h>
65#include <stdarg.h>
66#include <X11/Xdefs.h>
67#include <X11/Xfuncproto.h>
68
69#if defined(_POSIX_SOURCE)
70#include <limits.h>
71#else
72#define _POSIX_SOURCE
73#include <limits.h>
74#undef _POSIX_SOURCE
75#endif /* _POSIX_SOURCE */
76
77#if !defined(MAXHOSTNAMELEN32)
78#define MAXHOSTNAMELEN32 32
79#endif /* !MAXHOSTNAMELEN */
80
81/* For PATH_MAX */
82#include "misc.h"
83
84#include "Configint.h"
85#include "xf86tokens.h"
86
87#define CONFIG_BUF_LEN1024 1024
88#define CONFIG_MAX_FILES64 64
89
90static struct {
91 FILE *file;
92 char *path;
93} configFiles[CONFIG_MAX_FILES64];
94static const char **builtinConfig = NULL((void*)0);
95static int builtinIndex = 0;
96static int configPos = 0; /* current readers position */
97static int configLineNo = 0; /* linenumber */
98static char *configBuf, *configRBuf; /* buffer for lines */
99static char *configSection = NULL((void*)0); /* name of current section being parsed */
100static int numFiles = 0; /* number of config files */
101static int curFileIndex = 0; /* index of current config file */
102static int pushToken = LOCK_TOKEN;
103static int eol_seen = 0; /* private state to handle comments */
104LexRec xf86_lex_val;
105
106/*
107 * xf86getNextLine --
108 *
109 * read from the configFiles FILE stream until we encounter a new
110 * line; this is effectively just a big wrapper for fgets(3).
111 *
112 * xf86getToken() assumes that we will read up to the next
113 * newline; we need to grow configBuf and configRBuf as needed to
114 * support that.
115 */
116
117static char *
118xf86getNextLine(void)
119{
120 static int configBufLen = CONFIG_BUF_LEN1024;
121 char *tmpConfigBuf, *tmpConfigRBuf;
122 int c, i, pos = 0, eolFound = 0;
123 char *ret = NULL((void*)0);
124
125 /*
126 * reallocate the string if it was grown last time (i.e., is no
127 * longer CONFIG_BUF_LEN); we malloc the new strings first, so
128 * that if either of the mallocs fail, we can fall back on the
129 * existing buffer allocations
130 */
131
132 if (configBufLen != CONFIG_BUF_LEN1024) {
133
134 tmpConfigBuf = malloc(CONFIG_BUF_LEN1024);
135 tmpConfigRBuf = malloc(CONFIG_BUF_LEN1024);
136
137 if (!tmpConfigBuf || !tmpConfigRBuf) {
138
139 /*
140 * at least one of the mallocs failed; keep the old buffers
141 * and free any partial allocations
142 */
143
144 free(tmpConfigBuf);
145 free(tmpConfigRBuf);
146
147 }
148 else {
149
150 /*
151 * malloc succeeded; free the old buffers and use the new
152 * buffers
153 */
154
155 configBufLen = CONFIG_BUF_LEN1024;
156
157 free(configBuf);
158 free(configRBuf);
159
160 configBuf = tmpConfigBuf;
161 configRBuf = tmpConfigRBuf;
162 }
163 }
164
165 /* read in another block of chars */
166
167 do {
168 ret = fgets(configBuf + pos, configBufLen - pos - 1,
169 configFiles[curFileIndex].file);
170
171 if (!ret) {
172 /*
173 * if the file doesn't end in a newline, add one
174 * and trigger another read
175 */
176 if (pos != 0) {
177 strcpy(&configBuf[pos], "\n")__builtin___strcpy_chk (&configBuf[pos], "\n", __builtin_object_size
(&configBuf[pos], 2 > 1 ? 1 : 0))
;
178 ret = configBuf;
179 }
180 else
181 break;
182 }
183
184 /* search for EOL in the new block of chars */
185
186 for (i = pos; i < (configBufLen - 1); i++) {
187 c = configBuf[i];
188
189 if (c == '\0')
190 break;
191
192 if ((c == '\n') || (c == '\r')) {
193 eolFound = 1;
194 break;
195 }
196 }
197
198 /*
199 * if we didn't find EOL, then grow the string and
200 * read in more
201 */
202
203 if (!eolFound) {
204
205 tmpConfigBuf = realloc(configBuf, configBufLen + CONFIG_BUF_LEN1024);
206 tmpConfigRBuf = realloc(configRBuf, configBufLen + CONFIG_BUF_LEN1024);
207
208 if (!tmpConfigBuf || !tmpConfigRBuf) {
209
210 /*
211 * at least one of the reallocations failed; use the
212 * new allocation that succeeded, but we have to
213 * fallback to the previous configBufLen size and use
214 * the string we have, even though we don't have an
215 * EOL
216 */
217
218 if (tmpConfigBuf)
219 configBuf = tmpConfigBuf;
220 if (tmpConfigRBuf)
221 configRBuf = tmpConfigRBuf;
222
223 break;
224
225 }
226 else {
227
228 /* reallocation succeeded */
229
230 configBuf = tmpConfigBuf;
231 configRBuf = tmpConfigRBuf;
232 pos = i;
233 configBufLen += CONFIG_BUF_LEN1024;
234 }
235 }
236
237 } while (!eolFound);
238
239 return ret;
240}
241
242static int
243StringToToken(const char *str, const xf86ConfigSymTabRec * tab)
244{
245 int i;
246
247 for (i = 0; tab[i].token != -1; i++) {
248 if (!xf86nameCompare(tab[i].name, str))
249 return tab[i].token;
250 }
251 return ERROR_TOKEN;
252}
253
254/*
255 * xf86getToken --
256 * Read next Token from the config file. Handle the global variable
257 * pushToken.
258 */
259int
260xf86getToken(const xf86ConfigSymTabRec * tab)
261{
262 int c, i;
263
264 /*
265 * First check whether pushToken has a different value than LOCK_TOKEN.
266 * In this case rBuf[] contains a valid STRING/TOKEN/NUMBER. But in the
267 * oth * case the next token must be read from the input.
268 */
269 if (pushToken == EOF_TOKEN)
270 return EOF_TOKEN;
271 else if (pushToken == LOCK_TOKEN) {
272 /*
273 * eol_seen is only set for the first token after a newline.
274 */
275 eol_seen = 0;
276
277 c = configBuf[configPos];
278
279 /*
280 * Get start of next Token. EOF is handled,
281 * whitespaces are skipped.
282 */
283
284 again:
285 if (!c) {
286 char *ret;
287
288 if (numFiles > 0)
289 ret = xf86getNextLine();
290 else {
291 if (builtinConfig[builtinIndex] == NULL((void*)0))
292 ret = NULL((void*)0);
293 else {
294 strlcpy(configBuf,__builtin___strlcpy_chk (configBuf, builtinConfig[builtinIndex
], 1024, __builtin_object_size (configBuf, 2 > 1 ? 1 : 0))
295 builtinConfig[builtinIndex], CONFIG_BUF_LEN)__builtin___strlcpy_chk (configBuf, builtinConfig[builtinIndex
], 1024, __builtin_object_size (configBuf, 2 > 1 ? 1 : 0))
;
296 ret = configBuf;
297 builtinIndex++;
298 }
299 }
300 if (ret == NULL((void*)0)) {
301 /*
302 * if necessary, move to the next file and
303 * read the first line
304 */
305 if (curFileIndex + 1 < numFiles) {
306 curFileIndex++;
307 configLineNo = 0;
308 goto again;
309 }
310 else
311 return pushToken = EOF_TOKEN;
312 }
313 configLineNo++;
314 configPos = 0;
315 eol_seen = 1;
316 }
317
318 i = 0;
319 for (;;) {
320 c = configBuf[configPos++];
321 configRBuf[i++] = c;
322 switch (c) {
323 case ' ':
324 case '\t':
325 case '\r':
326 continue;
327 case '\n':
328 i = 0;
329 continue;
330 }
331 break;
332 }
333 if (c == '\0')
334 goto again;
335
336 if (c == '#') {
337 do {
338 configRBuf[i++] = (c = configBuf[configPos++]);
339 }
340 while ((c != '\n') && (c != '\r') && (c != '\0'));
341 configRBuf[i] = '\0';
342 /* XXX no private copy.
343 * Use xf86addComment when setting a comment.
344 */
345 xf86_lex_val.str = configRBuf;
346 return COMMENT;
347 }
348
349 /* GJA -- handle '-' and ',' * Be careful: "-hsync" is a keyword. */
350 else if ((c == ',') && !isalpha(configBuf[configPos])) {
351 return COMMA;
352 }
353 else if ((c == '-') && !isalpha(configBuf[configPos])) {
354 return DASH;
355 }
356
357 /*
358 * Numbers are returned immediately ...
359 */
360 if (isdigit(c)) {
361 int base;
362
363 if (c == '0')
364 if ((configBuf[configPos] == 'x') ||
365 (configBuf[configPos] == 'X')) {
366 base = 16;
367 xf86_lex_val.numType = PARSE_HEX;
368 }
369 else {
370 base = 8;
371 xf86_lex_val.numType = PARSE_OCTAL;
372 }
373 else {
374 base = 10;
375 xf86_lex_val.numType = PARSE_DECIMAL;
376 }
377
378 configRBuf[0] = c;
379 i = 1;
380 while (isdigit(c = configBuf[configPos++]) ||
381 (c == '.') || (c == 'x') || (c == 'X') ||
382 ((base == 16) && (((c >= 'a') && (c <= 'f')) ||
383 ((c >= 'A') && (c <= 'F')))))
384 configRBuf[i++] = c;
385 configPos--; /* GJA -- one too far */
386 configRBuf[i] = '\0';
387 xf86_lex_val.num = strtoul(configRBuf, NULL((void*)0), 0);
388 xf86_lex_val.realnum = atof(configRBuf);
389 return NUMBER;
390 }
391
392 /*
393 * All Strings START with a \" ...
394 */
395 else if (c == '\"') {
396 i = -1;
397 do {
398 configRBuf[++i] = (c = configBuf[configPos++]);
399 }
400 while ((c != '\"') && (c != '\n') && (c != '\r') && (c != '\0'));
401 configRBuf[i] = '\0';
402 xf86_lex_val.str = malloc(strlen(configRBuf) + 1);
403 strcpy(xf86_lex_val.str, configRBuf)__builtin___strcpy_chk (xf86_lex_val.str, configRBuf, __builtin_object_size
(xf86_lex_val.str, 2 > 1 ? 1 : 0))
; /* private copy ! */
404 return STRING;
405 }
406
407 /*
408 * ... and now we MUST have a valid token. The search is
409 * handled later along with the pushed tokens.
410 */
411 else {
412 configRBuf[0] = c;
413 i = 0;
414 do {
415 configRBuf[++i] = (c = configBuf[configPos++]);
416 }
417 while ((c != ' ') && (c != '\t') && (c != '\n') && (c != '\r') &&
418 (c != '\0') && (c != '#'));
419 --configPos;
420 configRBuf[i] = '\0';
421 i = 0;
Value stored to 'i' is never read
422 }
423
424 }
425 else {
426
427 /*
428 * Here we deal with pushed tokens. Reinitialize pushToken again. If
429 * the pushed token was NUMBER || STRING return them again ...
430 */
431 int temp = pushToken;
432
433 pushToken = LOCK_TOKEN;
434
435 if (temp == COMMA || temp == DASH)
436 return temp;
437 if (temp == NUMBER || temp == STRING)
438 return temp;
439 }
440
441 /*
442 * Joop, at last we have to lookup the token ...
443 */
444 if (tab)
445 return StringToToken(configRBuf, tab);
446
447 return ERROR_TOKEN; /* Error catcher */
448}
449
450int
451xf86getSubToken(char **comment)
452{
453 int token;
454
455 for (;;) {
456 token = xf86getToken(NULL((void*)0));
457 if (token == COMMENT) {
458 if (comment)
459 *comment = xf86addComment(*comment, xf86_lex_val.str);
460 }
461 else
462 return token;
463 }
464 /*NOTREACHED*/}
465
466int
467xf86getSubTokenWithTab(char **comment, const xf86ConfigSymTabRec * tab)
468{
469 int token;
470
471 for (;;) {
472 token = xf86getToken(tab);
473 if (token == COMMENT) {
474 if (comment)
475 *comment = xf86addComment(*comment, xf86_lex_val.str);
476 }
477 else
478 return token;
479 }
480 /*NOTREACHED*/}
481
482void
483xf86unGetToken(int token)
484{
485 pushToken = token;
486}
487
488char *
489xf86tokenString(void)
490{
491 return configRBuf;
492}
493
494int
495xf86pathIsAbsolute(const char *path)
496{
497 if (path && path[0] == '/')
498 return 1;
499 return 0;
500}
501
502/* A path is "safe" if it is relative and if it contains no ".." elements. */
503int
504xf86pathIsSafe(const char *path)
505{
506 if (xf86pathIsAbsolute(path))
507 return 0;
508
509 /* Compare with ".." */
510 if (!strcmp(path, ".."))
511 return 0;
512
513 /* Look for leading "../" */
514 if (!strncmp(path, "../", 3))
515 return 0;
516
517 /* Look for trailing "/.." */
518 if ((strlen(path) > 3) && !strcmp(path + strlen(path) - 3, "/.."))
519 return 0;
520
521 /* Look for "/../" */
522 if (strstr(path, "/../"))
523 return 0;
524
525 return 1;
526}
527
528/*
529 * This function substitutes the following escape sequences:
530 *
531 * %A cmdline argument as an absolute path (must be absolute to match)
532 * %R cmdline argument as a relative path
533 * %S cmdline argument as a "safe" path (relative, and no ".." elements)
534 * %X default config file name ("xorg.conf")
535 * %H hostname
536 * %E config file environment ($XORGCONFIG) as an absolute path
537 * %F config file environment ($XORGCONFIG) as a relative path
538 * %G config file environment ($XORGCONFIG) as a safe path
539 * %P projroot
540 * %C sysconfdir
541 * %D datadir
542 * %% %
543 */
544
545#ifndef XCONFIGFILE"xorg.conf"
546#define XCONFIGFILE"xorg.conf" "xorg.conf"
547#endif
548#ifndef XCONFIGDIR"xorg.conf.d"
549#define XCONFIGDIR"xorg.conf.d" "xorg.conf.d"
550#endif
551#ifndef XCONFIGSUFFIX".conf"
552#define XCONFIGSUFFIX".conf" ".conf"
553#endif
554#ifndef PROJECTROOT"/Users/jeremy/src/freedesktop/jhbuild/build"
555#define PROJECTROOT"/Users/jeremy/src/freedesktop/jhbuild/build" "/usr/X11R6"
556#endif
557#ifndef SYSCONFDIR"/Users/jeremy/src/freedesktop/jhbuild/build/etc"
558#define SYSCONFDIR"/Users/jeremy/src/freedesktop/jhbuild/build/etc" PROJECTROOT"/Users/jeremy/src/freedesktop/jhbuild/build" "/etc"
559#endif
560#ifndef DATADIR"/Users/jeremy/src/freedesktop/jhbuild/build/share"
561#define DATADIR"/Users/jeremy/src/freedesktop/jhbuild/build/share" PROJECTROOT"/Users/jeremy/src/freedesktop/jhbuild/build" "/share"
562#endif
563#ifndef XCONFENV"XORGCONFIG"
564#define XCONFENV"XORGCONFIG" "XORGCONFIG"
565#endif
566
567#define BAIL_OUTdo { free(result); return ((void*)0); } while (0) do { \
568 free(result); \
569 return NULL((void*)0); \
570 } while (0)
571
572#define CHECK_LENGTHdo { if (l > 1024) { do { free(result); return ((void*)0);
} while (0); } } while (0)
do { \
573 if (l > PATH_MAX1024) { \
574 BAIL_OUTdo { free(result); return ((void*)0); } while (0); \
575 } \
576 } while (0)
577
578#define APPEND_STR(s)do { if (strlen(s) + l > 1024) { do { free(result); return
((void*)0); } while (0); } else { __builtin___strcpy_chk (result
+ l, s, __builtin_object_size (result + l, 2 > 1 ? 1 : 0)
); l += strlen(s); } } while (0)
do { \
579 if (strlen(s) + l > PATH_MAX1024) { \
580 BAIL_OUTdo { free(result); return ((void*)0); } while (0); \
581 } else { \
582 strcpy(result + l, s)__builtin___strcpy_chk (result + l, s, __builtin_object_size (
result + l, 2 > 1 ? 1 : 0))
; \
583 l += strlen(s); \
584 } \
585 } while (0)
586
587static char *
588DoSubstitution(const char *template, const char *cmdline, const char *projroot,
589 int *cmdlineUsed, int *envUsed, const char *XConfigFile)
590{
591 char *result;
592 int i, l;
593 static const char *env = NULL((void*)0);
594 static char *hostname = NULL((void*)0);
595
596 if (!template)
597 return NULL((void*)0);
598
599 if (cmdlineUsed)
600 *cmdlineUsed = 0;
601 if (envUsed)
602 *envUsed = 0;
603
604 result = malloc(PATH_MAX1024 + 1);
605 l = 0;
606 for (i = 0; template[i]; i++) {
607 if (template[i] != '%') {
608 result[l++] = template[i];
609 CHECK_LENGTHdo { if (l > 1024) { do { free(result); return ((void*)0);
} while (0); } } while (0)
;
610 }
611 else {
612 switch (template[++i]) {
613 case 'A':
614 if (cmdline && xf86pathIsAbsolute(cmdline)) {
615 APPEND_STR(cmdline)do { if (strlen(cmdline) + l > 1024) { do { free(result); return
((void*)0); } while (0); } else { __builtin___strcpy_chk (result
+ l, cmdline, __builtin_object_size (result + l, 2 > 1 ? 1
: 0)); l += strlen(cmdline); } } while (0)
;
616 if (cmdlineUsed)
617 *cmdlineUsed = 1;
618 }
619 else
620 BAIL_OUTdo { free(result); return ((void*)0); } while (0);
621 break;
622 case 'R':
623 if (cmdline && !xf86pathIsAbsolute(cmdline)) {
624 APPEND_STR(cmdline)do { if (strlen(cmdline) + l > 1024) { do { free(result); return
((void*)0); } while (0); } else { __builtin___strcpy_chk (result
+ l, cmdline, __builtin_object_size (result + l, 2 > 1 ? 1
: 0)); l += strlen(cmdline); } } while (0)
;
625 if (cmdlineUsed)
626 *cmdlineUsed = 1;
627 }
628 else
629 BAIL_OUTdo { free(result); return ((void*)0); } while (0);
630 break;
631 case 'S':
632 if (cmdline && xf86pathIsSafe(cmdline)) {
633 APPEND_STR(cmdline)do { if (strlen(cmdline) + l > 1024) { do { free(result); return
((void*)0); } while (0); } else { __builtin___strcpy_chk (result
+ l, cmdline, __builtin_object_size (result + l, 2 > 1 ? 1
: 0)); l += strlen(cmdline); } } while (0)
;
634 if (cmdlineUsed)
635 *cmdlineUsed = 1;
636 }
637 else
638 BAIL_OUTdo { free(result); return ((void*)0); } while (0);
639 break;
640 case 'X':
641 APPEND_STR(XConfigFile)do { if (strlen(XConfigFile) + l > 1024) { do { free(result
); return ((void*)0); } while (0); } else { __builtin___strcpy_chk
(result + l, XConfigFile, __builtin_object_size (result + l,
2 > 1 ? 1 : 0)); l += strlen(XConfigFile); } } while (0)
;
642 break;
643 case 'H':
644 if (!hostname) {
645 if ((hostname = malloc(MAXHOSTNAMELEN32 + 1))) {
646 if (gethostname(hostname, MAXHOSTNAMELEN32) == 0) {
647 hostname[MAXHOSTNAMELEN32] = '\0';
648 }
649 else {
650 free(hostname);
651 hostname = NULL((void*)0);
652 }
653 }
654 }
655 if (hostname)
656 APPEND_STR(hostname)do { if (strlen(hostname) + l > 1024) { do { free(result);
return ((void*)0); } while (0); } else { __builtin___strcpy_chk
(result + l, hostname, __builtin_object_size (result + l, 2 >
1 ? 1 : 0)); l += strlen(hostname); } } while (0)
;
657 break;
658 case 'E':
659 if (!env)
660 env = getenv(XCONFENV"XORGCONFIG");
661 if (env && xf86pathIsAbsolute(env)) {
662 APPEND_STR(env)do { if (strlen(env) + l > 1024) { do { free(result); return
((void*)0); } while (0); } else { __builtin___strcpy_chk (result
+ l, env, __builtin_object_size (result + l, 2 > 1 ? 1 : 0
)); l += strlen(env); } } while (0)
;
663 if (envUsed)
664 *envUsed = 1;
665 }
666 else
667 BAIL_OUTdo { free(result); return ((void*)0); } while (0);
668 break;
669 case 'F':
670 if (!env)
671 env = getenv(XCONFENV"XORGCONFIG");
672 if (env && !xf86pathIsAbsolute(env)) {
673 APPEND_STR(env)do { if (strlen(env) + l > 1024) { do { free(result); return
((void*)0); } while (0); } else { __builtin___strcpy_chk (result
+ l, env, __builtin_object_size (result + l, 2 > 1 ? 1 : 0
)); l += strlen(env); } } while (0)
;
674 if (envUsed)
675 *envUsed = 1;
676 }
677 else
678 BAIL_OUTdo { free(result); return ((void*)0); } while (0);
679 break;
680 case 'G':
681 if (!env)
682 env = getenv(XCONFENV"XORGCONFIG");
683 if (env && xf86pathIsSafe(env)) {
684 APPEND_STR(env)do { if (strlen(env) + l > 1024) { do { free(result); return
((void*)0); } while (0); } else { __builtin___strcpy_chk (result
+ l, env, __builtin_object_size (result + l, 2 > 1 ? 1 : 0
)); l += strlen(env); } } while (0)
;
685 if (envUsed)
686 *envUsed = 1;
687 }
688 else
689 BAIL_OUTdo { free(result); return ((void*)0); } while (0);
690 break;
691 case 'P':
692 if (projroot && xf86pathIsAbsolute(projroot))
693 APPEND_STR(projroot)do { if (strlen(projroot) + l > 1024) { do { free(result);
return ((void*)0); } while (0); } else { __builtin___strcpy_chk
(result + l, projroot, __builtin_object_size (result + l, 2 >
1 ? 1 : 0)); l += strlen(projroot); } } while (0)
;
694 else
695 BAIL_OUTdo { free(result); return ((void*)0); } while (0);
696 break;
697 case 'C':
698 APPEND_STR(SYSCONFDIR)do { if (strlen("/Users/jeremy/src/freedesktop/jhbuild/build/etc"
) + l > 1024) { do { free(result); return ((void*)0); } while
(0); } else { __builtin___strcpy_chk (result + l, "/Users/jeremy/src/freedesktop/jhbuild/build/etc"
, __builtin_object_size (result + l, 2 > 1 ? 1 : 0)); l +=
strlen("/Users/jeremy/src/freedesktop/jhbuild/build/etc"); }
} while (0)
;
699 break;
700 case 'D':
701 APPEND_STR(DATADIR)do { if (strlen("/Users/jeremy/src/freedesktop/jhbuild/build/share"
) + l > 1024) { do { free(result); return ((void*)0); } while
(0); } else { __builtin___strcpy_chk (result + l, "/Users/jeremy/src/freedesktop/jhbuild/build/share"
, __builtin_object_size (result + l, 2 > 1 ? 1 : 0)); l +=
strlen("/Users/jeremy/src/freedesktop/jhbuild/build/share");
} } while (0)
;
702 break;
703 case '%':
704 result[l++] = '%';
705 CHECK_LENGTHdo { if (l > 1024) { do { free(result); return ((void*)0);
} while (0); } } while (0)
;
706 break;
707 default:
708 fprintf(stderr__stderrp, "invalid escape %%%c found in path template\n",
709 template[i]);
710 BAIL_OUTdo { free(result); return ((void*)0); } while (0);
711 break;
712 }
713 }
714 }
715#ifdef DEBUG
716 fprintf(stderr__stderrp, "Converted `%s' to `%s'\n", template, result);
717#endif
718 return result;
719}
720
721/*
722 * Given some searching parameters, locate and open the xorg config file.
723 */
724static char *
725OpenConfigFile(const char *path, const char *cmdline, const char *projroot,
726 const char *confname)
727{
728 char *filepath = NULL((void*)0);
729 char *pathcopy;
730 const char *template;
731 int cmdlineUsed = 0;
732 FILE *file = NULL((void*)0);
733
734 pathcopy = strdup(path);
735 for (template = strtok(pathcopy, ","); template && !file;
736 template = strtok(NULL((void*)0), ",")) {
737 filepath = DoSubstitution(template, cmdline, projroot,
738 &cmdlineUsed, NULL((void*)0), confname);
739 if (!filepath)
740 continue;
741 if (cmdline && !cmdlineUsed) {
742 free(filepath);
743 filepath = NULL((void*)0);
744 continue;
745 }
746 file = fopen(filepath, "r");
747 if (!file) {
748 free(filepath);
749 filepath = NULL((void*)0);
750 }
751 }
752
753 free(pathcopy);
754 if (file) {
755 configFiles[numFiles].file = file;
756 configFiles[numFiles].path = strdup(filepath);
757 numFiles++;
758 }
759 return filepath;
760}
761
762/*
763 * Match non-hidden files in the xorg config directory with a .conf
764 * suffix. This filter is passed to scandir(3).
765 */
766static int
767ConfigFilter(const struct dirent *de)
768{
769 const char *name = de->d_name;
770 size_t len;
771 size_t suflen = strlen(XCONFIGSUFFIX".conf");
772
773 if (!name || name[0] == '.')
774 return 0;
775 len = strlen(name);
776 if (len <= suflen)
777 return 0;
778 if (strcmp(&name[len - suflen], XCONFIGSUFFIX".conf") != 0)
779 return 0;
780 return 1;
781}
782
783static Bool
784AddConfigDirFiles(const char *dirpath, struct dirent **list, int num)
785{
786 int i;
787 Bool openedFile = FALSE0;
788 Bool warnOnce = FALSE0;
789
790 for (i = 0; i < num; i++) {
791 char *path;
792 FILE *file;
793
794 if (numFiles >= CONFIG_MAX_FILES64) {
795 if (!warnOnce) {
796 ErrorF("Maximum number of configuration " "files opened\n");
797 warnOnce = TRUE1;
798 }
799 continue;
800 }
801
802 path = malloc(PATH_MAX1024 + 1);
803 snprintf(path, PATH_MAX + 1, "%s/%s", dirpath, list[i]->d_name)__builtin___snprintf_chk (path, 1024 + 1, 0, __builtin_object_size
(path, 2 > 1 ? 1 : 0), "%s/%s", dirpath, list[i]->d_name
)
;
804 file = fopen(path, "r");
805 if (!file) {
806 free(path);
807 continue;
808 }
809 openedFile = TRUE1;
810
811 configFiles[numFiles].file = file;
812 configFiles[numFiles].path = path;
813 numFiles++;
814 }
815
816 return openedFile;
817}
818
819/*
820 * Given some searching parameters, locate and open the xorg config
821 * directory. The directory does not need to contain config files.
822 */
823static char *
824OpenConfigDir(const char *path, const char *cmdline, const char *projroot,
825 const char *confname)
826{
827 char *dirpath = NULL((void*)0), *pathcopy;
828 const char *template;
829 Bool found = FALSE0;
830 int cmdlineUsed = 0;
831
832 pathcopy = strdup(path);
833 for (template = strtok(pathcopy, ","); template && !found;
834 template = strtok(NULL((void*)0), ",")) {
835 struct dirent **list = NULL((void*)0);
836 int num;
837
838 dirpath = DoSubstitution(template, cmdline, projroot,
839 &cmdlineUsed, NULL((void*)0), confname);
840 if (!dirpath)
841 continue;
842 if (cmdline && !cmdlineUsed) {
843 free(dirpath);
844 dirpath = NULL((void*)0);
845 continue;
846 }
847
848 /* match files named *.conf */
849 num = scandir(dirpath, &list, ConfigFilter, alphasort);
850 if (num < 0) {
851 list = NULL((void*)0);
852 num = 0;
853 }
854 found = AddConfigDirFiles(dirpath, list, num);
855 if (!found) {
856 free(dirpath);
857 dirpath = NULL((void*)0);
858 }
859 while (num--)
860 free(list[num]);
861 free(list);
862 }
863
864 free(pathcopy);
865 return dirpath;
866}
867
868/*
869 * xf86initConfigFiles -- Setup global variables and buffers.
870 */
871void
872xf86initConfigFiles(void)
873{
874 curFileIndex = 0;
875 configPos = 0;
876 configLineNo = 0;
877 pushToken = LOCK_TOKEN;
878
879 configBuf = malloc(CONFIG_BUF_LEN1024);
880 configRBuf = malloc(CONFIG_BUF_LEN1024);
881 configBuf[0] = '\0'; /* sanity ... */
882}
883
884/*
885 * xf86openConfigFile --
886 *
887 * This function take a config file search path (optional), a command-line
888 * specified file name (optional) and the ProjectRoot path (optional) and
889 * locates and opens a config file based on that information. If a
890 * command-line file name is specified, then this function fails if none
891 * of the located files.
892 *
893 * The return value is a pointer to the actual name of the file that was
894 * opened. When no file is found, the return value is NULL. The caller should
895 * free() the returned value.
896 *
897 * The escape sequences allowed in the search path are defined above.
898 *
899 */
900
901#ifndef DEFAULT_CONF_PATH"/etc/X11/%S," "%P/etc/X11/%S," "/etc/X11/%G," "%P/etc/X11/%G,"
"/etc/X11/%X-%M," "/etc/X11/%X," "/etc/%X," "%P/etc/X11/%X.%H,"
"%P/etc/X11/%X-%M," "%P/etc/X11/%X," "%P/lib/X11/%X.%H," "%P/lib/X11/%X-%M,"
"%P/lib/X11/%X"
902#define DEFAULT_CONF_PATH"/etc/X11/%S," "%P/etc/X11/%S," "/etc/X11/%G," "%P/etc/X11/%G,"
"/etc/X11/%X-%M," "/etc/X11/%X," "/etc/%X," "%P/etc/X11/%X.%H,"
"%P/etc/X11/%X-%M," "%P/etc/X11/%X," "%P/lib/X11/%X.%H," "%P/lib/X11/%X-%M,"
"%P/lib/X11/%X"
"/etc/X11/%S," \
903 "%P/etc/X11/%S," \
904 "/etc/X11/%G," \
905 "%P/etc/X11/%G," \
906 "/etc/X11/%X-%M," \
907 "/etc/X11/%X," \
908 "/etc/%X," \
909 "%P/etc/X11/%X.%H," \
910 "%P/etc/X11/%X-%M," \
911 "%P/etc/X11/%X," \
912 "%P/lib/X11/%X.%H," \
913 "%P/lib/X11/%X-%M," \
914 "%P/lib/X11/%X"
915#endif
916
917char *
918xf86openConfigFile(const char *path, const char *cmdline, const char *projroot)
919{
920 if (!path || !path[0])
921 path = DEFAULT_CONF_PATH"/etc/X11/%S," "%P/etc/X11/%S," "/etc/X11/%G," "%P/etc/X11/%G,"
"/etc/X11/%X-%M," "/etc/X11/%X," "/etc/%X," "%P/etc/X11/%X.%H,"
"%P/etc/X11/%X-%M," "%P/etc/X11/%X," "%P/lib/X11/%X.%H," "%P/lib/X11/%X-%M,"
"%P/lib/X11/%X"
;
922 if (!projroot || !projroot[0])
923 projroot = PROJECTROOT"/Users/jeremy/src/freedesktop/jhbuild/build";
924
925 /* Search for a config file */
926 return OpenConfigFile(path, cmdline, projroot, XCONFIGFILE"xorg.conf");
927}
928
929/*
930 * xf86openConfigDirFiles --
931 *
932 * This function take a config directory search path (optional), a
933 * command-line specified directory name (optional) and the ProjectRoot path
934 * (optional) and locates and opens a config directory based on that
935 * information. If a command-line name is specified, then this function
936 * fails if it is not found.
937 *
938 * The return value is a pointer to the actual name of the direcoty that was
939 * opened. When no directory is found, the return value is NULL. The caller
940 * should free() the returned value.
941 *
942 * The escape sequences allowed in the search path are defined above.
943 *
944 */
945char *
946xf86openConfigDirFiles(const char *path, const char *cmdline,
947 const char *projroot)
948{
949 if (!path || !path[0])
950 path = DEFAULT_CONF_PATH"/etc/X11/%S," "%P/etc/X11/%S," "/etc/X11/%G," "%P/etc/X11/%G,"
"/etc/X11/%X-%M," "/etc/X11/%X," "/etc/%X," "%P/etc/X11/%X.%H,"
"%P/etc/X11/%X-%M," "%P/etc/X11/%X," "%P/lib/X11/%X.%H," "%P/lib/X11/%X-%M,"
"%P/lib/X11/%X"
;
951 if (!projroot || !projroot[0])
952 projroot = PROJECTROOT"/Users/jeremy/src/freedesktop/jhbuild/build";
953
954 /* Search for the multiconf directory */
955 return OpenConfigDir(path, cmdline, projroot, XCONFIGDIR"xorg.conf.d");
956}
957
958void
959xf86closeConfigFile(void)
960{
961 int i;
962
963 free(configRBuf);
964 configRBuf = NULL((void*)0);
965 free(configBuf);
966 configBuf = NULL((void*)0);
967
968 if (numFiles == 0) {
969 builtinConfig = NULL((void*)0);
970 builtinIndex = 0;
971 }
972 for (i = 0; i < numFiles; i++) {
973 fclose(configFiles[i].file);
974 configFiles[i].file = NULL((void*)0);
975 free(configFiles[i].path);
976 configFiles[i].path = NULL((void*)0);
977 }
978 numFiles = 0;
979}
980
981void
982xf86setBuiltinConfig(const char *config[])
983{
984 builtinConfig = config;
985}
986
987void
988xf86parseError(const char *format, ...)
989{
990 va_list ap;
991 const char *filename = numFiles ? configFiles[curFileIndex].path
992 : "<builtin configuration>";
993
994 ErrorF("Parse error on line %d of section %s in file %s\n\t",
995 configLineNo, configSection, filename);
996 va_start(ap, format)__builtin_va_start(ap, format);
997 VErrorF(format, ap);
998 va_end(ap)__builtin_va_end(ap);
999
1000 ErrorF("\n");
1001}
1002
1003void
1004xf86validationError(const char *format, ...)
1005{
1006 va_list ap;
1007 const char *filename = numFiles ? configFiles[curFileIndex].path
1008 : "<builtin configuration>";
1009
1010 ErrorF("Data incomplete in file %s\n\t", filename);
1011 va_start(ap, format)__builtin_va_start(ap, format);
1012 VErrorF(format, ap);
1013 va_end(ap)__builtin_va_end(ap);
1014
1015 ErrorF("\n");
1016}
1017
1018void
1019xf86setSection(const char *section)
1020{
1021 free(configSection);
1022 configSection = strdup(section);
1023}
1024
1025/*
1026 * xf86getToken --
1027 * Lookup a string if it is actually a token in disguise.
1028 */
1029int
1030xf86getStringToken(const xf86ConfigSymTabRec * tab)
1031{
1032 return StringToToken(xf86_lex_val.str, tab);
1033}
1034
1035/*
1036 * Compare two names. The characters '_', ' ', and '\t' are ignored
1037 * in the comparison.
1038 */
1039int
1040xf86nameCompare(const char *s1, const char *s2)
1041{
1042 char c1, c2;
1043
1044 if (!s1 || *s1 == 0) {
1045 if (!s2 || *s2 == 0)
1046 return 0;
1047 else
1048 return 1;
1049 }
1050
1051 while (*s1 == '_' || *s1 == ' ' || *s1 == '\t')
1052 s1++;
1053 while (*s2 == '_' || *s2 == ' ' || *s2 == '\t')
1054 s2++;
1055 c1 = (isupper(*s1) ? tolower(*s1) : *s1);
1056 c2 = (isupper(*s2) ? tolower(*s2) : *s2);
1057 while (c1 == c2) {
1058 if (c1 == '\0')
1059 return 0;
1060 s1++;
1061 s2++;
1062 while (*s1 == '_' || *s1 == ' ' || *s1 == '\t')
1063 s1++;
1064 while (*s2 == '_' || *s2 == ' ' || *s2 == '\t')
1065 s2++;
1066 c1 = (isupper(*s1) ? tolower(*s1) : *s1);
1067 c2 = (isupper(*s2) ? tolower(*s2) : *s2);
1068 }
1069 return c1 - c2;
1070}
1071
1072char *
1073xf86addComment(char *cur, const char *add)
1074{
1075 char *str;
1076 const char *cstr;
1077 int len, curlen, iscomment, hasnewline = 0, insnewline, endnewline;
1078
1079 if (add == NULL((void*)0) || add[0] == '\0')
1080 return cur;
1081
1082 if (cur) {
1083 curlen = strlen(cur);
1084 if (curlen)
1085 hasnewline = cur[curlen - 1] == '\n';
1086 eol_seen = 0;
1087 }
1088 else
1089 curlen = 0;
1090
1091 cstr = add;
1092 iscomment = 0;
1093 while (*cstr) {
1094 if (*cstr != ' ' && *cstr != '\t')
1095 break;
1096 ++cstr;
1097 }
1098 iscomment = (*cstr == '#');
1099
1100 len = strlen(add);
1101 endnewline = add[len - 1] == '\n';
1102
1103 insnewline = eol_seen || (curlen && !hasnewline);
1104 if (insnewline)
1105 len++;
1106 if (!iscomment)
1107 len++;
1108 if (!endnewline)
1109 len++;
1110
1111 /* Allocate + 1 char for '\0' terminator. */
1112 str = realloc(cur, curlen + len + 1);
1113 if (!str)
1114 return cur;
1115
1116 cur = str;
1117
1118 if (insnewline)
1119 cur[curlen++] = '\n';
1120 if (!iscomment)
1121 cur[curlen++] = '#';
1122 strcpy(cur + curlen, add)__builtin___strcpy_chk (cur + curlen, add, __builtin_object_size
(cur + curlen, 2 > 1 ? 1 : 0))
;
1123 if (!endnewline)
1124 strcat(cur, "\n")__builtin___strcat_chk (cur, "\n", __builtin_object_size (cur
, 2 > 1 ? 1 : 0))
;
1125
1126 return cur;
1127}
1128
1129Bool
1130xf86getBoolValue(Bool *val, const char *str)
1131{
1132 if (!val || !str)
1133 return FALSE0;
1134 if (*str == '\0') {
1135 *val = TRUE1;
1136 }
1137 else {
1138 if (xf86nameCompare(str, "1") == 0)
1139 *val = TRUE1;
1140 else if (xf86nameCompare(str, "on") == 0)
1141 *val = TRUE1;
1142 else if (xf86nameCompare(str, "true") == 0)
1143 *val = TRUE1;
1144 else if (xf86nameCompare(str, "yes") == 0)
1145 *val = TRUE1;
1146 else if (xf86nameCompare(str, "0") == 0)
1147 *val = FALSE0;
1148 else if (xf86nameCompare(str, "off") == 0)
1149 *val = FALSE0;
1150 else if (xf86nameCompare(str, "false") == 0)
1151 *val = FALSE0;
1152 else if (xf86nameCompare(str, "no") == 0)
1153 *val = FALSE0;
1154 else
1155 return FALSE0;
1156 }
1157 return TRUE1;
1158}