2003-11-14 17:48:57 +01:00
|
|
|
/*
|
|
|
|
* Copyright (c) 1997 Metro Link Incorporated
|
|
|
|
*
|
|
|
|
* Permission is hereby granted, free of charge, to any person obtaining a
|
|
|
|
* copy of this software and associated documentation files (the "Software"),
|
|
|
|
* to deal in the Software without restriction, including without limitation
|
|
|
|
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
|
|
|
* and/or sell copies of the Software, and to permit persons to whom the
|
|
|
|
* Software is furnished to do so, subject to the following conditions:
|
|
|
|
*
|
|
|
|
* The above copyright notice and this permission notice shall be included in
|
|
|
|
* all copies or substantial portions of the Software.
|
|
|
|
*
|
|
|
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
|
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
|
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
|
|
|
* THE X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
|
|
|
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
|
|
|
|
* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
|
|
* SOFTWARE.
|
|
|
|
*
|
|
|
|
* Except as contained in this notice, the name of the Metro Link shall not be
|
|
|
|
* used in advertising or otherwise to promote the sale, use or other dealings
|
|
|
|
* in this Software without prior written authorization from Metro Link.
|
|
|
|
*
|
|
|
|
*/
|
2003-11-25 20:29:01 +01:00
|
|
|
/*
|
|
|
|
* Copyright (c) 1997-2003 by The XFree86 Project, Inc.
|
|
|
|
*
|
|
|
|
* Permission is hereby granted, free of charge, to any person obtaining a
|
|
|
|
* copy of this software and associated documentation files (the "Software"),
|
|
|
|
* to deal in the Software without restriction, including without limitation
|
|
|
|
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
|
|
|
* and/or sell copies of the Software, and to permit persons to whom the
|
|
|
|
* Software is furnished to do so, subject to the following conditions:
|
|
|
|
*
|
|
|
|
* The above copyright notice and this permission notice shall be included in
|
|
|
|
* all copies or substantial portions of the Software.
|
|
|
|
*
|
|
|
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
|
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
|
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
|
|
|
* THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
|
|
|
|
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
|
|
|
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
|
|
|
* OTHER DEALINGS IN THE SOFTWARE.
|
|
|
|
*
|
|
|
|
* Except as contained in this notice, the name of the copyright holder(s)
|
|
|
|
* and author(s) shall not be used in advertising or otherwise to promote
|
|
|
|
* the sale, use or other dealings in this Software without prior written
|
|
|
|
* authorization from the copyright holder(s) and author(s).
|
|
|
|
*/
|
|
|
|
|
2003-11-14 17:48:57 +01:00
|
|
|
/* View/edit this file with tab stops set to 4 */
|
|
|
|
|
2005-07-03 09:02:09 +02:00
|
|
|
#ifdef HAVE_XORG_CONFIG_H
|
|
|
|
#include <xorg-config.h>
|
|
|
|
#endif
|
|
|
|
|
2003-11-14 17:48:57 +01:00
|
|
|
#include <ctype.h>
|
|
|
|
#include <stdio.h>
|
|
|
|
#include <stdlib.h>
|
|
|
|
#include <string.h>
|
2009-12-21 09:04:16 +01:00
|
|
|
#include <sys/types.h>
|
|
|
|
#include <dirent.h>
|
2003-11-14 17:48:57 +01:00
|
|
|
#include <unistd.h>
|
|
|
|
#include <stdarg.h>
|
2009-12-21 09:04:16 +01:00
|
|
|
#include <X11/Xdefs.h>
|
2007-12-03 20:29:54 +01:00
|
|
|
#include <X11/Xfuncproto.h>
|
2003-11-14 17:48:57 +01:00
|
|
|
|
|
|
|
#if defined(_POSIX_SOURCE)
|
|
|
|
#include <limits.h>
|
|
|
|
#else
|
|
|
|
#define _POSIX_SOURCE
|
|
|
|
#include <limits.h>
|
|
|
|
#undef _POSIX_SOURCE
|
2012-03-21 20:55:09 +01:00
|
|
|
#endif /* _POSIX_SOURCE */
|
2008-07-17 20:37:50 +02:00
|
|
|
|
2003-11-14 17:48:57 +01:00
|
|
|
#if !defined(MAXHOSTNAMELEN)
|
|
|
|
#define MAXHOSTNAMELEN 32
|
2012-03-21 20:55:09 +01:00
|
|
|
#endif /* !MAXHOSTNAMELEN */
|
2003-11-14 17:48:57 +01:00
|
|
|
|
2011-03-09 01:17:27 +01:00
|
|
|
/* For PATH_MAX */
|
|
|
|
#include "misc.h"
|
|
|
|
|
2003-11-14 17:48:57 +01:00
|
|
|
#include "Configint.h"
|
|
|
|
#include "xf86tokens.h"
|
|
|
|
|
|
|
|
#define CONFIG_BUF_LEN 1024
|
2009-12-21 09:04:16 +01:00
|
|
|
#define CONFIG_MAX_FILES 64
|
2003-11-14 17:48:57 +01:00
|
|
|
|
2012-03-21 20:55:09 +01:00
|
|
|
static int StringToToken(const char *, xf86ConfigSymTabRec *);
|
2003-11-14 17:48:57 +01:00
|
|
|
|
2009-12-21 09:04:16 +01:00
|
|
|
static struct {
|
2012-03-21 20:55:09 +01:00
|
|
|
FILE *file;
|
|
|
|
char *path;
|
2009-12-21 09:04:16 +01:00
|
|
|
} configFiles[CONFIG_MAX_FILES];
|
2003-11-25 20:29:01 +01:00
|
|
|
static const char **builtinConfig = NULL;
|
|
|
|
static int builtinIndex = 0;
|
2012-03-21 20:55:09 +01:00
|
|
|
static int configPos = 0; /* current readers position */
|
|
|
|
static int configLineNo = 0; /* linenumber */
|
|
|
|
static char *configBuf, *configRBuf; /* buffer for lines */
|
|
|
|
static char *configSection = NULL; /* name of current section being parsed */
|
|
|
|
static int numFiles = 0; /* number of config files */
|
|
|
|
static int curFileIndex = 0; /* index of current config file */
|
2003-11-14 17:48:57 +01:00
|
|
|
static int pushToken = LOCK_TOKEN;
|
2012-03-21 20:55:09 +01:00
|
|
|
static int eol_seen = 0; /* private state to handle comments */
|
2003-11-14 17:48:57 +01:00
|
|
|
LexRec val;
|
|
|
|
|
2006-09-21 23:45:17 +02:00
|
|
|
/*
|
|
|
|
* xf86getNextLine --
|
|
|
|
*
|
2009-12-21 09:04:16 +01:00
|
|
|
* read from the configFiles FILE stream until we encounter a new
|
2006-09-21 23:45:17 +02:00
|
|
|
* line; this is effectively just a big wrapper for fgets(3).
|
|
|
|
*
|
|
|
|
* xf86getToken() assumes that we will read up to the next
|
|
|
|
* newline; we need to grow configBuf and configRBuf as needed to
|
|
|
|
* support that.
|
|
|
|
*/
|
|
|
|
|
2012-03-21 20:55:09 +01:00
|
|
|
static char *
|
2006-09-21 23:45:17 +02:00
|
|
|
xf86getNextLine(void)
|
|
|
|
{
|
2012-03-21 20:55:09 +01:00
|
|
|
static int configBufLen = CONFIG_BUF_LEN;
|
|
|
|
char *tmpConfigBuf, *tmpConfigRBuf;
|
|
|
|
int c, i, pos = 0, eolFound = 0;
|
|
|
|
char *ret = NULL;
|
2006-09-21 23:45:17 +02:00
|
|
|
|
2012-03-21 20:55:09 +01:00
|
|
|
/*
|
|
|
|
* reallocate the string if it was grown last time (i.e., is no
|
|
|
|
* longer CONFIG_BUF_LEN); we malloc the new strings first, so
|
|
|
|
* that if either of the mallocs fail, we can fall back on the
|
|
|
|
* existing buffer allocations
|
|
|
|
*/
|
2006-09-21 23:45:17 +02:00
|
|
|
|
2012-03-21 20:55:09 +01:00
|
|
|
if (configBufLen != CONFIG_BUF_LEN) {
|
2006-09-21 23:45:17 +02:00
|
|
|
|
2012-03-21 20:55:09 +01:00
|
|
|
tmpConfigBuf = malloc(CONFIG_BUF_LEN);
|
|
|
|
tmpConfigRBuf = malloc(CONFIG_BUF_LEN);
|
2006-09-21 23:45:17 +02:00
|
|
|
|
2012-03-21 20:55:09 +01:00
|
|
|
if (!tmpConfigBuf || !tmpConfigRBuf) {
|
2006-09-21 23:45:17 +02:00
|
|
|
|
2012-03-21 20:55:09 +01:00
|
|
|
/*
|
|
|
|
* at least one of the mallocs failed; keep the old buffers
|
|
|
|
* and free any partial allocations
|
|
|
|
*/
|
2006-09-21 23:45:17 +02:00
|
|
|
|
2012-03-21 20:55:09 +01:00
|
|
|
free(tmpConfigBuf);
|
|
|
|
free(tmpConfigRBuf);
|
2006-09-21 23:45:17 +02:00
|
|
|
|
2012-03-21 20:55:09 +01:00
|
|
|
}
|
|
|
|
else {
|
2006-09-21 23:45:17 +02:00
|
|
|
|
2012-03-21 20:55:09 +01:00
|
|
|
/*
|
|
|
|
* malloc succeeded; free the old buffers and use the new
|
|
|
|
* buffers
|
|
|
|
*/
|
2006-09-21 23:45:17 +02:00
|
|
|
|
2012-03-21 20:55:09 +01:00
|
|
|
configBufLen = CONFIG_BUF_LEN;
|
2006-09-21 23:45:17 +02:00
|
|
|
|
2012-03-21 20:55:09 +01:00
|
|
|
free(configBuf);
|
|
|
|
free(configRBuf);
|
2006-09-21 23:45:17 +02:00
|
|
|
|
2012-03-21 20:55:09 +01:00
|
|
|
configBuf = tmpConfigBuf;
|
|
|
|
configRBuf = tmpConfigRBuf;
|
|
|
|
}
|
|
|
|
}
|
2006-09-21 23:45:17 +02:00
|
|
|
|
2012-03-21 20:55:09 +01:00
|
|
|
/* read in another block of chars */
|
2006-09-21 23:45:17 +02:00
|
|
|
|
2012-03-21 20:55:09 +01:00
|
|
|
do {
|
|
|
|
ret = fgets(configBuf + pos, configBufLen - pos - 1,
|
|
|
|
configFiles[curFileIndex].file);
|
2006-09-21 23:45:17 +02:00
|
|
|
|
2012-03-21 20:55:09 +01:00
|
|
|
if (!ret) {
|
|
|
|
/*
|
|
|
|
* if the file doesn't end in a newline, add one
|
|
|
|
* and trigger another read
|
|
|
|
*/
|
|
|
|
if (pos != 0) {
|
|
|
|
strcpy(&configBuf[pos], "\n");
|
|
|
|
ret = configBuf;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
break;
|
|
|
|
}
|
2006-09-21 23:45:17 +02:00
|
|
|
|
2012-03-21 20:55:09 +01:00
|
|
|
/* search for EOL in the new block of chars */
|
2006-09-21 23:45:17 +02:00
|
|
|
|
2012-03-21 20:55:09 +01:00
|
|
|
for (i = pos; i < (configBufLen - 1); i++) {
|
|
|
|
c = configBuf[i];
|
2006-09-21 23:45:17 +02:00
|
|
|
|
2012-03-21 20:55:09 +01:00
|
|
|
if (c == '\0')
|
|
|
|
break;
|
2006-09-21 23:45:17 +02:00
|
|
|
|
2012-03-21 20:55:09 +01:00
|
|
|
if ((c == '\n') || (c == '\r')) {
|
|
|
|
eolFound = 1;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
2006-09-21 23:45:17 +02:00
|
|
|
|
2012-03-21 20:55:09 +01:00
|
|
|
/*
|
|
|
|
* if we didn't find EOL, then grow the string and
|
|
|
|
* read in more
|
|
|
|
*/
|
2006-09-21 23:45:17 +02:00
|
|
|
|
2012-03-21 20:55:09 +01:00
|
|
|
if (!eolFound) {
|
2006-09-21 23:45:17 +02:00
|
|
|
|
2012-03-21 20:55:09 +01:00
|
|
|
tmpConfigBuf = realloc(configBuf, configBufLen + CONFIG_BUF_LEN);
|
|
|
|
tmpConfigRBuf = realloc(configRBuf, configBufLen + CONFIG_BUF_LEN);
|
2006-09-21 23:45:17 +02:00
|
|
|
|
2012-03-21 20:55:09 +01:00
|
|
|
if (!tmpConfigBuf || !tmpConfigRBuf) {
|
2006-09-21 23:45:17 +02:00
|
|
|
|
2012-03-21 20:55:09 +01:00
|
|
|
/*
|
|
|
|
* at least one of the reallocations failed; use the
|
|
|
|
* new allocation that succeeded, but we have to
|
|
|
|
* fallback to the previous configBufLen size and use
|
|
|
|
* the string we have, even though we don't have an
|
|
|
|
* EOL
|
|
|
|
*/
|
2006-09-21 23:45:17 +02:00
|
|
|
|
2012-03-21 20:55:09 +01:00
|
|
|
if (tmpConfigBuf)
|
|
|
|
configBuf = tmpConfigBuf;
|
|
|
|
if (tmpConfigRBuf)
|
|
|
|
configRBuf = tmpConfigRBuf;
|
2006-09-21 23:45:17 +02:00
|
|
|
|
2012-03-21 20:55:09 +01:00
|
|
|
break;
|
2006-09-21 23:45:17 +02:00
|
|
|
|
2012-03-21 20:55:09 +01:00
|
|
|
}
|
|
|
|
else {
|
2006-09-21 23:45:17 +02:00
|
|
|
|
2012-03-21 20:55:09 +01:00
|
|
|
/* reallocation succeeded */
|
2006-09-21 23:45:17 +02:00
|
|
|
|
2012-03-21 20:55:09 +01:00
|
|
|
configBuf = tmpConfigBuf;
|
|
|
|
configRBuf = tmpConfigRBuf;
|
|
|
|
pos = i;
|
|
|
|
configBufLen += CONFIG_BUF_LEN;
|
|
|
|
}
|
|
|
|
}
|
2006-09-21 23:45:17 +02:00
|
|
|
|
2012-03-21 20:55:09 +01:00
|
|
|
} while (!eolFound);
|
2006-09-21 23:45:17 +02:00
|
|
|
|
2012-03-21 20:55:09 +01:00
|
|
|
return ret;
|
2006-09-21 23:45:17 +02:00
|
|
|
}
|
|
|
|
|
2003-11-14 17:48:57 +01:00
|
|
|
/*
|
|
|
|
* xf86getToken --
|
2006-09-21 23:45:17 +02:00
|
|
|
* Read next Token from the config file. Handle the global variable
|
2003-11-14 17:48:57 +01:00
|
|
|
* pushToken.
|
|
|
|
*/
|
|
|
|
int
|
2012-03-21 20:55:09 +01:00
|
|
|
xf86getToken(xf86ConfigSymTabRec * tab)
|
2003-11-14 17:48:57 +01:00
|
|
|
{
|
2012-03-21 20:55:09 +01:00
|
|
|
int c, i;
|
|
|
|
|
|
|
|
/*
|
|
|
|
* First check whether pushToken has a different value than LOCK_TOKEN.
|
|
|
|
* In this case rBuf[] contains a valid STRING/TOKEN/NUMBER. But in the
|
|
|
|
* oth * case the next token must be read from the input.
|
|
|
|
*/
|
|
|
|
if (pushToken == EOF_TOKEN)
|
|
|
|
return EOF_TOKEN;
|
|
|
|
else if (pushToken == LOCK_TOKEN) {
|
|
|
|
/*
|
|
|
|
* eol_seen is only set for the first token after a newline.
|
|
|
|
*/
|
|
|
|
eol_seen = 0;
|
|
|
|
|
|
|
|
c = configBuf[configPos];
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Get start of next Token. EOF is handled,
|
|
|
|
* whitespaces are skipped.
|
|
|
|
*/
|
|
|
|
|
|
|
|
again:
|
|
|
|
if (!c) {
|
|
|
|
char *ret;
|
|
|
|
|
|
|
|
if (numFiles > 0)
|
|
|
|
ret = xf86getNextLine();
|
|
|
|
else {
|
|
|
|
if (builtinConfig[builtinIndex] == NULL)
|
|
|
|
ret = NULL;
|
|
|
|
else {
|
|
|
|
strlcpy(configBuf,
|
|
|
|
builtinConfig[builtinIndex], CONFIG_BUF_LEN);
|
|
|
|
ret = configBuf;
|
|
|
|
builtinIndex++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (ret == NULL) {
|
|
|
|
/*
|
|
|
|
* if necessary, move to the next file and
|
|
|
|
* read the first line
|
|
|
|
*/
|
|
|
|
if (curFileIndex + 1 < numFiles) {
|
|
|
|
curFileIndex++;
|
|
|
|
configLineNo = 0;
|
|
|
|
goto again;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
return pushToken = EOF_TOKEN;
|
|
|
|
}
|
|
|
|
configLineNo++;
|
|
|
|
configPos = 0;
|
|
|
|
eol_seen = 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
i = 0;
|
|
|
|
for (;;) {
|
|
|
|
c = configBuf[configPos++];
|
|
|
|
configRBuf[i++] = c;
|
|
|
|
switch (c) {
|
|
|
|
case ' ':
|
|
|
|
case '\t':
|
|
|
|
case '\r':
|
|
|
|
continue;
|
|
|
|
case '\n':
|
|
|
|
i = 0;
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
if (c == '\0')
|
|
|
|
goto again;
|
|
|
|
|
|
|
|
if (c == '#') {
|
|
|
|
do {
|
|
|
|
configRBuf[i++] = (c = configBuf[configPos++]);
|
|
|
|
}
|
|
|
|
while ((c != '\n') && (c != '\r') && (c != '\0'));
|
|
|
|
configRBuf[i] = '\0';
|
|
|
|
/* XXX no private copy.
|
|
|
|
* Use xf86addComment when setting a comment.
|
|
|
|
*/
|
|
|
|
val.str = configRBuf;
|
|
|
|
return COMMENT;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* GJA -- handle '-' and ',' * Be careful: "-hsync" is a keyword. */
|
|
|
|
else if ((c == ',') && !isalpha(configBuf[configPos])) {
|
|
|
|
return COMMA;
|
|
|
|
}
|
|
|
|
else if ((c == '-') && !isalpha(configBuf[configPos])) {
|
|
|
|
return DASH;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Numbers are returned immediately ...
|
|
|
|
*/
|
|
|
|
if (isdigit(c)) {
|
|
|
|
int base;
|
|
|
|
|
|
|
|
if (c == '0')
|
|
|
|
if ((configBuf[configPos] == 'x') ||
|
|
|
|
(configBuf[configPos] == 'X')) {
|
|
|
|
base = 16;
|
|
|
|
val.numType = PARSE_HEX;
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
base = 8;
|
|
|
|
val.numType = PARSE_OCTAL;
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
base = 10;
|
|
|
|
val.numType = PARSE_DECIMAL;
|
|
|
|
}
|
|
|
|
|
|
|
|
configRBuf[0] = c;
|
|
|
|
i = 1;
|
|
|
|
while (isdigit(c = configBuf[configPos++]) ||
|
|
|
|
(c == '.') || (c == 'x') || (c == 'X') ||
|
|
|
|
((base == 16) && (((c >= 'a') && (c <= 'f')) ||
|
|
|
|
((c >= 'A') && (c <= 'F')))))
|
|
|
|
configRBuf[i++] = c;
|
|
|
|
configPos--; /* GJA -- one too far */
|
|
|
|
configRBuf[i] = '\0';
|
|
|
|
val.num = strtoul(configRBuf, NULL, 0);
|
|
|
|
val.realnum = atof(configRBuf);
|
|
|
|
return NUMBER;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* All Strings START with a \" ...
|
|
|
|
*/
|
|
|
|
else if (c == '\"') {
|
|
|
|
i = -1;
|
|
|
|
do {
|
|
|
|
configRBuf[++i] = (c = configBuf[configPos++]);
|
|
|
|
}
|
|
|
|
while ((c != '\"') && (c != '\n') && (c != '\r') && (c != '\0'));
|
|
|
|
configRBuf[i] = '\0';
|
|
|
|
val.str = malloc(strlen(configRBuf) + 1);
|
|
|
|
strcpy(val.str, configRBuf); /* private copy ! */
|
|
|
|
return STRING;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* ... and now we MUST have a valid token. The search is
|
|
|
|
* handled later along with the pushed tokens.
|
|
|
|
*/
|
|
|
|
else {
|
|
|
|
configRBuf[0] = c;
|
|
|
|
i = 0;
|
|
|
|
do {
|
|
|
|
configRBuf[++i] = (c = configBuf[configPos++]);
|
|
|
|
}
|
|
|
|
while ((c != ' ') && (c != '\t') && (c != '\n') && (c != '\r') &&
|
|
|
|
(c != '\0') && (c != '#'));
|
|
|
|
--configPos;
|
|
|
|
configRBuf[i] = '\0';
|
|
|
|
i = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Here we deal with pushed tokens. Reinitialize pushToken again. If
|
|
|
|
* the pushed token was NUMBER || STRING return them again ...
|
|
|
|
*/
|
|
|
|
int temp = pushToken;
|
|
|
|
|
|
|
|
pushToken = LOCK_TOKEN;
|
|
|
|
|
|
|
|
if (temp == COMMA || temp == DASH)
|
|
|
|
return temp;
|
|
|
|
if (temp == NUMBER || temp == STRING)
|
|
|
|
return temp;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Joop, at last we have to lookup the token ...
|
|
|
|
*/
|
|
|
|
if (tab) {
|
|
|
|
i = 0;
|
|
|
|
while (tab[i].token != -1)
|
|
|
|
if (xf86nameCompare(configRBuf, tab[i].name) == 0)
|
|
|
|
return tab[i].token;
|
|
|
|
else
|
|
|
|
i++;
|
|
|
|
}
|
|
|
|
|
|
|
|
return ERROR_TOKEN; /* Error catcher */
|
2003-11-14 17:48:57 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
int
|
2012-03-21 20:55:09 +01:00
|
|
|
xf86getSubToken(char **comment)
|
2003-11-14 17:48:57 +01:00
|
|
|
{
|
2012-03-21 20:55:09 +01:00
|
|
|
int token;
|
|
|
|
|
|
|
|
for (;;) {
|
|
|
|
token = xf86getToken(NULL);
|
|
|
|
if (token == COMMENT) {
|
|
|
|
if (comment)
|
|
|
|
*comment = xf86addComment(*comment, val.str);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
return token;
|
|
|
|
}
|
|
|
|
/*NOTREACHED*/}
|
2003-11-14 17:48:57 +01:00
|
|
|
|
|
|
|
int
|
2012-03-21 20:55:09 +01:00
|
|
|
xf86getSubTokenWithTab(char **comment, xf86ConfigSymTabRec * tab)
|
2003-11-14 17:48:57 +01:00
|
|
|
{
|
2012-03-21 20:55:09 +01:00
|
|
|
int token;
|
|
|
|
|
|
|
|
for (;;) {
|
|
|
|
token = xf86getToken(tab);
|
|
|
|
if (token == COMMENT) {
|
|
|
|
if (comment)
|
|
|
|
*comment = xf86addComment(*comment, val.str);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
return token;
|
|
|
|
}
|
|
|
|
/*NOTREACHED*/}
|
2003-11-14 17:48:57 +01:00
|
|
|
|
|
|
|
void
|
2012-03-21 20:55:09 +01:00
|
|
|
xf86unGetToken(int token)
|
2003-11-14 17:48:57 +01:00
|
|
|
{
|
2012-03-21 20:55:09 +01:00
|
|
|
pushToken = token;
|
2003-11-14 17:48:57 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
char *
|
2012-03-21 20:55:09 +01:00
|
|
|
xf86tokenString(void)
|
2003-11-14 17:48:57 +01:00
|
|
|
{
|
2012-03-21 20:55:09 +01:00
|
|
|
return configRBuf;
|
2003-11-14 17:48:57 +01:00
|
|
|
}
|
|
|
|
|
Rework symbol visibility for easier maintenance
Save in a few special cases, _X_EXPORT should not be used in C source
files. Instead, it should be used in headers, and the proper C source
include that header. Some special cases are symbols that need to be
shared between modules, but not expected to be used by external drivers,
and symbols that are accessible via LoaderSymbol/dlopen.
This patch also adds conditionally some new sdk header files, depending
on extensions enabled. These files were added to match pattern for
other extensions/modules, that is, have the headers "deciding" symbol
visibility in the sdk. These headers are:
o Xext/panoramiXsrv.h, Xext/panoramiX.h
o fbpict.h (unconditionally)
o vidmodeproc.h
o mioverlay.h (unconditionally, used only by xaa)
o xfixes.h (unconditionally, symbols required by dri2)
LoaderSymbol and similar functions now don't have different prototypes,
in loaderProcs.h and xf86Module.h, so that both headers can be included,
without the need of defining IN_LOADER.
xf86NewInputDevice() device prototype readded to xf86Xinput.h, but
not exported (and with a comment about it).
2008-12-03 08:43:34 +01:00
|
|
|
int
|
2003-11-14 17:48:57 +01:00
|
|
|
xf86pathIsAbsolute(const char *path)
|
|
|
|
{
|
2012-03-21 20:55:09 +01:00
|
|
|
if (path && path[0] == '/')
|
|
|
|
return 1;
|
|
|
|
return 0;
|
2003-11-14 17:48:57 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
/* A path is "safe" if it is relative and if it contains no ".." elements. */
|
Rework symbol visibility for easier maintenance
Save in a few special cases, _X_EXPORT should not be used in C source
files. Instead, it should be used in headers, and the proper C source
include that header. Some special cases are symbols that need to be
shared between modules, but not expected to be used by external drivers,
and symbols that are accessible via LoaderSymbol/dlopen.
This patch also adds conditionally some new sdk header files, depending
on extensions enabled. These files were added to match pattern for
other extensions/modules, that is, have the headers "deciding" symbol
visibility in the sdk. These headers are:
o Xext/panoramiXsrv.h, Xext/panoramiX.h
o fbpict.h (unconditionally)
o vidmodeproc.h
o mioverlay.h (unconditionally, used only by xaa)
o xfixes.h (unconditionally, symbols required by dri2)
LoaderSymbol and similar functions now don't have different prototypes,
in loaderProcs.h and xf86Module.h, so that both headers can be included,
without the need of defining IN_LOADER.
xf86NewInputDevice() device prototype readded to xf86Xinput.h, but
not exported (and with a comment about it).
2008-12-03 08:43:34 +01:00
|
|
|
int
|
2003-11-14 17:48:57 +01:00
|
|
|
xf86pathIsSafe(const char *path)
|
|
|
|
{
|
2012-03-21 20:55:09 +01:00
|
|
|
if (xf86pathIsAbsolute(path))
|
|
|
|
return 0;
|
2003-11-14 17:48:57 +01:00
|
|
|
|
2012-03-21 20:55:09 +01:00
|
|
|
/* Compare with ".." */
|
|
|
|
if (!strcmp(path, ".."))
|
|
|
|
return 0;
|
2003-11-14 17:48:57 +01:00
|
|
|
|
2012-03-21 20:55:09 +01:00
|
|
|
/* Look for leading "../" */
|
|
|
|
if (!strncmp(path, "../", 3))
|
|
|
|
return 0;
|
2003-11-14 17:48:57 +01:00
|
|
|
|
2012-03-21 20:55:09 +01:00
|
|
|
/* Look for trailing "/.." */
|
|
|
|
if ((strlen(path) > 3) && !strcmp(path + strlen(path) - 3, "/.."))
|
|
|
|
return 0;
|
2003-11-14 17:48:57 +01:00
|
|
|
|
2012-03-21 20:55:09 +01:00
|
|
|
/* Look for "/../" */
|
|
|
|
if (strstr(path, "/../"))
|
|
|
|
return 0;
|
2003-11-14 17:48:57 +01:00
|
|
|
|
2012-03-21 20:55:09 +01:00
|
|
|
return 1;
|
2003-11-14 17:48:57 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* This function substitutes the following escape sequences:
|
|
|
|
*
|
|
|
|
* %A cmdline argument as an absolute path (must be absolute to match)
|
|
|
|
* %R cmdline argument as a relative path
|
|
|
|
* %S cmdline argument as a "safe" path (relative, and no ".." elements)
|
2004-04-23 21:54:30 +02:00
|
|
|
* %X default config file name ("xorg.conf")
|
2003-11-14 17:48:57 +01:00
|
|
|
* %H hostname
|
2004-04-23 21:54:30 +02:00
|
|
|
* %E config file environment ($XORGCONFIG) as an absolute path
|
|
|
|
* %F config file environment ($XORGCONFIG) as a relative path
|
|
|
|
* %G config file environment ($XORGCONFIG) as a safe path
|
2003-11-14 17:48:57 +01:00
|
|
|
* %P projroot
|
2010-04-03 18:33:47 +02:00
|
|
|
* %C sysconfdir
|
|
|
|
* %D datadir
|
2003-11-14 17:48:57 +01:00
|
|
|
* %% %
|
|
|
|
*/
|
|
|
|
|
|
|
|
#ifndef XCONFIGFILE
|
2004-04-23 21:54:30 +02:00
|
|
|
#define XCONFIGFILE "xorg.conf"
|
2003-11-14 17:48:57 +01:00
|
|
|
#endif
|
2009-12-21 09:04:16 +01:00
|
|
|
#ifndef XCONFIGDIR
|
|
|
|
#define XCONFIGDIR "xorg.conf.d"
|
|
|
|
#endif
|
|
|
|
#ifndef XCONFIGSUFFIX
|
|
|
|
#define XCONFIGSUFFIX ".conf"
|
|
|
|
#endif
|
2003-11-14 17:48:57 +01:00
|
|
|
#ifndef PROJECTROOT
|
|
|
|
#define PROJECTROOT "/usr/X11R6"
|
|
|
|
#endif
|
2010-04-03 18:33:47 +02:00
|
|
|
#ifndef SYSCONFDIR
|
|
|
|
#define SYSCONFDIR PROJECTROOT "/etc"
|
|
|
|
#endif
|
|
|
|
#ifndef DATADIR
|
|
|
|
#define DATADIR PROJECTROOT "/share"
|
|
|
|
#endif
|
2003-11-14 17:48:57 +01:00
|
|
|
#ifndef XCONFENV
|
2004-04-23 21:54:30 +02:00
|
|
|
#define XCONFENV "XORGCONFIG"
|
2003-11-14 17:48:57 +01:00
|
|
|
#endif
|
|
|
|
|
|
|
|
#define BAIL_OUT do { \
|
2009-04-06 23:56:49 +02:00
|
|
|
free(result); \
|
2003-11-14 17:48:57 +01:00
|
|
|
return NULL; \
|
|
|
|
} while (0)
|
|
|
|
|
|
|
|
#define CHECK_LENGTH do { \
|
|
|
|
if (l > PATH_MAX) { \
|
|
|
|
BAIL_OUT; \
|
|
|
|
} \
|
|
|
|
} while (0)
|
|
|
|
|
|
|
|
#define APPEND_STR(s) do { \
|
|
|
|
if (strlen(s) + l > PATH_MAX) { \
|
|
|
|
BAIL_OUT; \
|
|
|
|
} else { \
|
|
|
|
strcpy(result + l, s); \
|
|
|
|
l += strlen(s); \
|
|
|
|
} \
|
|
|
|
} while (0)
|
|
|
|
|
|
|
|
static char *
|
|
|
|
DoSubstitution(const char *template, const char *cmdline, const char *projroot,
|
2012-03-21 20:55:09 +01:00
|
|
|
int *cmdlineUsed, int *envUsed, const char *XConfigFile)
|
2003-11-14 17:48:57 +01:00
|
|
|
{
|
2012-03-21 20:55:09 +01:00
|
|
|
char *result;
|
|
|
|
int i, l;
|
|
|
|
static const char *env = NULL;
|
|
|
|
static char *hostname = NULL;
|
|
|
|
|
|
|
|
if (!template)
|
|
|
|
return NULL;
|
|
|
|
|
|
|
|
if (cmdlineUsed)
|
|
|
|
*cmdlineUsed = 0;
|
|
|
|
if (envUsed)
|
|
|
|
*envUsed = 0;
|
|
|
|
|
|
|
|
result = malloc(PATH_MAX + 1);
|
|
|
|
l = 0;
|
|
|
|
for (i = 0; template[i]; i++) {
|
|
|
|
if (template[i] != '%') {
|
|
|
|
result[l++] = template[i];
|
|
|
|
CHECK_LENGTH;
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
switch (template[++i]) {
|
|
|
|
case 'A':
|
|
|
|
if (cmdline && xf86pathIsAbsolute(cmdline)) {
|
|
|
|
APPEND_STR(cmdline);
|
|
|
|
if (cmdlineUsed)
|
|
|
|
*cmdlineUsed = 1;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
BAIL_OUT;
|
|
|
|
break;
|
|
|
|
case 'R':
|
|
|
|
if (cmdline && !xf86pathIsAbsolute(cmdline)) {
|
|
|
|
APPEND_STR(cmdline);
|
|
|
|
if (cmdlineUsed)
|
|
|
|
*cmdlineUsed = 1;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
BAIL_OUT;
|
|
|
|
break;
|
|
|
|
case 'S':
|
|
|
|
if (cmdline && xf86pathIsSafe(cmdline)) {
|
|
|
|
APPEND_STR(cmdline);
|
|
|
|
if (cmdlineUsed)
|
|
|
|
*cmdlineUsed = 1;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
BAIL_OUT;
|
|
|
|
break;
|
|
|
|
case 'X':
|
|
|
|
APPEND_STR(XConfigFile);
|
|
|
|
break;
|
|
|
|
case 'H':
|
|
|
|
if (!hostname) {
|
|
|
|
if ((hostname = malloc(MAXHOSTNAMELEN + 1))) {
|
|
|
|
if (gethostname(hostname, MAXHOSTNAMELEN) == 0) {
|
|
|
|
hostname[MAXHOSTNAMELEN] = '\0';
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
free(hostname);
|
|
|
|
hostname = NULL;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (hostname)
|
|
|
|
APPEND_STR(hostname);
|
|
|
|
break;
|
|
|
|
case 'E':
|
|
|
|
if (!env)
|
|
|
|
env = getenv(XCONFENV);
|
|
|
|
if (env && xf86pathIsAbsolute(env)) {
|
|
|
|
APPEND_STR(env);
|
|
|
|
if (envUsed)
|
|
|
|
*envUsed = 1;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
BAIL_OUT;
|
|
|
|
break;
|
|
|
|
case 'F':
|
|
|
|
if (!env)
|
|
|
|
env = getenv(XCONFENV);
|
|
|
|
if (env && !xf86pathIsAbsolute(env)) {
|
|
|
|
APPEND_STR(env);
|
|
|
|
if (envUsed)
|
|
|
|
*envUsed = 1;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
BAIL_OUT;
|
|
|
|
break;
|
|
|
|
case 'G':
|
|
|
|
if (!env)
|
|
|
|
env = getenv(XCONFENV);
|
|
|
|
if (env && xf86pathIsSafe(env)) {
|
|
|
|
APPEND_STR(env);
|
|
|
|
if (envUsed)
|
|
|
|
*envUsed = 1;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
BAIL_OUT;
|
|
|
|
break;
|
|
|
|
case 'P':
|
|
|
|
if (projroot && xf86pathIsAbsolute(projroot))
|
|
|
|
APPEND_STR(projroot);
|
|
|
|
else
|
|
|
|
BAIL_OUT;
|
|
|
|
break;
|
|
|
|
case 'C':
|
|
|
|
APPEND_STR(SYSCONFDIR);
|
|
|
|
break;
|
|
|
|
case 'D':
|
|
|
|
APPEND_STR(DATADIR);
|
|
|
|
break;
|
|
|
|
case '%':
|
|
|
|
result[l++] = '%';
|
|
|
|
CHECK_LENGTH;
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
fprintf(stderr, "invalid escape %%%c found in path template\n",
|
|
|
|
template[i]);
|
|
|
|
BAIL_OUT;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2003-11-14 17:48:57 +01:00
|
|
|
#ifdef DEBUG
|
2012-03-21 20:55:09 +01:00
|
|
|
fprintf(stderr, "Converted `%s' to `%s'\n", template, result);
|
2003-11-14 17:48:57 +01:00
|
|
|
#endif
|
2012-03-21 20:55:09 +01:00
|
|
|
return result;
|
2003-11-14 17:48:57 +01:00
|
|
|
}
|
|
|
|
|
2009-12-21 09:04:16 +01:00
|
|
|
/*
|
|
|
|
* Given some searching parameters, locate and open the xorg config file.
|
|
|
|
*/
|
|
|
|
static char *
|
|
|
|
OpenConfigFile(const char *path, const char *cmdline, const char *projroot,
|
2012-03-21 20:55:09 +01:00
|
|
|
const char *confname)
|
2009-12-21 09:04:16 +01:00
|
|
|
{
|
2012-03-21 20:55:09 +01:00
|
|
|
char *filepath = NULL;
|
|
|
|
char *pathcopy;
|
|
|
|
const char *template;
|
|
|
|
int cmdlineUsed = 0;
|
|
|
|
FILE *file = NULL;
|
|
|
|
|
|
|
|
pathcopy = strdup(path);
|
|
|
|
for (template = strtok(pathcopy, ","); template && !file;
|
|
|
|
template = strtok(NULL, ",")) {
|
|
|
|
filepath = DoSubstitution(template, cmdline, projroot,
|
|
|
|
&cmdlineUsed, NULL, confname);
|
|
|
|
if (!filepath)
|
|
|
|
continue;
|
|
|
|
if (cmdline && !cmdlineUsed) {
|
|
|
|
free(filepath);
|
|
|
|
filepath = NULL;
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
file = fopen(filepath, "r");
|
|
|
|
if (!file) {
|
|
|
|
free(filepath);
|
|
|
|
filepath = NULL;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
free(pathcopy);
|
|
|
|
if (file) {
|
|
|
|
configFiles[numFiles].file = file;
|
|
|
|
configFiles[numFiles].path = strdup(filepath);
|
|
|
|
numFiles++;
|
|
|
|
}
|
|
|
|
return filepath;
|
2009-12-21 09:04:16 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Match non-hidden files in the xorg config directory with a .conf
|
|
|
|
* suffix. This filter is passed to scandir(3).
|
|
|
|
*/
|
|
|
|
static int
|
|
|
|
ConfigFilter(const struct dirent *de)
|
|
|
|
{
|
2012-03-21 20:55:09 +01:00
|
|
|
const char *name = de->d_name;
|
|
|
|
size_t len;
|
|
|
|
size_t suflen = strlen(XCONFIGSUFFIX);
|
|
|
|
|
|
|
|
if (!name || name[0] == '.')
|
|
|
|
return 0;
|
|
|
|
len = strlen(name);
|
|
|
|
if (len <= suflen)
|
|
|
|
return 0;
|
|
|
|
if (strcmp(&name[len - suflen], XCONFIGSUFFIX) != 0)
|
|
|
|
return 0;
|
|
|
|
return 1;
|
2009-12-21 09:04:16 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
static Bool
|
|
|
|
AddConfigDirFiles(const char *dirpath, struct dirent **list, int num)
|
|
|
|
{
|
2012-03-21 20:55:09 +01:00
|
|
|
int i;
|
|
|
|
Bool openedFile = FALSE;
|
|
|
|
Bool warnOnce = FALSE;
|
|
|
|
|
|
|
|
for (i = 0; i < num; i++) {
|
|
|
|
char *path;
|
|
|
|
FILE *file;
|
|
|
|
|
|
|
|
if (numFiles >= CONFIG_MAX_FILES) {
|
|
|
|
if (!warnOnce) {
|
|
|
|
ErrorF("Maximum number of configuration " "files opened\n");
|
|
|
|
warnOnce = TRUE;
|
|
|
|
}
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
path = malloc(PATH_MAX + 1);
|
|
|
|
snprintf(path, PATH_MAX + 1, "%s/%s", dirpath, list[i]->d_name);
|
|
|
|
file = fopen(path, "r");
|
|
|
|
if (!file) {
|
|
|
|
free(path);
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
openedFile = TRUE;
|
|
|
|
|
|
|
|
configFiles[numFiles].file = file;
|
|
|
|
configFiles[numFiles].path = path;
|
|
|
|
numFiles++;
|
|
|
|
}
|
|
|
|
|
|
|
|
return openedFile;
|
2009-12-21 09:04:16 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Given some searching parameters, locate and open the xorg config
|
|
|
|
* directory. The directory does not need to contain config files.
|
|
|
|
*/
|
|
|
|
static char *
|
2009-12-21 10:13:44 +01:00
|
|
|
OpenConfigDir(const char *path, const char *cmdline, const char *projroot,
|
2012-03-21 20:55:09 +01:00
|
|
|
const char *confname)
|
2009-12-21 09:04:16 +01:00
|
|
|
{
|
2012-03-21 20:55:09 +01:00
|
|
|
char *dirpath, *pathcopy;
|
|
|
|
const char *template;
|
|
|
|
Bool found = FALSE;
|
|
|
|
int cmdlineUsed = 0;
|
|
|
|
|
|
|
|
pathcopy = strdup(path);
|
|
|
|
for (template = strtok(pathcopy, ","); template && !found;
|
|
|
|
template = strtok(NULL, ",")) {
|
|
|
|
struct dirent **list = NULL;
|
|
|
|
int num;
|
|
|
|
|
|
|
|
dirpath = DoSubstitution(template, cmdline, projroot,
|
|
|
|
&cmdlineUsed, NULL, confname);
|
|
|
|
if (!dirpath)
|
|
|
|
continue;
|
|
|
|
if (cmdline && !cmdlineUsed) {
|
|
|
|
free(dirpath);
|
|
|
|
dirpath = NULL;
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* match files named *.conf */
|
|
|
|
num = scandir(dirpath, &list, ConfigFilter, alphasort);
|
|
|
|
if (num < 0) {
|
|
|
|
list = NULL;
|
|
|
|
num = 0;
|
|
|
|
}
|
|
|
|
found = AddConfigDirFiles(dirpath, list, num);
|
|
|
|
if (!found) {
|
|
|
|
free(dirpath);
|
|
|
|
dirpath = NULL;
|
|
|
|
}
|
|
|
|
while (num--)
|
|
|
|
free(list[num]);
|
|
|
|
free(list);
|
|
|
|
}
|
|
|
|
|
|
|
|
free(pathcopy);
|
|
|
|
return dirpath;
|
2009-12-21 09:04:16 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* xf86initConfigFiles -- Setup global variables and buffers.
|
|
|
|
*/
|
|
|
|
void
|
|
|
|
xf86initConfigFiles(void)
|
|
|
|
{
|
2012-03-21 20:55:09 +01:00
|
|
|
curFileIndex = 0;
|
|
|
|
configPos = 0;
|
|
|
|
configLineNo = 0;
|
|
|
|
pushToken = LOCK_TOKEN;
|
|
|
|
|
|
|
|
configBuf = malloc(CONFIG_BUF_LEN);
|
|
|
|
configRBuf = malloc(CONFIG_BUF_LEN);
|
|
|
|
configBuf[0] = '\0'; /* sanity ... */
|
2009-12-21 09:04:16 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
2003-11-14 17:48:57 +01:00
|
|
|
* xf86openConfigFile --
|
|
|
|
*
|
|
|
|
* This function take a config file search path (optional), a command-line
|
|
|
|
* specified file name (optional) and the ProjectRoot path (optional) and
|
|
|
|
* locates and opens a config file based on that information. If a
|
|
|
|
* command-line file name is specified, then this function fails if none
|
|
|
|
* of the located files.
|
|
|
|
*
|
|
|
|
* The return value is a pointer to the actual name of the file that was
|
2011-10-30 21:04:59 +01:00
|
|
|
* opened. When no file is found, the return value is NULL. The caller should
|
|
|
|
* free() the returned value.
|
2003-11-14 17:48:57 +01:00
|
|
|
*
|
|
|
|
* The escape sequences allowed in the search path are defined above.
|
2009-12-21 09:04:16 +01:00
|
|
|
*
|
2003-11-14 17:48:57 +01:00
|
|
|
*/
|
|
|
|
|
|
|
|
#ifndef DEFAULT_CONF_PATH
|
|
|
|
#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"
|
|
|
|
#endif
|
|
|
|
|
2011-10-30 21:04:59 +01:00
|
|
|
char *
|
2003-11-14 17:48:57 +01:00
|
|
|
xf86openConfigFile(const char *path, const char *cmdline, const char *projroot)
|
|
|
|
{
|
2012-03-21 20:55:09 +01:00
|
|
|
if (!path || !path[0])
|
|
|
|
path = DEFAULT_CONF_PATH;
|
|
|
|
if (!projroot || !projroot[0])
|
|
|
|
projroot = PROJECTROOT;
|
2003-11-14 17:48:57 +01:00
|
|
|
|
2012-03-21 20:55:09 +01:00
|
|
|
/* Search for a config file */
|
|
|
|
return OpenConfigFile(path, cmdline, projroot, XCONFIGFILE);
|
2009-12-21 09:04:16 +01:00
|
|
|
}
|
2003-11-14 17:48:57 +01:00
|
|
|
|
2009-12-21 09:04:16 +01:00
|
|
|
/*
|
|
|
|
* xf86openConfigDirFiles --
|
|
|
|
*
|
|
|
|
* This function take a config directory search path (optional), a
|
|
|
|
* command-line specified directory name (optional) and the ProjectRoot path
|
|
|
|
* (optional) and locates and opens a config directory based on that
|
|
|
|
* information. If a command-line name is specified, then this function
|
|
|
|
* fails if it is not found.
|
|
|
|
*
|
|
|
|
* The return value is a pointer to the actual name of the direcoty that was
|
2011-10-30 21:04:59 +01:00
|
|
|
* opened. When no directory is found, the return value is NULL. The caller
|
|
|
|
* should free() the returned value.
|
2009-12-21 09:04:16 +01:00
|
|
|
*
|
|
|
|
* The escape sequences allowed in the search path are defined above.
|
|
|
|
*
|
|
|
|
*/
|
2011-10-30 21:04:59 +01:00
|
|
|
char *
|
2009-12-21 09:04:16 +01:00
|
|
|
xf86openConfigDirFiles(const char *path, const char *cmdline,
|
2012-03-21 20:55:09 +01:00
|
|
|
const char *projroot)
|
2009-12-21 09:04:16 +01:00
|
|
|
{
|
2012-03-21 20:55:09 +01:00
|
|
|
if (!path || !path[0])
|
|
|
|
path = DEFAULT_CONF_PATH;
|
|
|
|
if (!projroot || !projroot[0])
|
|
|
|
projroot = PROJECTROOT;
|
2003-11-14 17:48:57 +01:00
|
|
|
|
2012-03-21 20:55:09 +01:00
|
|
|
/* Search for the multiconf directory */
|
|
|
|
return OpenConfigDir(path, cmdline, projroot, XCONFIGDIR);
|
2003-11-14 17:48:57 +01:00
|
|
|
}
|
|
|
|
|
Rework symbol visibility for easier maintenance
Save in a few special cases, _X_EXPORT should not be used in C source
files. Instead, it should be used in headers, and the proper C source
include that header. Some special cases are symbols that need to be
shared between modules, but not expected to be used by external drivers,
and symbols that are accessible via LoaderSymbol/dlopen.
This patch also adds conditionally some new sdk header files, depending
on extensions enabled. These files were added to match pattern for
other extensions/modules, that is, have the headers "deciding" symbol
visibility in the sdk. These headers are:
o Xext/panoramiXsrv.h, Xext/panoramiX.h
o fbpict.h (unconditionally)
o vidmodeproc.h
o mioverlay.h (unconditionally, used only by xaa)
o xfixes.h (unconditionally, symbols required by dri2)
LoaderSymbol and similar functions now don't have different prototypes,
in loaderProcs.h and xf86Module.h, so that both headers can be included,
without the need of defining IN_LOADER.
xf86NewInputDevice() device prototype readded to xf86Xinput.h, but
not exported (and with a comment about it).
2008-12-03 08:43:34 +01:00
|
|
|
void
|
2012-03-21 20:55:09 +01:00
|
|
|
xf86closeConfigFile(void)
|
2003-11-14 17:48:57 +01:00
|
|
|
{
|
2012-03-21 20:55:09 +01:00
|
|
|
int i;
|
|
|
|
|
|
|
|
free(configRBuf);
|
|
|
|
configRBuf = NULL;
|
|
|
|
free(configBuf);
|
|
|
|
configBuf = NULL;
|
|
|
|
|
|
|
|
if (numFiles == 0) {
|
|
|
|
builtinConfig = NULL;
|
|
|
|
builtinIndex = 0;
|
|
|
|
}
|
|
|
|
for (i = 0; i < numFiles; i++) {
|
|
|
|
fclose(configFiles[i].file);
|
|
|
|
configFiles[i].file = NULL;
|
|
|
|
free(configFiles[i].path);
|
|
|
|
configFiles[i].path = NULL;
|
|
|
|
}
|
|
|
|
numFiles = 0;
|
2003-11-25 20:29:01 +01:00
|
|
|
}
|
|
|
|
|
Rework symbol visibility for easier maintenance
Save in a few special cases, _X_EXPORT should not be used in C source
files. Instead, it should be used in headers, and the proper C source
include that header. Some special cases are symbols that need to be
shared between modules, but not expected to be used by external drivers,
and symbols that are accessible via LoaderSymbol/dlopen.
This patch also adds conditionally some new sdk header files, depending
on extensions enabled. These files were added to match pattern for
other extensions/modules, that is, have the headers "deciding" symbol
visibility in the sdk. These headers are:
o Xext/panoramiXsrv.h, Xext/panoramiX.h
o fbpict.h (unconditionally)
o vidmodeproc.h
o mioverlay.h (unconditionally, used only by xaa)
o xfixes.h (unconditionally, symbols required by dri2)
LoaderSymbol and similar functions now don't have different prototypes,
in loaderProcs.h and xf86Module.h, so that both headers can be included,
without the need of defining IN_LOADER.
xf86NewInputDevice() device prototype readded to xf86Xinput.h, but
not exported (and with a comment about it).
2008-12-03 08:43:34 +01:00
|
|
|
void
|
2003-11-25 20:29:01 +01:00
|
|
|
xf86setBuiltinConfig(const char *config[])
|
|
|
|
{
|
2012-03-21 20:55:09 +01:00
|
|
|
builtinConfig = config;
|
2003-11-14 17:48:57 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
2012-03-21 20:55:09 +01:00
|
|
|
xf86parseError(const char *format, ...)
|
2003-11-14 17:48:57 +01:00
|
|
|
{
|
2012-03-21 20:55:09 +01:00
|
|
|
va_list ap;
|
|
|
|
const char *filename = numFiles ? configFiles[curFileIndex].path
|
|
|
|
: "<builtin configuration>";
|
2003-11-14 17:48:57 +01:00
|
|
|
|
2012-03-21 20:55:09 +01:00
|
|
|
ErrorF("Parse error on line %d of section %s in file %s\n\t",
|
|
|
|
configLineNo, configSection, filename);
|
|
|
|
va_start(ap, format);
|
|
|
|
VErrorF(format, ap);
|
|
|
|
va_end(ap);
|
2003-11-14 17:48:57 +01:00
|
|
|
|
2012-03-21 20:55:09 +01:00
|
|
|
ErrorF("\n");
|
2003-11-14 17:48:57 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
2012-03-21 20:55:09 +01:00
|
|
|
xf86validationError(const char *format, ...)
|
2003-11-14 17:48:57 +01:00
|
|
|
{
|
2012-03-21 20:55:09 +01:00
|
|
|
va_list ap;
|
|
|
|
const char *filename = numFiles ? configFiles[curFileIndex].path
|
|
|
|
: "<builtin configuration>";
|
2003-11-14 17:48:57 +01:00
|
|
|
|
2012-03-21 20:55:09 +01:00
|
|
|
ErrorF("Data incomplete in file %s\n\t", filename);
|
|
|
|
va_start(ap, format);
|
|
|
|
VErrorF(format, ap);
|
|
|
|
va_end(ap);
|
2003-11-14 17:48:57 +01:00
|
|
|
|
2012-03-21 20:55:09 +01:00
|
|
|
ErrorF("\n");
|
2003-11-14 17:48:57 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
2012-03-21 20:55:09 +01:00
|
|
|
xf86setSection(const char *section)
|
2003-11-14 17:48:57 +01:00
|
|
|
{
|
2012-03-21 20:55:09 +01:00
|
|
|
free(configSection);
|
|
|
|
configSection = strdup(section);
|
2003-11-14 17:48:57 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* xf86getToken --
|
|
|
|
* Lookup a string if it is actually a token in disguise.
|
|
|
|
*/
|
|
|
|
int
|
2012-03-21 20:55:09 +01:00
|
|
|
xf86getStringToken(xf86ConfigSymTabRec * tab)
|
2003-11-14 17:48:57 +01:00
|
|
|
{
|
2012-03-21 20:55:09 +01:00
|
|
|
return StringToToken(val.str, tab);
|
2003-11-14 17:48:57 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
2012-03-21 20:55:09 +01:00
|
|
|
StringToToken(const char *str, xf86ConfigSymTabRec * tab)
|
2003-11-14 17:48:57 +01:00
|
|
|
{
|
2012-03-21 20:55:09 +01:00
|
|
|
int i;
|
2003-11-14 17:48:57 +01:00
|
|
|
|
2012-03-21 20:55:09 +01:00
|
|
|
for (i = 0; tab[i].token != -1; i++) {
|
|
|
|
if (!xf86nameCompare(tab[i].name, str))
|
|
|
|
return tab[i].token;
|
|
|
|
}
|
|
|
|
return ERROR_TOKEN;
|
|
|
|
}
|
2003-11-14 17:48:57 +01:00
|
|
|
|
|
|
|
/*
|
|
|
|
* Compare two names. The characters '_', ' ', and '\t' are ignored
|
|
|
|
* in the comparison.
|
|
|
|
*/
|
Rework symbol visibility for easier maintenance
Save in a few special cases, _X_EXPORT should not be used in C source
files. Instead, it should be used in headers, and the proper C source
include that header. Some special cases are symbols that need to be
shared between modules, but not expected to be used by external drivers,
and symbols that are accessible via LoaderSymbol/dlopen.
This patch also adds conditionally some new sdk header files, depending
on extensions enabled. These files were added to match pattern for
other extensions/modules, that is, have the headers "deciding" symbol
visibility in the sdk. These headers are:
o Xext/panoramiXsrv.h, Xext/panoramiX.h
o fbpict.h (unconditionally)
o vidmodeproc.h
o mioverlay.h (unconditionally, used only by xaa)
o xfixes.h (unconditionally, symbols required by dri2)
LoaderSymbol and similar functions now don't have different prototypes,
in loaderProcs.h and xf86Module.h, so that both headers can be included,
without the need of defining IN_LOADER.
xf86NewInputDevice() device prototype readded to xf86Xinput.h, but
not exported (and with a comment about it).
2008-12-03 08:43:34 +01:00
|
|
|
int
|
2012-03-21 20:55:09 +01:00
|
|
|
xf86nameCompare(const char *s1, const char *s2)
|
2003-11-14 17:48:57 +01:00
|
|
|
{
|
2012-03-21 20:55:09 +01:00
|
|
|
char c1, c2;
|
|
|
|
|
|
|
|
if (!s1 || *s1 == 0) {
|
|
|
|
if (!s2 || *s2 == 0)
|
|
|
|
return 0;
|
|
|
|
else
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
while (*s1 == '_' || *s1 == ' ' || *s1 == '\t')
|
|
|
|
s1++;
|
|
|
|
while (*s2 == '_' || *s2 == ' ' || *s2 == '\t')
|
|
|
|
s2++;
|
|
|
|
c1 = (isupper(*s1) ? tolower(*s1) : *s1);
|
|
|
|
c2 = (isupper(*s2) ? tolower(*s2) : *s2);
|
|
|
|
while (c1 == c2) {
|
|
|
|
if (c1 == '\0')
|
|
|
|
return 0;
|
|
|
|
s1++;
|
|
|
|
s2++;
|
|
|
|
while (*s1 == '_' || *s1 == ' ' || *s1 == '\t')
|
|
|
|
s1++;
|
|
|
|
while (*s2 == '_' || *s2 == ' ' || *s2 == '\t')
|
|
|
|
s2++;
|
|
|
|
c1 = (isupper(*s1) ? tolower(*s1) : *s1);
|
|
|
|
c2 = (isupper(*s2) ? tolower(*s2) : *s2);
|
|
|
|
}
|
|
|
|
return c1 - c2;
|
2003-11-14 17:48:57 +01:00
|
|
|
}
|
|
|
|
|
Rework symbol visibility for easier maintenance
Save in a few special cases, _X_EXPORT should not be used in C source
files. Instead, it should be used in headers, and the proper C source
include that header. Some special cases are symbols that need to be
shared between modules, but not expected to be used by external drivers,
and symbols that are accessible via LoaderSymbol/dlopen.
This patch also adds conditionally some new sdk header files, depending
on extensions enabled. These files were added to match pattern for
other extensions/modules, that is, have the headers "deciding" symbol
visibility in the sdk. These headers are:
o Xext/panoramiXsrv.h, Xext/panoramiX.h
o fbpict.h (unconditionally)
o vidmodeproc.h
o mioverlay.h (unconditionally, used only by xaa)
o xfixes.h (unconditionally, symbols required by dri2)
LoaderSymbol and similar functions now don't have different prototypes,
in loaderProcs.h and xf86Module.h, so that both headers can be included,
without the need of defining IN_LOADER.
xf86NewInputDevice() device prototype readded to xf86Xinput.h, but
not exported (and with a comment about it).
2008-12-03 08:43:34 +01:00
|
|
|
char *
|
2003-11-14 17:48:57 +01:00
|
|
|
xf86addComment(char *cur, char *add)
|
|
|
|
{
|
2012-03-21 20:55:09 +01:00
|
|
|
char *str;
|
|
|
|
int len, curlen, iscomment, hasnewline = 0, insnewline, endnewline;
|
|
|
|
|
|
|
|
if (add == NULL || add[0] == '\0')
|
|
|
|
return cur;
|
|
|
|
|
|
|
|
if (cur) {
|
|
|
|
curlen = strlen(cur);
|
|
|
|
if (curlen)
|
|
|
|
hasnewline = cur[curlen - 1] == '\n';
|
|
|
|
eol_seen = 0;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
curlen = 0;
|
|
|
|
|
|
|
|
str = add;
|
|
|
|
iscomment = 0;
|
|
|
|
while (*str) {
|
|
|
|
if (*str != ' ' && *str != '\t')
|
|
|
|
break;
|
|
|
|
++str;
|
|
|
|
}
|
|
|
|
iscomment = (*str == '#');
|
|
|
|
|
|
|
|
len = strlen(add);
|
|
|
|
endnewline = add[len - 1] == '\n';
|
|
|
|
|
|
|
|
insnewline = eol_seen || (curlen && !hasnewline);
|
|
|
|
if (insnewline)
|
|
|
|
len++;
|
|
|
|
if (!iscomment)
|
|
|
|
len++;
|
|
|
|
if (!endnewline)
|
|
|
|
len++;
|
|
|
|
|
|
|
|
/* Allocate + 1 char for '\0' terminator. */
|
|
|
|
str = realloc(cur, curlen + len + 1);
|
|
|
|
if (!str)
|
|
|
|
return cur;
|
|
|
|
|
|
|
|
cur = str;
|
|
|
|
|
|
|
|
if (insnewline)
|
|
|
|
cur[curlen++] = '\n';
|
|
|
|
if (!iscomment)
|
|
|
|
cur[curlen++] = '#';
|
|
|
|
strcpy(cur + curlen, add);
|
|
|
|
if (!endnewline)
|
|
|
|
strcat(cur, "\n");
|
|
|
|
|
|
|
|
return cur;
|
2003-11-14 17:48:57 +01:00
|
|
|
}
|
2009-10-02 15:28:03 +02:00
|
|
|
|
|
|
|
Bool
|
|
|
|
xf86getBoolValue(Bool *val, const char *str)
|
|
|
|
{
|
2012-03-21 20:55:09 +01:00
|
|
|
if (!val || !str)
|
|
|
|
return FALSE;
|
|
|
|
if (*str == '\0') {
|
|
|
|
*val = TRUE;
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
if (xf86nameCompare(str, "1") == 0)
|
|
|
|
*val = TRUE;
|
|
|
|
else if (xf86nameCompare(str, "on") == 0)
|
|
|
|
*val = TRUE;
|
|
|
|
else if (xf86nameCompare(str, "true") == 0)
|
|
|
|
*val = TRUE;
|
|
|
|
else if (xf86nameCompare(str, "yes") == 0)
|
|
|
|
*val = TRUE;
|
|
|
|
else if (xf86nameCompare(str, "0") == 0)
|
|
|
|
*val = FALSE;
|
|
|
|
else if (xf86nameCompare(str, "off") == 0)
|
|
|
|
*val = FALSE;
|
|
|
|
else if (xf86nameCompare(str, "false") == 0)
|
|
|
|
*val = FALSE;
|
|
|
|
else if (xf86nameCompare(str, "no") == 0)
|
|
|
|
*val = FALSE;
|
|
|
|
else
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
return TRUE;
|
2009-10-02 15:28:03 +02:00
|
|
|
}
|