xfree86: Use xorg.conf.d directory for multiple config files
Currently there is a single file, xorg.conf, for configuring the server. This works fine most of the time, but it becomes a problem when packages or system services need to adjust the configuration. Instead, allow multiple configuration files to live in a directory. Typically this will be /etc/X11/xorg.conf.d. Files with a suffix of .conf will be read and added to the server configuration after xorg.conf. The server won't fall back to using the auto configuration unless there is no config file and there are no files in the config directory. Right now this uses a simpler search template than the config file search path by not using the command line or environment variable parameters. The matching code was refactored a bit to make this more coherent. Any DDX wanting to read the config files will need to call xf86initConfigFiles before opening/reading them. This is to allow xf86openConfigFile without xf86openConfigDirFiles and vice-versa. Signed-off-by: Dan Nicholson <dbn.lists@gmail.com> Reviewed-by: Peter Hutterer <peter.hutterer at who-t.net>
This commit is contained in:
parent
f1e869aca1
commit
efa5269f23
|
@ -1737,6 +1737,7 @@ if test "x$XORG" = xyes; then
|
||||||
|
|
||||||
dnl these only go in xorg-config.h
|
dnl these only go in xorg-config.h
|
||||||
XF86CONFIGFILE="xorg.conf"
|
XF86CONFIGFILE="xorg.conf"
|
||||||
|
XF86CONFIGDIR="xorg.conf.d"
|
||||||
CONFIGFILE="$sysconfdir/$XF86CONFIGFILE"
|
CONFIGFILE="$sysconfdir/$XF86CONFIGFILE"
|
||||||
LOGPREFIX="$logdir/Xorg."
|
LOGPREFIX="$logdir/Xorg."
|
||||||
AC_DEFINE(XORG_SERVER, 1, [Building Xorg server])
|
AC_DEFINE(XORG_SERVER, 1, [Building Xorg server])
|
||||||
|
@ -1749,6 +1750,7 @@ if test "x$XORG" = xyes; then
|
||||||
AC_DEFINE(__XSERVERNAME__, "Xorg", [Name of X server])
|
AC_DEFINE(__XSERVERNAME__, "Xorg", [Name of X server])
|
||||||
AC_DEFINE_DIR(__XCONFIGFILE__, XF86CONFIGFILE, [Name of configuration file])
|
AC_DEFINE_DIR(__XCONFIGFILE__, XF86CONFIGFILE, [Name of configuration file])
|
||||||
AC_DEFINE_DIR(XF86CONFIGFILE, XF86CONFIGFILE, [Name of configuration file])
|
AC_DEFINE_DIR(XF86CONFIGFILE, XF86CONFIGFILE, [Name of configuration file])
|
||||||
|
AC_DEFINE_DIR(__XCONFIGDIR__, XF86CONFIGDIR, [Name of configuration directory])
|
||||||
AC_DEFINE_DIR(DEFAULT_MODULE_PATH, moduledir, [Default module search path])
|
AC_DEFINE_DIR(DEFAULT_MODULE_PATH, moduledir, [Default module search path])
|
||||||
AC_DEFINE_DIR(DEFAULT_LIBRARY_PATH, libdir, [Default library install path])
|
AC_DEFINE_DIR(DEFAULT_LIBRARY_PATH, libdir, [Default library install path])
|
||||||
AC_DEFINE_DIR(DEFAULT_LOGPREFIX, LOGPREFIX, [Default log location])
|
AC_DEFINE_DIR(DEFAULT_LOGPREFIX, LOGPREFIX, [Default log location])
|
||||||
|
|
|
@ -36,7 +36,8 @@ MANDEFS = \
|
||||||
-D__adminmansuffix__=$(ADMIN_MAN_SUFFIX) \
|
-D__adminmansuffix__=$(ADMIN_MAN_SUFFIX) \
|
||||||
-D__mandir__=$(mandir) \
|
-D__mandir__=$(mandir) \
|
||||||
-D__projectroot__=$(prefix) \
|
-D__projectroot__=$(prefix) \
|
||||||
-D__xconfigfile__=$(__XCONFIGFILE__) -D__xconfigdir__=$(XCONFIGDIR) \
|
-D__xconfigfile__=$(__XCONFIGFILE__) \
|
||||||
|
-D__xconfigdir__=$(__XCONFIGDIR__) \
|
||||||
-D__xkbdir__=$(XKB_BASE_DIRECTORY) \
|
-D__xkbdir__=$(XKB_BASE_DIRECTORY) \
|
||||||
-D__modulepath__="$(DEFAULT_MODULE_PATH)" \
|
-D__modulepath__="$(DEFAULT_MODULE_PATH)" \
|
||||||
-D__xlogfile__=$(XLOGFILE) -D__xservername__=$(XSERVERNAME)
|
-D__xlogfile__=$(XLOGFILE) -D__xservername__=$(XSERVERNAME)
|
||||||
|
|
|
@ -272,7 +272,8 @@ xf86AutoConfig(void)
|
||||||
for (cp = builtinConfig; *cp; cp++)
|
for (cp = builtinConfig; *cp; cp++)
|
||||||
xf86ErrorFVerb(3, "\t%s", *cp);
|
xf86ErrorFVerb(3, "\t%s", *cp);
|
||||||
xf86MsgVerb(X_DEFAULT, 3, "--- End of built-in configuration ---\n");
|
xf86MsgVerb(X_DEFAULT, 3, "--- End of built-in configuration ---\n");
|
||||||
|
|
||||||
|
xf86initConfigFiles();
|
||||||
xf86setBuiltinConfig(builtinConfig);
|
xf86setBuiltinConfig(builtinConfig);
|
||||||
ret = xf86HandleConfigFile(TRUE);
|
ret = xf86HandleConfigFile(TRUE);
|
||||||
FreeConfig();
|
FreeConfig();
|
||||||
|
|
|
@ -95,6 +95,13 @@ extern DeviceAssocRec mouse_assoc;
|
||||||
"%P/lib/X11/%X.%H," "%P/lib/X11/%X-%M," \
|
"%P/lib/X11/%X.%H," "%P/lib/X11/%X-%M," \
|
||||||
"%P/lib/X11/%X"
|
"%P/lib/X11/%X"
|
||||||
#endif
|
#endif
|
||||||
|
#ifndef CONFIGDIRPATH
|
||||||
|
#define CONFIGDIRPATH "/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
|
||||||
#ifndef PROJECTROOT
|
#ifndef PROJECTROOT
|
||||||
#define PROJECTROOT "/usr/X11R6"
|
#define PROJECTROOT "/usr/X11R6"
|
||||||
#endif
|
#endif
|
||||||
|
@ -2389,7 +2396,7 @@ checkInput(serverLayoutPtr layout, Bool implicit_layout) {
|
||||||
ConfigStatus
|
ConfigStatus
|
||||||
xf86HandleConfigFile(Bool autoconfig)
|
xf86HandleConfigFile(Bool autoconfig)
|
||||||
{
|
{
|
||||||
const char *filename;
|
const char *filename, *dirname;
|
||||||
char *searchpath;
|
char *searchpath;
|
||||||
MessageType from = X_DEFAULT;
|
MessageType from = X_DEFAULT;
|
||||||
char *scanptr;
|
char *scanptr;
|
||||||
|
@ -2405,7 +2412,9 @@ xf86HandleConfigFile(Bool autoconfig)
|
||||||
if (xf86ConfigFile)
|
if (xf86ConfigFile)
|
||||||
from = X_CMDLINE;
|
from = X_CMDLINE;
|
||||||
|
|
||||||
|
xf86initConfigFiles();
|
||||||
filename = xf86openConfigFile(searchpath, xf86ConfigFile, PROJECTROOT);
|
filename = xf86openConfigFile(searchpath, xf86ConfigFile, PROJECTROOT);
|
||||||
|
dirname = xf86openConfigDirFiles(CONFIGDIRPATH, NULL, PROJECTROOT);
|
||||||
if (filename) {
|
if (filename) {
|
||||||
xf86MsgVerb(from, 0, "Using config file: \"%s\"\n", filename);
|
xf86MsgVerb(from, 0, "Using config file: \"%s\"\n", filename);
|
||||||
xf86ConfigFile = xnfstrdup(filename);
|
xf86ConfigFile = xnfstrdup(filename);
|
||||||
|
@ -2413,10 +2422,14 @@ xf86HandleConfigFile(Bool autoconfig)
|
||||||
if (xf86ConfigFile)
|
if (xf86ConfigFile)
|
||||||
xf86Msg(X_ERROR, "Unable to locate/open config file: \"%s\"\n",
|
xf86Msg(X_ERROR, "Unable to locate/open config file: \"%s\"\n",
|
||||||
xf86ConfigFile);
|
xf86ConfigFile);
|
||||||
return CONFIG_NOFILE;
|
|
||||||
}
|
}
|
||||||
|
if (dirname)
|
||||||
|
xf86MsgVerb(X_DEFAULT, 0, "Using config directory: \"%s\"\n",
|
||||||
|
dirname);
|
||||||
|
if (!filename && !dirname)
|
||||||
|
return CONFIG_NOFILE;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((xf86configptr = xf86readConfigFile ()) == NULL) {
|
if ((xf86configptr = xf86readConfigFile ()) == NULL) {
|
||||||
xf86Msg(X_ERROR, "Problem parsing the config file\n");
|
xf86Msg(X_ERROR, "Problem parsing the config file\n");
|
||||||
return CONFIG_PARSE_ERROR;
|
return CONFIG_PARSE_ERROR;
|
||||||
|
|
|
@ -2,27 +2,35 @@
|
||||||
.ds q \N'34'
|
.ds q \N'34'
|
||||||
.TH __xconfigfile__ __filemansuffix__ __vendorversion__
|
.TH __xconfigfile__ __filemansuffix__ __vendorversion__
|
||||||
.SH NAME
|
.SH NAME
|
||||||
__xconfigfile__ \- configuration File for __xservername__ X server
|
__xconfigfile__ and __xconfigdir__ \- configuration files for
|
||||||
|
__xservername__ X server
|
||||||
.SH INTRODUCTION
|
.SH INTRODUCTION
|
||||||
.B __xservername__
|
.B __xservername__
|
||||||
supports several mechanisms for supplying/obtaining configuration and
|
supports several mechanisms for supplying/obtaining configuration and
|
||||||
run-time parameters: command line options, environment variables, the
|
run-time parameters: command line options, environment variables, the
|
||||||
__xconfigfile__ configuration file, auto-detection, and fallback defaults.
|
__xconfigfile__ and __xconfigdir__ configuration files, auto-detection,
|
||||||
When the same information is supplied in more than one way, the highest
|
and fallback defaults. When the same information is supplied in more
|
||||||
precedence mechanism is used. The list of mechanisms is ordered from
|
than one way, the highest precedence mechanism is used. The list of
|
||||||
highest precedence to lowest. Note that not all parameters can be
|
mechanisms is ordered from highest precedence to lowest. Note that not
|
||||||
supplied via all methods. The available command line options and
|
all parameters can be supplied via all methods. The available command
|
||||||
environment variables (and some defaults) are described in the Xserver(__appmansuffix__)
|
line options and environment variables (and some defaults) are
|
||||||
and __xservername__(__appmansuffix__) manual pages. Most configuration file parameters, with
|
described in the Xserver(__appmansuffix__) and
|
||||||
their defaults, are described below. Driver and module specific
|
__xservername__(__appmansuffix__) manual pages. Most configuration file
|
||||||
configuration parameters are described in the relevant driver or module
|
parameters, with their defaults, are described below. Driver and module
|
||||||
manual page.
|
specific configuration parameters are described in the relevant driver
|
||||||
|
or module manual page.
|
||||||
.SH DESCRIPTION
|
.SH DESCRIPTION
|
||||||
.B __xservername__
|
.B __xservername__
|
||||||
uses a configuration file called
|
uses a configuration file called
|
||||||
.I __xconfigfile__
|
.I __xconfigfile__
|
||||||
|
and files ending in the suffix
|
||||||
|
.I .conf
|
||||||
|
from the directory
|
||||||
|
.I __xconfigdir__
|
||||||
for its initial setup.
|
for its initial setup.
|
||||||
This configuration file is searched for in the following places when the
|
The
|
||||||
|
.I __xconfigfile__
|
||||||
|
configuration file is searched for in the following places when the
|
||||||
server is started as a normal user:
|
server is started as a normal user:
|
||||||
.PP
|
.PP
|
||||||
.RS 4
|
.RS 4
|
||||||
|
@ -93,9 +101,28 @@ directory), and
|
||||||
is the machine's hostname as reported by
|
is the machine's hostname as reported by
|
||||||
.BR gethostname (__libmansuffix__).
|
.BR gethostname (__libmansuffix__).
|
||||||
.PP
|
.PP
|
||||||
|
Additional configuration files are searched for in the following
|
||||||
|
directories:
|
||||||
|
.PP
|
||||||
|
.RS 4
|
||||||
|
.nf
|
||||||
|
.I /etc/X11/__xconfigdir__\-4
|
||||||
|
.I /etc/X11/__xconfigdir__
|
||||||
|
.I /etc/__xconfigdir__
|
||||||
|
.IR __projectroot__/etc/X11/__xconfigdir__. <hostname>
|
||||||
|
.I __projectroot__/etc/X11/__xconfigdir__\-4
|
||||||
|
.I __projectroot__/etc/X11/__xconfigdir__
|
||||||
|
.IR __projectroot__/lib/X11/__xconfigdir__. <hostname>
|
||||||
|
.I __projectroot__/lib/X11/__xconfigdir__\-4
|
||||||
|
.I __projectroot__/lib/X11/__xconfigdir__
|
||||||
|
.fi
|
||||||
|
.RE
|
||||||
|
.PP
|
||||||
The
|
The
|
||||||
.I __xconfigfile__
|
.I __xconfigfile__
|
||||||
file is composed of a number of sections which may be present in any order,
|
and
|
||||||
|
.I __xconfigdir__
|
||||||
|
files are composed of a number of sections which may be present in any order,
|
||||||
or omitted to use default configuration values.
|
or omitted to use default configuration values.
|
||||||
Each section has the form:
|
Each section has the form:
|
||||||
.PP
|
.PP
|
||||||
|
|
|
@ -62,8 +62,11 @@
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <dirent.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
|
#include <X11/Xdefs.h>
|
||||||
#include <X11/Xfuncproto.h>
|
#include <X11/Xfuncproto.h>
|
||||||
|
|
||||||
#if defined(_POSIX_SOURCE)
|
#if defined(_POSIX_SOURCE)
|
||||||
|
@ -90,17 +93,24 @@
|
||||||
#include "xf86tokens.h"
|
#include "xf86tokens.h"
|
||||||
|
|
||||||
#define CONFIG_BUF_LEN 1024
|
#define CONFIG_BUF_LEN 1024
|
||||||
|
#define CONFIG_MAX_FILES 64
|
||||||
|
|
||||||
static int StringToToken (char *, xf86ConfigSymTabRec *);
|
static int StringToToken (char *, xf86ConfigSymTabRec *);
|
||||||
|
|
||||||
static FILE *configFile = NULL;
|
static struct {
|
||||||
|
FILE *file;
|
||||||
|
char *path;
|
||||||
|
} configFiles[CONFIG_MAX_FILES];
|
||||||
static const char **builtinConfig = NULL;
|
static const char **builtinConfig = NULL;
|
||||||
static int builtinIndex = 0;
|
static int builtinIndex = 0;
|
||||||
static int configPos = 0; /* current readers position */
|
static int configPos = 0; /* current readers position */
|
||||||
static int configLineNo = 0; /* linenumber */
|
static int configLineNo = 0; /* linenumber */
|
||||||
static char *configBuf, *configRBuf; /* buffer for lines */
|
static char *configBuf, *configRBuf; /* buffer for lines */
|
||||||
static char *configPath; /* path to config file */
|
static char *configPath; /* path to config file */
|
||||||
|
static char *configDirPath; /* path to config dir */
|
||||||
static char *configSection = NULL; /* name of current section being parsed */
|
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 */
|
||||||
static int pushToken = LOCK_TOKEN;
|
static int pushToken = LOCK_TOKEN;
|
||||||
static int eol_seen = 0; /* private state to handle comments */
|
static int eol_seen = 0; /* private state to handle comments */
|
||||||
LexRec val;
|
LexRec val;
|
||||||
|
@ -155,7 +165,7 @@ xf86strToUL (char *str)
|
||||||
/*
|
/*
|
||||||
* xf86getNextLine --
|
* xf86getNextLine --
|
||||||
*
|
*
|
||||||
* read from the configFile FILE stream until we encounter a new
|
* read from the configFiles FILE stream until we encounter a new
|
||||||
* line; this is effectively just a big wrapper for fgets(3).
|
* line; this is effectively just a big wrapper for fgets(3).
|
||||||
*
|
*
|
||||||
* xf86getToken() assumes that we will read up to the next
|
* xf86getToken() assumes that we will read up to the next
|
||||||
|
@ -213,9 +223,18 @@ xf86getNextLine(void)
|
||||||
/* read in another block of chars */
|
/* read in another block of chars */
|
||||||
|
|
||||||
do {
|
do {
|
||||||
ret = fgets(configBuf + pos, configBufLen - pos - 1, configFile);
|
ret = fgets(configBuf + pos, configBufLen - pos - 1,
|
||||||
|
configFiles[curFileIndex].file);
|
||||||
|
|
||||||
if (!ret) break;
|
if (!ret) {
|
||||||
|
/* stop if there are no more files */
|
||||||
|
if (++curFileIndex >= numFiles) {
|
||||||
|
curFileIndex = 0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
configLineNo = 0;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
/* search for EOL in the new block of chars */
|
/* search for EOL in the new block of chars */
|
||||||
|
|
||||||
|
@ -306,7 +325,7 @@ again:
|
||||||
if (!c)
|
if (!c)
|
||||||
{
|
{
|
||||||
char *ret;
|
char *ret;
|
||||||
if (configFile)
|
if (numFiles > 0)
|
||||||
ret = xf86getNextLine();
|
ret = xf86getNextLine();
|
||||||
else {
|
else {
|
||||||
if (builtinConfig[builtinIndex] == NULL)
|
if (builtinConfig[builtinIndex] == NULL)
|
||||||
|
@ -575,6 +594,12 @@ xf86pathIsSafe(const char *path)
|
||||||
#ifndef XCONFIGFILE
|
#ifndef XCONFIGFILE
|
||||||
#define XCONFIGFILE "xorg.conf"
|
#define XCONFIGFILE "xorg.conf"
|
||||||
#endif
|
#endif
|
||||||
|
#ifndef XCONFIGDIR
|
||||||
|
#define XCONFIGDIR "xorg.conf.d"
|
||||||
|
#endif
|
||||||
|
#ifndef XCONFIGSUFFIX
|
||||||
|
#define XCONFIGSUFFIX ".conf"
|
||||||
|
#endif
|
||||||
#ifndef PROJECTROOT
|
#ifndef PROJECTROOT
|
||||||
#define PROJECTROOT "/usr/X11R6"
|
#define PROJECTROOT "/usr/X11R6"
|
||||||
#endif
|
#endif
|
||||||
|
@ -616,7 +641,8 @@ xf86pathIsSafe(const char *path)
|
||||||
|
|
||||||
static char *
|
static char *
|
||||||
DoSubstitution(const char *template, const char *cmdline, const char *projroot,
|
DoSubstitution(const char *template, const char *cmdline, const char *projroot,
|
||||||
int *cmdlineUsed, int *envUsed, char *XConfigFile)
|
int *cmdlineUsed, int *envUsed,
|
||||||
|
const char *XConfigFile)
|
||||||
{
|
{
|
||||||
char *result;
|
char *result;
|
||||||
int i, l;
|
int i, l;
|
||||||
|
@ -745,7 +771,155 @@ DoSubstitution(const char *template, const char *cmdline, const char *projroot,
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
* Given some searching parameters, locate and open the xorg config file.
|
||||||
|
*/
|
||||||
|
static char *
|
||||||
|
OpenConfigFile(const char *path, const char *cmdline, const char *projroot,
|
||||||
|
const char *confname)
|
||||||
|
{
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (file) {
|
||||||
|
configFiles[numFiles].file = file;
|
||||||
|
configFiles[numFiles].path = strdup(filepath);
|
||||||
|
numFiles++;
|
||||||
|
}
|
||||||
|
return filepath;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 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)
|
||||||
|
{
|
||||||
|
const char *name = de->d_name;
|
||||||
|
size_t len = strlen(name);
|
||||||
|
size_t suflen = strlen(XCONFIGSUFFIX);
|
||||||
|
|
||||||
|
if (!name || name[0] == '.' || len <= suflen)
|
||||||
|
return 0;
|
||||||
|
if (strcmp(&name[len-suflen], XCONFIGSUFFIX) != 0)
|
||||||
|
return 0;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static Bool
|
||||||
|
AddConfigDirFiles(const char *dirpath, struct dirent **list, int num)
|
||||||
|
{
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
free(list[i]);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
path = malloc(PATH_MAX + 1);
|
||||||
|
snprintf(path, PATH_MAX + 1, "%s/%s", dirpath,
|
||||||
|
list[i]->d_name);
|
||||||
|
free(list[i]);
|
||||||
|
file = fopen(path, "r");
|
||||||
|
if (!file) {
|
||||||
|
free(path);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
openedFile = TRUE;
|
||||||
|
|
||||||
|
configFiles[numFiles].file = file;
|
||||||
|
configFiles[numFiles].path = path;
|
||||||
|
numFiles++;
|
||||||
|
}
|
||||||
|
|
||||||
|
return openedFile;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Given some searching parameters, locate and open the xorg config
|
||||||
|
* directory. The directory does not need to contain config files.
|
||||||
|
*/
|
||||||
|
static char *
|
||||||
|
OpenConfigDir(const char *path, const char *projroot, const char *confname)
|
||||||
|
{
|
||||||
|
char *dirpath, *pathcopy;
|
||||||
|
const char *template;
|
||||||
|
Bool found = FALSE;
|
||||||
|
|
||||||
|
pathcopy = strdup(path);
|
||||||
|
for (template = strtok(pathcopy, ","); template && !found;
|
||||||
|
template = strtok(NULL, ",")) {
|
||||||
|
struct dirent **list = NULL;
|
||||||
|
int num;
|
||||||
|
|
||||||
|
if (!(dirpath = DoSubstitution(template, NULL, projroot,
|
||||||
|
NULL, NULL, confname)))
|
||||||
|
continue;
|
||||||
|
/* match files named *.conf */
|
||||||
|
num = scandir(dirpath, &list, ConfigFilter, alphasort);
|
||||||
|
found = AddConfigDirFiles(dirpath, list, num);
|
||||||
|
if (!found) {
|
||||||
|
free(dirpath);
|
||||||
|
dirpath = NULL;
|
||||||
|
if (list)
|
||||||
|
free(list);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return dirpath;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* xf86initConfigFiles -- Setup global variables and buffers.
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
xf86initConfigFiles(void)
|
||||||
|
{
|
||||||
|
curFileIndex = 0;
|
||||||
|
configPos = 0;
|
||||||
|
configLineNo = 0;
|
||||||
|
pushToken = LOCK_TOKEN;
|
||||||
|
|
||||||
|
configBuf = malloc(CONFIG_BUF_LEN);
|
||||||
|
configRBuf = malloc(CONFIG_BUF_LEN);
|
||||||
|
configBuf[0] = '\0'; /* sanity ... */
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
* xf86openConfigFile --
|
* xf86openConfigFile --
|
||||||
*
|
*
|
||||||
* This function take a config file search path (optional), a command-line
|
* This function take a config file search path (optional), a command-line
|
||||||
|
@ -758,7 +932,7 @@ DoSubstitution(const char *template, const char *cmdline, const char *projroot,
|
||||||
* opened. When no file is found, the return value is NULL.
|
* opened. When no file is found, the return value is NULL.
|
||||||
*
|
*
|
||||||
* The escape sequences allowed in the search path are defined above.
|
* The escape sequences allowed in the search path are defined above.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef DEFAULT_CONF_PATH
|
#ifndef DEFAULT_CONF_PATH
|
||||||
|
@ -780,117 +954,90 @@ DoSubstitution(const char *template, const char *cmdline, const char *projroot,
|
||||||
const char *
|
const char *
|
||||||
xf86openConfigFile(const char *path, const char *cmdline, const char *projroot)
|
xf86openConfigFile(const char *path, const char *cmdline, const char *projroot)
|
||||||
{
|
{
|
||||||
char *pathcopy;
|
|
||||||
const char *template;
|
|
||||||
int cmdlineUsed = 0;
|
|
||||||
|
|
||||||
configFile = NULL;
|
|
||||||
configPos = 0; /* current readers position */
|
|
||||||
configLineNo = 0; /* linenumber */
|
|
||||||
pushToken = LOCK_TOKEN;
|
|
||||||
|
|
||||||
if (!path || !path[0])
|
if (!path || !path[0])
|
||||||
path = DEFAULT_CONF_PATH;
|
path = DEFAULT_CONF_PATH;
|
||||||
pathcopy = malloc(strlen(path) + 1);
|
|
||||||
strcpy(pathcopy, path);
|
|
||||||
if (!projroot || !projroot[0])
|
if (!projroot || !projroot[0])
|
||||||
projroot = PROJECTROOT;
|
projroot = PROJECTROOT;
|
||||||
|
|
||||||
template = strtok(pathcopy, ",");
|
/* Search for a config file or a fallback */
|
||||||
|
configPath = OpenConfigFile(path, cmdline, projroot, XCONFIGFILE);
|
||||||
/* First, search for a config file. */
|
if (!configPath)
|
||||||
while (template && !configFile) {
|
configPath = OpenConfigFile(path, cmdline, projroot,
|
||||||
if ((configPath = DoSubstitution(template, cmdline, projroot,
|
XFREE86CFGFILE);
|
||||||
&cmdlineUsed, NULL,
|
|
||||||
XCONFIGFILE))) {
|
|
||||||
if ((configFile = fopen(configPath, "r")) != 0) {
|
|
||||||
if (cmdline && !cmdlineUsed) {
|
|
||||||
fclose(configFile);
|
|
||||||
configFile = NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (configPath && !configFile) {
|
|
||||||
free(configPath);
|
|
||||||
configPath = NULL;
|
|
||||||
}
|
|
||||||
template = strtok(NULL, ",");
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Then search for fallback */
|
|
||||||
if (!configFile) {
|
|
||||||
strcpy(pathcopy, path);
|
|
||||||
template = strtok(pathcopy, ",");
|
|
||||||
|
|
||||||
while (template && !configFile) {
|
|
||||||
if ((configPath = DoSubstitution(template, cmdline, projroot,
|
|
||||||
&cmdlineUsed, NULL,
|
|
||||||
XFREE86CFGFILE))) {
|
|
||||||
if ((configFile = fopen(configPath, "r")) != 0) {
|
|
||||||
if (cmdline && !cmdlineUsed) {
|
|
||||||
fclose(configFile);
|
|
||||||
configFile = NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (configPath && !configFile) {
|
|
||||||
free(configPath);
|
|
||||||
configPath = NULL;
|
|
||||||
}
|
|
||||||
template = strtok(NULL, ",");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
free(pathcopy);
|
|
||||||
if (!configFile) {
|
|
||||||
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
configBuf = malloc (CONFIG_BUF_LEN);
|
|
||||||
configRBuf = malloc (CONFIG_BUF_LEN);
|
|
||||||
configBuf[0] = '\0'; /* sanity ... */
|
|
||||||
|
|
||||||
return configPath;
|
return configPath;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 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
|
||||||
|
* opened. When no directory is found, the return value is NULL.
|
||||||
|
*
|
||||||
|
* The escape sequences allowed in the search path are defined above.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
const char *
|
||||||
|
xf86openConfigDirFiles(const char *path, const char *cmdline,
|
||||||
|
const char *projroot)
|
||||||
|
{
|
||||||
|
if (!path || !path[0])
|
||||||
|
path = DEFAULT_CONF_PATH;
|
||||||
|
if (!projroot || !projroot[0])
|
||||||
|
projroot = PROJECTROOT;
|
||||||
|
|
||||||
|
/* Search for the multiconf directory */
|
||||||
|
configDirPath = OpenConfigDir(path, projroot, XCONFIGDIR);
|
||||||
|
return configDirPath;
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
xf86closeConfigFile (void)
|
xf86closeConfigFile (void)
|
||||||
{
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
free (configPath);
|
free (configPath);
|
||||||
configPath = NULL;
|
configPath = NULL;
|
||||||
|
free (configDirPath);
|
||||||
|
configDirPath = NULL;
|
||||||
free (configRBuf);
|
free (configRBuf);
|
||||||
configRBuf = NULL;
|
configRBuf = NULL;
|
||||||
free (configBuf);
|
free (configBuf);
|
||||||
configBuf = NULL;
|
configBuf = NULL;
|
||||||
|
|
||||||
if (configFile) {
|
if (numFiles == 0) {
|
||||||
fclose (configFile);
|
|
||||||
configFile = NULL;
|
|
||||||
} else {
|
|
||||||
builtinConfig = NULL;
|
builtinConfig = NULL;
|
||||||
builtinIndex = 0;
|
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;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
xf86setBuiltinConfig(const char *config[])
|
xf86setBuiltinConfig(const char *config[])
|
||||||
{
|
{
|
||||||
builtinConfig = config;
|
builtinConfig = config;
|
||||||
configPath = strdup("<builtin configuration>");
|
|
||||||
configBuf = malloc (CONFIG_BUF_LEN);
|
|
||||||
configRBuf = malloc (CONFIG_BUF_LEN);
|
|
||||||
configBuf[0] = '\0'; /* sanity ... */
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
xf86parseError (char *format,...)
|
xf86parseError (char *format,...)
|
||||||
{
|
{
|
||||||
va_list ap;
|
va_list ap;
|
||||||
|
char *filename = numFiles ? configFiles[curFileIndex].path :
|
||||||
|
"<builtin configuration>";
|
||||||
|
|
||||||
ErrorF ("Parse error on line %d of section %s in file %s\n\t",
|
ErrorF ("Parse error on line %d of section %s in file %s\n\t",
|
||||||
configLineNo, configSection, configPath);
|
configLineNo, configSection, filename);
|
||||||
va_start (ap, format);
|
va_start (ap, format);
|
||||||
VErrorF (format, ap);
|
VErrorF (format, ap);
|
||||||
va_end (ap);
|
va_end (ap);
|
||||||
|
@ -902,8 +1049,10 @@ void
|
||||||
xf86validationError (char *format,...)
|
xf86validationError (char *format,...)
|
||||||
{
|
{
|
||||||
va_list ap;
|
va_list ap;
|
||||||
|
char *filename = numFiles ? configFiles[curFileIndex].path :
|
||||||
|
"<builtin configuration>";
|
||||||
|
|
||||||
ErrorF ("Data incomplete in file %s\n\t", configPath);
|
ErrorF ("Data incomplete in file %s\n\t", filename);
|
||||||
va_start (ap, format);
|
va_start (ap, format);
|
||||||
VErrorF (format, ap);
|
VErrorF (format, ap);
|
||||||
va_end (ap);
|
va_end (ap);
|
||||||
|
|
|
@ -456,8 +456,11 @@ xf86ConfigSymTabRec, *xf86ConfigSymTabPtr;
|
||||||
/*
|
/*
|
||||||
* prototypes for public functions
|
* prototypes for public functions
|
||||||
*/
|
*/
|
||||||
extern const char *xf86openConfigFile(const char *, const char *,
|
extern void xf86initConfigFiles(void);
|
||||||
const char *);
|
extern const char *xf86openConfigFile(const char *path, const char *cmdline,
|
||||||
|
const char *projroot);
|
||||||
|
extern const char *xf86openConfigDirFiles(const char *path, const char *cmdline,
|
||||||
|
const char *projroot);
|
||||||
extern void xf86setBuiltinConfig(const char *config[]);
|
extern void xf86setBuiltinConfig(const char *config[]);
|
||||||
extern XF86ConfigPtr xf86readConfigFile(void);
|
extern XF86ConfigPtr xf86readConfigFile(void);
|
||||||
extern void xf86closeConfigFile(void);
|
extern void xf86closeConfigFile(void);
|
||||||
|
|
|
@ -50,6 +50,13 @@
|
||||||
"%P/lib/X11/%X.%H," "%P/lib/X11/%X-%M," \
|
"%P/lib/X11/%X.%H," "%P/lib/X11/%X-%M," \
|
||||||
"%P/lib/X11/%X"
|
"%P/lib/X11/%X"
|
||||||
#endif
|
#endif
|
||||||
|
#ifndef CONFIGDIRPATH
|
||||||
|
#define CONFIGDIRPATH "/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
|
||||||
|
|
||||||
XF86ConfigPtr g_xf86configptr = NULL;
|
XF86ConfigPtr g_xf86configptr = NULL;
|
||||||
#endif
|
#endif
|
||||||
|
@ -109,7 +116,7 @@ Bool
|
||||||
winReadConfigfile ()
|
winReadConfigfile ()
|
||||||
{
|
{
|
||||||
Bool retval = TRUE;
|
Bool retval = TRUE;
|
||||||
const char *filename;
|
const char *filename, *dirname;
|
||||||
MessageType from = X_DEFAULT;
|
MessageType from = X_DEFAULT;
|
||||||
char *xf86ConfigFile = NULL;
|
char *xf86ConfigFile = NULL;
|
||||||
|
|
||||||
|
@ -120,9 +127,10 @@ winReadConfigfile ()
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Parse config file into data structure */
|
/* Parse config file into data structure */
|
||||||
|
xf86initConfigFiles();
|
||||||
filename = xf86openConfigFile (CONFIGPATH, xf86ConfigFile, PROJECTROOT);
|
filename = xf86openConfigFile (CONFIGPATH, xf86ConfigFile, PROJECTROOT);
|
||||||
|
dirname = xf86openConfigDirFiles (CONFIGDIRPATH, NULL, PROJECTROOT);
|
||||||
|
|
||||||
/* Hack for backward compatibility */
|
/* Hack for backward compatibility */
|
||||||
if (!filename && from == X_DEFAULT)
|
if (!filename && from == X_DEFAULT)
|
||||||
filename = xf86openConfigFile (CONFIGPATH, "XF86Config", PROJECTROOT);
|
filename = xf86openConfigFile (CONFIGPATH, "XF86Config", PROJECTROOT);
|
||||||
|
@ -137,6 +145,13 @@ winReadConfigfile ()
|
||||||
if (xf86ConfigFile)
|
if (xf86ConfigFile)
|
||||||
ErrorF (": \"%s\"", xf86ConfigFile);
|
ErrorF (": \"%s\"", xf86ConfigFile);
|
||||||
ErrorF ("\n");
|
ErrorF ("\n");
|
||||||
|
}
|
||||||
|
if (dirname)
|
||||||
|
{
|
||||||
|
winMsg (from, "Using config directory: \"%s\"\n", dirname);
|
||||||
|
}
|
||||||
|
if (!filename && !dirname)
|
||||||
|
{
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
if ((g_xf86configptr = xf86readConfigFile ()) == NULL)
|
if ((g_xf86configptr = xf86readConfigFile ()) == NULL)
|
||||||
|
|
|
@ -36,6 +36,9 @@
|
||||||
/* Path to configuration file. */
|
/* Path to configuration file. */
|
||||||
#undef __XCONFIGFILE__
|
#undef __XCONFIGFILE__
|
||||||
|
|
||||||
|
/* Name of configuration directory. */
|
||||||
|
#undef __XCONFIGDIR__
|
||||||
|
|
||||||
/* Path to loadable modules. */
|
/* Path to loadable modules. */
|
||||||
#undef DEFAULT_MODULE_PATH
|
#undef DEFAULT_MODULE_PATH
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue