[PATCH v4 2/3] xfree86: Use xorg.conf.d directory for multiple config files

Peter Hutterer peter.hutterer at who-t.net
Mon Dec 21 16:11:46 PST 2009


On Mon, Dec 21, 2009 at 12:35:08PM -0800, Dan Nicholson wrote:
> 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 at gmail.com>
> ---
>  configure.ac                         |    2 +
>  cpprules.in                          |    3 +-
>  hw/xfree86/common/xf86AutoConfig.c   |    3 +-
>  hw/xfree86/common/xf86Config.c       |   19 ++-
>  hw/xfree86/doc/man/xorg.conf.man.pre |   53 +++++--
>  hw/xfree86/parser/scan.c             |  317 +++++++++++++++++++++++++---------
>  hw/xfree86/parser/xf86Parser.h       |    7 +-
>  hw/xwin/winconfig.c                  |   21 ++-
>  include/xorg-config.h.in             |    3 +
>  9 files changed, 321 insertions(+), 107 deletions(-)
> 
> diff --git a/configure.ac b/configure.ac
> index 6cdef15..950dee0 100644
> --- a/configure.ac
> +++ b/configure.ac
> @@ -1720,6 +1720,7 @@ if test "x$XORG" = xyes; then
>  
>  	dnl these only go in xorg-config.h
>  	XF86CONFIGFILE="xorg.conf"
> +	XF86CONFIGDIR="xorg.conf.d"
>  	CONFIGFILE="$sysconfdir/$XF86CONFIGFILE"
>  	LOGPREFIX="$logdir/Xorg."
>  	AC_DEFINE(XORG_SERVER, 1, [Building Xorg server])
> @@ -1732,6 +1733,7 @@ if test "x$XORG" = xyes; then
>  	AC_DEFINE(__XSERVERNAME__, "Xorg", [Name of X server])
>  	AC_DEFINE_DIR(__XCONFIGFILE__, 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_LIBRARY_PATH, libdir, [Default library install path])
>  	AC_DEFINE_DIR(DEFAULT_LOGPREFIX, LOGPREFIX, [Default log location])
> diff --git a/cpprules.in b/cpprules.in
> index 7fcb9bd..7219e36 100644
> --- a/cpprules.in
> +++ b/cpprules.in
> @@ -36,7 +36,8 @@ MANDEFS = \
>  	-D__adminmansuffix__=$(ADMIN_MAN_SUFFIX) \
>  	-D__mandir__=$(mandir) \
>  	-D__projectroot__=$(prefix) \
> -	-D__xconfigfile__=$(__XCONFIGFILE__) -D__xconfigdir__=$(XCONFIGDIR) \
> +	-D__xconfigfile__=$(__XCONFIGFILE__) \
> +	-D__xconfigdir__=$(__XCONFIGDIR__) \
>  	-D__xkbdir__=$(XKB_BASE_DIRECTORY) \
>  	-D__modulepath__="$(DEFAULT_MODULE_PATH)" \
>  	-D__xlogfile__=$(XLOGFILE) -D__xservername__=$(XSERVERNAME) 
> diff --git a/hw/xfree86/common/xf86AutoConfig.c b/hw/xfree86/common/xf86AutoConfig.c
> index a6199b0..1c4595e 100644
> --- a/hw/xfree86/common/xf86AutoConfig.c
> +++ b/hw/xfree86/common/xf86AutoConfig.c
> @@ -272,7 +272,8 @@ xf86AutoConfig(void)
>      for (cp = builtinConfig; *cp; cp++)
>  	xf86ErrorFVerb(3, "\t%s", *cp);
>      xf86MsgVerb(X_DEFAULT, 3, "--- End of built-in configuration ---\n");
> -    
> +
> +    xf86initConfigFiles();
>      xf86setBuiltinConfig(builtinConfig);
>      ret = xf86HandleConfigFile(TRUE);
>      FreeConfig();
> diff --git a/hw/xfree86/common/xf86Config.c b/hw/xfree86/common/xf86Config.c
> index e1283f9..d718814 100644
> --- a/hw/xfree86/common/xf86Config.c
> +++ b/hw/xfree86/common/xf86Config.c
> @@ -102,6 +102,13 @@ extern DeviceAssocRec mouse_assoc;
>  			"%P/lib/X11/%X.%H," "%P/lib/X11/%X-%M," \
>  			"%P/lib/X11/%X"
>  #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
>  #define PROJECTROOT	"/usr/X11R6"
>  #endif
> @@ -2437,7 +2444,7 @@ checkInput(serverLayoutPtr layout, Bool implicit_layout) {
>  ConfigStatus
>  xf86HandleConfigFile(Bool autoconfig)
>  {
> -    const char *filename;
> +    const char *filename, *dirname;
>      char *searchpath;
>      MessageType from = X_DEFAULT;
>      char *scanptr;
> @@ -2453,7 +2460,9 @@ xf86HandleConfigFile(Bool autoconfig)
>  	if (xf86ConfigFile)
>  	    from = X_CMDLINE;
>  
> +	xf86initConfigFiles();
>  	filename = xf86openConfigFile(searchpath, xf86ConfigFile, PROJECTROOT);
> +	dirname = xf86openConfigDirFiles(CONFIGDIRPATH, NULL, PROJECTROOT);
>  	if (filename) {
>  	    xf86MsgVerb(from, 0, "Using config file: \"%s\"\n", filename);
>  	    xf86ConfigFile = xnfstrdup(filename);
> @@ -2461,10 +2470,14 @@ xf86HandleConfigFile(Bool autoconfig)
>  	    if (xf86ConfigFile)
>  		xf86Msg(X_ERROR, "Unable to locate/open config file: \"%s\"\n",
>  			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) {
>  	xf86Msg(X_ERROR, "Problem parsing the config file\n");
>  	return CONFIG_PARSE_ERROR;
> diff --git a/hw/xfree86/doc/man/xorg.conf.man.pre b/hw/xfree86/doc/man/xorg.conf.man.pre
> index ace041c..60ce512 100644
> --- a/hw/xfree86/doc/man/xorg.conf.man.pre
> +++ b/hw/xfree86/doc/man/xorg.conf.man.pre
> @@ -2,27 +2,35 @@
>  .ds q \N'34'
>  .TH __xconfigfile__ __filemansuffix__ __vendorversion__
>  .SH NAME
> -__xconfigfile__ \- configuration File for __xservername__ X server
> +__xconfigfile__ and __xconfigdir__ \- configuration files for
> +__xservername__ X server
>  .SH INTRODUCTION
>  .B __xservername__
>  supports several mechanisms for supplying/obtaining configuration and
>  run-time parameters: command line options, environment variables, the
> -__xconfigfile__ configuration file, auto-detection, and fallback defaults.
> -When the same information is supplied in more than one way, the highest
> -precedence mechanism is used.  The list of mechanisms is ordered from
> -highest precedence to lowest.  Note that not all parameters can be
> -supplied via all methods.  The available command line options and
> -environment variables (and some defaults) are described in the Xserver(__appmansuffix__)
> -and __xservername__(__appmansuffix__) manual pages.  Most configuration file parameters, with
> -their defaults, are described below.  Driver and module specific
> -configuration parameters are described in the relevant driver or module
> -manual page.
> +__xconfigfile__ and __xconfigdir__ configuration files, auto-detection,
> +and fallback defaults. When the same information is supplied in more
> +than one way, the highest precedence mechanism is used. The list of
> +mechanisms is ordered from highest precedence to lowest. Note that not
> +all parameters can be supplied via all methods. The available command
> +line options and environment variables (and some defaults) are
> +described in the Xserver(__appmansuffix__) and
> +__xservername__(__appmansuffix__) manual pages. Most configuration file
> +parameters, with their defaults, are described below. Driver and module
> +specific configuration parameters are described in the relevant driver
> +or module manual page.
>  .SH DESCRIPTION
>  .B __xservername__
>  uses a configuration file called
>  .I __xconfigfile__
> +and files ending in the suffix
> +.I .conf
> +from the directory
> +.I __xconfigdir__
>  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:
>  .PP
>  .RS 4
> @@ -93,9 +101,28 @@ directory), and
>  is the machine's hostname as reported by
>  .BR gethostname (__libmansuffix__).
>  .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
>  .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.
>  Each section has the form:
>  .PP
> diff --git a/hw/xfree86/parser/scan.c b/hw/xfree86/parser/scan.c
> index d2e8b6d..24260e2 100644
> --- a/hw/xfree86/parser/scan.c
> +++ b/hw/xfree86/parser/scan.c
> @@ -62,8 +62,11 @@
>  #include <stdio.h>
>  #include <stdlib.h>
>  #include <string.h>
> +#include <sys/types.h>
> +#include <dirent.h>
>  #include <unistd.h>
>  #include <stdarg.h>
> +#include <X11/Xdefs.h>
>  #include <X11/Xfuncproto.h>
>  
>  #if defined(_POSIX_SOURCE)
> @@ -90,17 +93,24 @@
>  #include "xf86tokens.h"
>  
>  #define CONFIG_BUF_LEN     1024
> +#define CONFIG_MAX_FILES   64
>  
>  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 int builtinIndex = 0;
>  static int configPos = 0;		/* current readers position */
>  static int configLineNo = 0;	/* linenumber */
>  static char *configBuf, *configRBuf;	/* buffer for lines */
>  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 int numFiles = 0;		/* number of config files */
> +static int curFileIndex = 0;		/* index of current config file */
>  static int pushToken = LOCK_TOKEN;
>  static int eol_seen = 0;		/* private state to handle comments */
>  LexRec val;
> @@ -155,7 +165,7 @@ xf86strToUL (char *str)
>  /*
>   * 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).
>   *
>   *  xf86getToken() assumes that we will read up to the next
> @@ -213,9 +223,18 @@ xf86getNextLine(void)
>  	/* read in another block of chars */
>  
>  	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 */
>  
> @@ -306,7 +325,7 @@ again:
>  		if (!c)
>  		{
>  			char *ret;
> -			if (configFile)
> +			if (numFiles > 0)
>  				ret = xf86getNextLine();
>  			else {
>  				if (builtinConfig[builtinIndex] == NULL)
> @@ -575,6 +594,12 @@ xf86pathIsSafe(const char *path)
>  #ifndef XCONFIGFILE
>  #define XCONFIGFILE	"xorg.conf"
>  #endif
> +#ifndef XCONFIGDIR
> +#define XCONFIGDIR	"xorg.conf.d"
> +#endif
> +#ifndef XCONFIGSUFFIX
> +#define XCONFIGSUFFIX	".conf"
> +#endif
>  #ifndef PROJECTROOT
>  #define PROJECTROOT	"/usr/X11R6"
>  #endif
> @@ -616,7 +641,8 @@ xf86pathIsSafe(const char *path)
>  
>  static char *
>  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;
>  	int i, l;
> @@ -745,7 +771,155 @@ DoSubstitution(const char *template, const char *cmdline, const char *projroot,
>  	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 --
>   *
>   * 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.
>   *
>   * The escape sequences allowed in the search path are defined above.
> - *  
> + *
>   */
>  
>  #ifndef DEFAULT_CONF_PATH
> @@ -780,117 +954,90 @@ DoSubstitution(const char *template, const char *cmdline, const char *projroot,
>  const char *
>  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])
>  		path = DEFAULT_CONF_PATH;
> -	pathcopy = malloc(strlen(path) + 1);
> -	strcpy(pathcopy, path);
>  	if (!projroot || !projroot[0])
>  		projroot = PROJECTROOT;
>  
> -	template = strtok(pathcopy, ",");
> -
> -	/* First, search for a config file. */
> -	while (template && !configFile) {
> -		if ((configPath = DoSubstitution(template, cmdline, projroot,
> -						 &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;
> -	}
> +	/* Search for a config file or a fallback */
> +	configPath = OpenConfigFile(path, cmdline, projroot, XCONFIGFILE);
> +	if (!configPath)
> +		configPath = OpenConfigFile(path, cmdline, projroot,
> +					    XFREE86CFGFILE);
> +	return configPath;
> +}
>  
> -	configBuf = malloc (CONFIG_BUF_LEN);
> -	configRBuf = malloc (CONFIG_BUF_LEN);
> -	configBuf[0] = '\0';		/* sanity ... */
> +/*
> + * 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;
>  
> -	return configPath;
> +	/* Search for the multiconf directory */
> +	configDirPath = OpenConfigDir(path, projroot, XCONFIGDIR);
> +	return configDirPath;
>  }
>  
>  void
>  xf86closeConfigFile (void)
>  {
> +	int i;
> +
>  	free (configPath);
>  	configPath = NULL;
> +	free (configDirPath);
> +	configDirPath = NULL;
>  	free (configRBuf);
>  	configRBuf = NULL;
>  	free (configBuf);
>  	configBuf = NULL;
>  
> -	if (configFile) {
> -		fclose (configFile);
> -		configFile = NULL;
> -	} else {
> +	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;
>  }
>  
>  void
>  xf86setBuiltinConfig(const char *config[])
>  {
>  	builtinConfig = config;
> -	configPath = strdup("<builtin configuration>");
> -	configBuf = malloc (CONFIG_BUF_LEN);
> -	configRBuf = malloc (CONFIG_BUF_LEN);
> -	configBuf[0] = '\0';		/* sanity ... */
> -
>  }
>  
>  void
>  xf86parseError (char *format,...)
>  {
>  	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",
> -		 configLineNo, configSection, configPath);
> +		 configLineNo, configSection, filename);
>  	va_start (ap, format);
>  	VErrorF (format, ap);
>  	va_end (ap);
> @@ -902,8 +1049,10 @@ void
>  xf86validationError (char *format,...)
>  {
>  	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);
>  	VErrorF (format, ap);
>  	va_end (ap);
> diff --git a/hw/xfree86/parser/xf86Parser.h b/hw/xfree86/parser/xf86Parser.h
> index efa1b85..12bcd6e 100644
> --- a/hw/xfree86/parser/xf86Parser.h
> +++ b/hw/xfree86/parser/xf86Parser.h
> @@ -456,8 +456,11 @@ xf86ConfigSymTabRec, *xf86ConfigSymTabPtr;
>  /*
>   * prototypes for public functions
>   */
> -extern const char *xf86openConfigFile(const char *, const char *,
> -				      const char *);
> +extern void xf86initConfigFiles(void);
> +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 XF86ConfigPtr xf86readConfigFile(void);
>  extern void xf86closeConfigFile(void);
> diff --git a/hw/xwin/winconfig.c b/hw/xwin/winconfig.c
> index 3e1908c..6efd7ca 100644
> --- a/hw/xwin/winconfig.c
> +++ b/hw/xwin/winconfig.c
> @@ -50,6 +50,13 @@
>                      "%P/lib/X11/%X.%H," "%P/lib/X11/%X-%M," \
>                      "%P/lib/X11/%X"
>  #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;
>  #endif
> @@ -109,7 +116,7 @@ Bool
>  winReadConfigfile ()
>  {
>    Bool		retval = TRUE;
> -  const char	*filename;
> +  const char	*filename, *dirname;
>    MessageType	from = X_DEFAULT;
>    char		*xf86ConfigFile = NULL;
>  
> @@ -120,9 +127,10 @@ winReadConfigfile ()
>      }
>  
>    /* Parse config file into data structure */
> -
> +  xf86initConfigFiles();
>    filename = xf86openConfigFile (CONFIGPATH, xf86ConfigFile, PROJECTROOT);
> -    
> +  dirname = xf86openConfigDirFiles (CONFIGDIRPATH, NULL, PROJECTROOT);
> +
>    /* Hack for backward compatibility */
>    if (!filename && from == X_DEFAULT)
>      filename = xf86openConfigFile (CONFIGPATH, "XF86Config", PROJECTROOT);
> @@ -137,6 +145,13 @@ winReadConfigfile ()
>        if (xf86ConfigFile)
>  	ErrorF (": \"%s\"", xf86ConfigFile);
>        ErrorF ("\n");
> +    }
> +  if (dirname)
> +    {
> +      winMsg (from, "Using config directory: \"%s\"\n", dirname);
> +    }
> +  if (!filename && !dirname)
> +    {
>        return FALSE;
>      }
>    if ((g_xf86configptr = xf86readConfigFile ()) == NULL)
> diff --git a/include/xorg-config.h.in b/include/xorg-config.h.in
> index 794de7a..d28dc0d 100644
> --- a/include/xorg-config.h.in
> +++ b/include/xorg-config.h.in
> @@ -36,6 +36,9 @@
>  /* Path to configuration file. */
>  #undef __XCONFIGFILE__
>  
> +/* Name of configuration directory. */
> +#undef __XCONFIGDIR__
> +
>  /* Path to loadable modules. */
>  #undef DEFAULT_MODULE_PATH
>  
> -- 
> 1.6.2.5

Reviewed-by: Peter Hutterer <peter.hutterer at who-t.net>

Cheers,
  Peter


More information about the xorg-devel mailing list