[PATCH v4 3/3] xfree86: Allow config directory to be specified on command line

Dan Nicholson dbn.lists at gmail.com
Mon Dec 21 12:35:09 PST 2009


Add a new command line parameter, -configdir, to specify the config
directory to be used. Rules are the same as -config for root vs. user
privileges.

Signed-off-by: Dan Nicholson <dbn.lists at gmail.com>
---
 hw/xfree86/common/xf86Config.c  |   59 +++++++++++++++++++++++++++------------
 hw/xfree86/common/xf86Globals.c |    1 +
 hw/xfree86/common/xf86Init.c    |   15 ++++++++++
 hw/xfree86/common/xf86Priv.h    |    1 +
 hw/xfree86/doc/man/Xorg.man.pre |   34 ++++++++++++++++++++--
 hw/xfree86/parser/scan.c        |   17 ++++++++--
 hw/xwin/InitOutput.c            |    3 ++
 hw/xwin/winconfig.c             |   21 ++++++++++++--
 hw/xwin/winconfig.h             |    1 +
 hw/xwin/winprocarg.c            |   18 ++++++++++++
 10 files changed, 142 insertions(+), 28 deletions(-)

diff --git a/hw/xfree86/common/xf86Config.c b/hw/xfree86/common/xf86Config.c
index d718814..19063dc 100644
--- a/hw/xfree86/common/xf86Config.c
+++ b/hw/xfree86/common/xf86Config.c
@@ -102,12 +102,22 @@ 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"
+#ifndef ROOT_CONFIGDIRPATH
+#define ROOT_CONFIGDIRPATH	"%A," "%R," \
+				"/etc/X11/%R," "%P/etc/X11/%R," \
+				"/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 USER_CONFIGDIRPATH
+#define USER_CONFIGDIRPATH	"/etc/X11/%S," "%P/etc/X11/%S," \
+				"/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"
@@ -2445,35 +2455,48 @@ ConfigStatus
 xf86HandleConfigFile(Bool autoconfig)
 {
     const char *filename, *dirname;
-    char *searchpath;
-    MessageType from = X_DEFAULT;
+    char *filesearch, *dirsearch;
+    MessageType filefrom = X_DEFAULT;
+    MessageType dirfrom = X_DEFAULT;
     char *scanptr;
     Bool singlecard = 0;
     Bool implicit_layout = FALSE;
 
     if (!autoconfig) {
-	if (getuid() == 0)
-	    searchpath = ROOT_CONFIGPATH;
-	else
-	    searchpath = USER_CONFIGPATH;
+	if (getuid() == 0) {
+	    filesearch = ROOT_CONFIGPATH;
+	    dirsearch = ROOT_CONFIGDIRPATH;
+	} else {
+	    filesearch = USER_CONFIGPATH;
+	    dirsearch = USER_CONFIGDIRPATH;
+	}
 
 	if (xf86ConfigFile)
-	    from = X_CMDLINE;
+	    filefrom = X_CMDLINE;
+	if (xf86ConfigDir)
+	    dirfrom = X_CMDLINE;
 
 	xf86initConfigFiles();
-	filename = xf86openConfigFile(searchpath, xf86ConfigFile, PROJECTROOT);
-	dirname = xf86openConfigDirFiles(CONFIGDIRPATH, NULL, PROJECTROOT);
+	filename = xf86openConfigFile(filesearch, xf86ConfigFile, PROJECTROOT);
+	dirname = xf86openConfigDirFiles(dirsearch, xf86ConfigDir, PROJECTROOT);
 	if (filename) {
-	    xf86MsgVerb(from, 0, "Using config file: \"%s\"\n", filename);
+	    xf86MsgVerb(filefrom, 0, "Using config file: \"%s\"\n", filename);
 	    xf86ConfigFile = xnfstrdup(filename);
 	} else {
 	    if (xf86ConfigFile)
 		xf86Msg(X_ERROR, "Unable to locate/open config file: \"%s\"\n",
 			xf86ConfigFile);
 	}
-	if (dirname)
-	    xf86MsgVerb(X_DEFAULT, 0, "Using config directory: \"%s\"\n",
+	if (dirname) {
+	    xf86MsgVerb(dirfrom, 0, "Using config directory: \"%s\"\n",
 			dirname);
+	    xf86ConfigDir = xnfstrdup(dirname);
+	} else {
+	    if (xf86ConfigDir)
+		xf86Msg(X_ERROR,
+			"Unable to locate/open config directory: \"%s\"\n",
+			xf86ConfigDir);
+	}
 	if (!filename && !dirname)
 	    return CONFIG_NOFILE;
     }
diff --git a/hw/xfree86/common/xf86Globals.c b/hw/xfree86/common/xf86Globals.c
index d8f7f7f..65a7503 100644
--- a/hw/xfree86/common/xf86Globals.c
+++ b/hw/xfree86/common/xf86Globals.c
@@ -143,6 +143,7 @@ xf86InfoRec xf86Info = {
 #endif
 };
 const char *xf86ConfigFile = NULL;
+const char *xf86ConfigDir = NULL;
 const char *xf86ModulePath = DEFAULT_MODULE_PATH;
 MessageType xf86ModPathFrom = X_DEFAULT;
 const char *xf86LogFile = DEFAULT_LOGPREFIX;
diff --git a/hw/xfree86/common/xf86Init.c b/hw/xfree86/common/xf86Init.c
index 30f0c85..5eeafc9 100644
--- a/hw/xfree86/common/xf86Init.c
+++ b/hw/xfree86/common/xf86Init.c
@@ -1383,6 +1383,19 @@ ddxProcessArgument(int argc, char **argv, int i)
     xf86ConfigFile = argv[i + 1];
     return 2;
   }
+  if (!strcmp(argv[i], "-configdir"))
+  {
+    CHECK_FOR_REQUIRED_ARGUMENT();
+    if (getuid() != 0 && !xf86PathIsSafe(argv[i + 1])) {
+      FatalError("\nInvalid argument for %s\n"
+	  "\tFor non-root users, the file specified with %s must be\n"
+	  "\ta relative path and must not contain any \"..\" elements.\n"
+	  "\tUsing default "__XCONFIGDIR__" search path.\n\n",
+	  argv[i], argv[i]);
+    }
+    xf86ConfigDir = argv[i + 1];
+    return 2;
+  }
   if (!strcmp(argv[i],"-flipPixels"))
   {
     xf86FlipPixels = TRUE;
@@ -1666,6 +1679,8 @@ ddxUseMsg(void)
   }
   ErrorF("-config file           specify a configuration file, relative to the\n");
   ErrorF("                       "__XCONFIGFILE__" search path, only root can use absolute\n");
+  ErrorF("-configdir dir         specify a configuration directory, relative to the\n");
+  ErrorF("                       "__XCONFIGDIR__" search path, only root can use absolute\n");
   ErrorF("-verbose [n]           verbose startup messages\n");
   ErrorF("-logverbose [n]        verbose log messages\n");
   ErrorF("-quiet                 minimal startup messages\n");
diff --git a/hw/xfree86/common/xf86Priv.h b/hw/xfree86/common/xf86Priv.h
index 3bb1571..0612c9c 100644
--- a/hw/xfree86/common/xf86Priv.h
+++ b/hw/xfree86/common/xf86Priv.h
@@ -46,6 +46,7 @@
  * The global state of these things is held in xf86InfoRec (when appropriate).
  */
 extern _X_EXPORT const char *xf86ConfigFile;
+extern _X_EXPORT const char *xf86ConfigDir;
 extern _X_EXPORT  Bool xf86AllowMouseOpenFail;
 #ifdef XF86VIDMODE
 extern _X_EXPORT  Bool xf86VidModeDisabled;
diff --git a/hw/xfree86/doc/man/Xorg.man.pre b/hw/xfree86/doc/man/Xorg.man.pre
index fe32800..c1fadb8 100644
--- a/hw/xfree86/doc/man/Xorg.man.pre
+++ b/hw/xfree86/doc/man/Xorg.man.pre
@@ -109,7 +109,7 @@ script.
 .B __xservername__
 supports several mechanisms for supplying/obtaining configuration and
 run-time parameters: command line options, environment variables, the
-__xconfigfile__(__filemansuffix__) configuration file, auto-detection, and
+__xconfigfile__(__filemansuffix__) 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
@@ -176,6 +176,13 @@ This option will work for any file when the server is run as root (i.e,
 with real-uid 0), or for files relative to a directory in the config
 search path for all other users.
 .TP 8
+.BI \-configdir " directory"
+Read the server configuration files from
+.IR directory .
+This option will work for any directory when the server is run as root
+(i.e, with real-uid 0), or for directories relative to a directory in the
+config directory search path for all other users.
+.TP 8
 .B \-configure
 When this option is specified, the
 .B __xservername__
@@ -463,6 +470,10 @@ __xconfigfile__(__filemansuffix__) file option.
 .B __xservername__
 typically uses a configuration file called
 .B __xconfigfile__
+and configuration files with the suffix
+.I .conf
+in a directory called
+.B __xconfigdir__
 for its initial setup.
 Refer to the __xconfigfile__(__filemansuffix__) manual page for information
 about the format of this file.
@@ -471,7 +482,9 @@ about the format of this file.
 has a mechanism for automatically generating a built-in configuration
 at run-time when no
 .B __xconfigfile__
-file is present.  The current version of this automatic configuration
+file or
+.B __xconfigdir__
+files are present.  The current version of this automatic configuration
 mechanism works in two ways.
 .PP
 The first is via enhancements that have made many components of the
@@ -493,7 +506,7 @@ supported by __xservername__.  Enhancements are planned for future releases.
 .SH FILES
 The
 .B __xservername__
-server config file can be found in a range of locations.  These are
+server config files can be found in a range of locations.  These are
 documented fully in the __xconfigfile__(__filemansuffix__) manual page.  The
 most commonly used locations are shown here.
 .TP 30
@@ -512,6 +525,21 @@ Server configuration file.
 .B __projectroot__/lib/X11/__xconfigfile__
 Server configuration file.
 .TP 30
+.B /etc/X11/__xconfigdir__
+Server configuration directory.
+.TP 30
+.B /etc/X11/__xconfigdir__-4
+Server configuration directory.
+.TP 30
+.B /etc/__xconfigdir__
+Server configuration directory.
+.TP 30
+.B __projectroot__/etc/__xconfigdir__
+Server configuration directory.
+.TP 30
+.B __projectroot__/lib/X11/__xconfigdir__
+Server configuration directory.
+.TP 30
 .BI __logdir__/__xservername__. n .log
 Server log file for display
 .IR n .
diff --git a/hw/xfree86/parser/scan.c b/hw/xfree86/parser/scan.c
index 24260e2..9f18350 100644
--- a/hw/xfree86/parser/scan.c
+++ b/hw/xfree86/parser/scan.c
@@ -874,11 +874,13 @@ AddConfigDirFiles(const char *dirpath, struct dirent **list, int num)
  * directory. The directory does not need to contain config files.
  */
 static char *
-OpenConfigDir(const char *path, const char *projroot, const char *confname)
+OpenConfigDir(const char *path, const char *cmdline, const char *projroot,
+	      const char *confname)
 {
 	char *dirpath, *pathcopy;
 	const char *template;
 	Bool found = FALSE;
+	int cmdlineUsed = 0;
 
 	pathcopy = strdup(path);
 	for (template = strtok(pathcopy, ","); template && !found;
@@ -886,9 +888,16 @@ OpenConfigDir(const char *path, const char *projroot, const char *confname)
 		struct dirent **list = NULL;
 		int num;
 
-		if (!(dirpath = DoSubstitution(template, NULL, projroot,
-					       NULL, NULL, confname)))
+		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);
 		found = AddConfigDirFiles(dirpath, list, num);
@@ -992,7 +1001,7 @@ xf86openConfigDirFiles(const char *path, const char *cmdline,
 		projroot = PROJECTROOT;
 
 	/* Search for the multiconf directory */
-	configDirPath = OpenConfigDir(path, projroot, XCONFIGDIR);
+	configDirPath = OpenConfigDir(path, cmdline, projroot, XCONFIGDIR);
 	return configDirPath;
 }
 
diff --git a/hw/xwin/InitOutput.c b/hw/xwin/InitOutput.c
index 8fd82d0..91f5ec0 100644
--- a/hw/xwin/InitOutput.c
+++ b/hw/xwin/InitOutput.c
@@ -853,6 +853,9 @@ winUseMsg (void)
   ErrorF ("-config\n"
           "\tSpecify a configuration file.\n");
 
+  ErrorF ("-configdir\n"
+          "\tSpecify a configuration directory.\n");
+
   ErrorF ("-keyboard\n"
 	  "\tSpecify a keyboard device from the configuration file.\n");
 #endif
diff --git a/hw/xwin/winconfig.c b/hw/xwin/winconfig.c
index 6efd7ca..f1e805c 100644
--- a/hw/xwin/winconfig.c
+++ b/hw/xwin/winconfig.c
@@ -64,6 +64,7 @@ XF86ConfigPtr g_xf86configptr = NULL;
 WinCmdlineRec g_cmdline = {
 #ifdef XWIN_XF86CONFIG
   NULL,				/* configFile */
+  NULL,				/* configDir */
 #endif
   NULL,				/* fontPath */
 #ifdef XWIN_XF86CONFIG
@@ -117,19 +118,26 @@ winReadConfigfile ()
 {
   Bool		retval = TRUE;
   const char	*filename, *dirname;
-  MessageType	from = X_DEFAULT;
+  MessageType	filefrom = X_DEFAULT;
+  MessageType	dirfrom = X_DEFAULT;
   char		*xf86ConfigFile = NULL;
+  char		*xf86ConfigDir = NULL;
 
   if (g_cmdline.configFile)
     {
-      from = X_CMDLINE;
+      filefrom = X_CMDLINE;
       xf86ConfigFile = g_cmdline.configFile;
     }
+  if (g_cmdline.configDir)
+    {
+      dirfrom = X_CMDLINE;
+      xf86ConfigDir = g_cmdline.configDir;
+    }
 
   /* Parse config file into data structure */
   xf86initConfigFiles();
   filename = xf86openConfigFile (CONFIGPATH, xf86ConfigFile, PROJECTROOT);
-  dirname = xf86openConfigDirFiles (CONFIGDIRPATH, NULL, PROJECTROOT);
+  dirname = xf86openConfigDirFiles (CONFIGDIRPATH, xf86ConfigDir, PROJECTROOT);
 
   /* Hack for backward compatibility */
   if (!filename && from == X_DEFAULT)
@@ -150,6 +158,13 @@ winReadConfigfile ()
     {
       winMsg (from, "Using config directory: \"%s\"\n", dirname);
     }
+  else
+    {
+      winMsg (X_ERROR, "Unable to locate/open config directory");
+      if (xf86ConfigDir)
+	ErrorF (": \"%s\"", xf86ConfigDir);
+      ErrorF ("\n");
+    }
   if (!filename && !dirname)
     {
       return FALSE;
diff --git a/hw/xwin/winconfig.h b/hw/xwin/winconfig.h
index 63d6211..058884a 100644
--- a/hw/xwin/winconfig.h
+++ b/hw/xwin/winconfig.h
@@ -188,6 +188,7 @@ typedef struct
   /* Files */
 #ifdef XWIN_XF86CONFIG
   char *configFile;
+  char *configDir;
 #endif
   char *fontPath;
   /* input devices - keyboard */
diff --git a/hw/xwin/winprocarg.c b/hw/xwin/winprocarg.c
index 31e505e..fd7719c 100755
--- a/hw/xwin/winprocarg.c
+++ b/hw/xwin/winprocarg.c
@@ -1341,6 +1341,24 @@ ddxProcessArgument (int argc, char *argv[], int i)
     }
 
   /*
+   * Look for the '-configdir' argument
+   */
+  if (IS_OPTION ("-configdir"))
+    {
+      CHECK_ARGS (1);
+#ifdef XWIN_XF86CONFIG
+      g_cmdline.configDir = argv[++i];
+#else
+      winMessageBoxF ("The %s option is not supported in this "
+		      "release.\n"
+		      "Ignoring this option and continuing.\n",
+		      MB_ICONINFORMATION,
+		      argv[i]);
+#endif
+      return 2;
+    }
+
+  /*
    * Look for the '-keyboard' argument
    */
   if (IS_OPTION ("-keyboard"))
-- 
1.6.2.5



More information about the xorg-devel mailing list