diff options
author | Simon Howard | 2015-08-23 16:08:58 -0400 |
---|---|---|
committer | Mike Swanson | 2015-08-24 14:37:33 -0700 |
commit | 69faefcab4f8ac6599f47173b9a0eba80aaa10a6 (patch) | |
tree | 94b3fe0040cff87605484af7fa16340b843c33e2 | |
parent | 87db726b9a9ae61caf2ff167450625ce8f4076c3 (diff) | |
download | chocolate-doom-69faefcab4f8ac6599f47173b9a0eba80aaa10a6.tar.gz chocolate-doom-69faefcab4f8ac6599f47173b9a0eba80aaa10a6.tar.bz2 chocolate-doom-69faefcab4f8ac6599f47173b9a0eba80aaa10a6.zip |
Make IWAD search paths compliant with XDG spec.
The XDG Base Directory Specification defines standard directories
that are searched for data files via the XDG_DATA_HOME and
XDG_DATA_DIRS environment variables:
http://standards.freedesktop.org/basedir-spec/basedir-spec-latest.html
To make Chocolate Doom a good citizen, use these directories to
determine some of the locations in which to look for IWAD files. This
includes /usr/share/games/doom, which is absorbed under the default
value of the XDG_DATA_DIRS variable. We also now support the alternative
~/.local/share/games/doom as a user-writeable path in the user's home
directory that doesn't require root privileges.
This is part of #597 (thanks to @chungy for the suggestion).
-rw-r--r-- | src/d_iwad.c | 128 |
1 files changed, 82 insertions, 46 deletions
diff --git a/src/d_iwad.c b/src/d_iwad.c index 2d6460bc..3777bab6 100644 --- a/src/d_iwad.c +++ b/src/d_iwad.c @@ -509,55 +509,96 @@ static GameMission_t IdentifyIWADByName(char *name, int mask) return mission; } -// -// Add directories from the list in the DOOMWADPATH environment variable. -// - -static void AddDoomWadPath(void) +// Add IWAD directories parsed from splitting a path string containing +// paths separated by PATH_SEPARATOR. 'suffix' is a string to concatenate +// to the end of the paths before adding them. +static void AddIWADPath(char *path, char *suffix) { - char *doomwadpath; - char *p; - - // Check the DOOMWADPATH environment variable. - - doomwadpath = getenv("DOOMWADPATH"); - - if (doomwadpath == NULL) - { - return; - } + char *left, *p; - doomwadpath = M_StringDuplicate(doomwadpath); - - // Add the initial directory - - AddIWADDir(doomwadpath); + path = M_StringDuplicate(path); // Split into individual dirs within the list. - - p = doomwadpath; + left = path; for (;;) { - p = strchr(p, PATH_SEPARATOR); - + p = strchr(left, PATH_SEPARATOR); if (p != NULL) { - // Break at the separator and store the right hand side + // Break at the separator and use the left hand side // as another iwad dir - *p = '\0'; - p += 1; - AddIWADDir(p); + AddIWADDir(M_StringJoin(left, suffix, NULL)); + left = p + 1; } else { break; } } + + AddIWADDir(M_StringJoin(left, suffix, NULL)); + + free(path); } +// Add standard directories where IWADs are located on Unix systems. +// To respect the freedesktop.org specification we support overriding +// using standard environment variables. See the XDG Base Directory +// Specification: +// <http://standards.freedesktop.org/basedir-spec/basedir-spec-latest.html> +static void AddXdgDirs(void) +{ + char *env, *tmp_env; + + // Quote: + // > $XDG_DATA_HOME defines the base directory relative to which + // > user specific data files should be stored. If $XDG_DATA_HOME + // > is either not set or empty, a default equal to + // > $HOME/.local/share should be used. + env = getenv("XDG_DATA_HOME"); + tmp_env = NULL; + + if (env == NULL) + { + char *homedir = getenv("HOME"); + if (homedir == NULL) + { + homedir = "/"; + } + + tmp_env = M_StringJoin(homedir, "/.local/share", NULL); + env = tmp_env; + } + + // We support $XDG_DATA_HOME/games/doom (which will usually be + // ~/.local/share/games/doom) as a user-writeable extension to + // the usual /usr/share/games/doom location. + AddIWADDir(M_StringJoin(env, "/games/doom", NULL)); + free(tmp_env); + + // Quote: + // > $XDG_DATA_DIRS defines the preference-ordered set of base + // > directories to search for data files in addition to the + // > $XDG_DATA_HOME base directory. The directories in $XDG_DATA_DIRS + // > should be seperated with a colon ':'. + // > + // > If $XDG_DATA_DIRS is either not set or empty, a value equal to + // > /usr/local/share/:/usr/share/ should be used. + env = getenv("XDG_DATA_DIRS"); + if (env == NULL) + { + // (Trailing / omitted from paths, as it is added below) + env = "/usr/local/share:/usr/share"; + } + + // The "standard" location for IWADs on Unix that is supported by most + // source ports is /usr/share/games/doom - we support this through the + // XDG_DATA_DIRS mechanism, through which it can be overridden. + AddIWADPath(env, "/games/doom"); +} // // Build a list of IWAD files @@ -565,7 +606,7 @@ static void AddDoomWadPath(void) static void BuildIWADDirList(void) { - char *doomwaddir; + char *env; if (iwad_dirs_built) { @@ -573,21 +614,21 @@ static void BuildIWADDirList(void) } // Look in the current directory. Doom always does this. - AddIWADDir("."); // Add DOOMWADDIR if it is in the environment - - doomwaddir = getenv("DOOMWADDIR"); - - if (doomwaddir != NULL) + env = getenv("DOOMWADDIR"); + if (env != NULL) { - AddIWADDir(doomwaddir); - } - - // Add dirs from DOOMWADPATH + AddIWADDir(env); + } - AddDoomWadPath(); + // Add dirs from DOOMWADPATH: + env = getenv("DOOMWADPATH"); + if (env != NULL) + { + AddIWADPath(env, ""); + } #ifdef _WIN32 @@ -603,12 +644,7 @@ static void BuildIWADDirList(void) CheckSteamGUSPatches(); #else - - // Standard places where IWAD files are installed under Unix. - - AddIWADDir("/usr/share/games/doom"); - AddIWADDir("/usr/local/share/games/doom"); - + AddXdgDirs(); #endif // Don't run this function again. |