From 27d524f75848aa4c234f4ca0f6cdd4cb02425ba8 Mon Sep 17 00:00:00 2001 From: meep-eep Date: Mon, 9 Aug 2004 03:15:40 +0000 Subject: [PATCH] No longer chdir() to the content dir (bug #564) Also, ~ and environment variables are interpreted in the supplied content path now. There's no longer a hardcoded fallback for CONTENTDIR in starcon2.c, as it should always be defined in config.h. Don't look for content in the default directories if an explicitely supplied path failed. It would only confuse users. git-svn-id: svn://svn.code.sf.net/p/sc2/code/trunk@1406 8092fc87-c524-0410-9efc-e669fe64eaf9 --- sc2/ChangeLog | 7 +++- sc2/src/options.c | 94 ++++++++++++++++++++++++++++++++++++++-------- sc2/src/starcon2.c | 8 +--- 3 files changed, 86 insertions(+), 23 deletions(-) diff --git a/sc2/ChangeLog b/sc2/ChangeLog index 46b89e9af..54baf474f 100644 --- a/sc2/ChangeLog +++ b/sc2/ChangeLog @@ -1,9 +1,14 @@ Changes towards version 0.4: +- No longer chdir() to the content dir (bug #564) + Environment variables and ~ are interpreted in the supplied content + path now. + Don't look for content in the default directories if an explicitely + supplied path failed. It would only confuse users. - SvdB - The unix build script is now able to detect SDL on Darwin (bug #358) - SvdB - Resource units given more obviously when ordering a probe to self-destruct (bug #586), from Nic. - Shipyard "Combat Energy" changed to reflect the recharge rate (bug #522). - Also, some cleanups. Thanks and apologies to Nic. + Also, some cleanups. Thanks and apologies to Nic. - SvdB - Added lots of debugging functions, SvdB - Cleaned up use of the DEBUG define, SvdB - Talking Pet .txt file corrected to match the .ogg files, diff --git a/sc2/src/options.c b/sc2/src/options.c index e24ad6b7f..8a4bcace5 100644 --- a/sc2/src/options.c +++ b/sc2/src/options.c @@ -49,32 +49,96 @@ extern uio_Repository *repository; extern uio_DirHandle *rootDir; +static const char *findFileInDirs (const char *locs[], int numLocs, + const char *file); static void mountContentDir (uio_Repository *repository, const char *contentPath, const char **addons); static void mountDirZips (uio_MountHandle *contentHandle, uio_DirHandle *dirHandle); + +// Looks for a file 'file' in all 'numLocs' locations from 'locs'. +// returns the first element from locs where 'file' is found. +// If there is no matching location, NULL will be returned and +// errno will be set to 'ENOENT'. +// Entries from 'locs' that together with 'file' are longer than +// PATH_MAX will be ignored, except for a warning given to stderr. +static const char * +findFileInDirs (const char *locs[], int numLocs, const char *file) +{ + int locI; + char path[PATH_MAX]; + size_t fileLen; + + for (locI = 0; locI < numLocs; locI++) + { + size_t locLen; + const char *loc; + bool needSlash; + + loc = locs[locI]; + locLen = strlen (loc); + + needSlash = (locLen != 0 && loc[locLen - 1] != '/'); + if (locLen + (needSlash ? 1 : 0) + fileLen + 1 >= sizeof path) + { + // This dir plus the file name is too long. + fprintf (stderr, "Warning: path '%s' is ignored because it is " + "too long.\n", loc); + continue; + } + + snprintf (path, sizeof path, "%s%s%s", loc, needSlash ? "/" : "", + file); + if (fileExists (path)) + return loc; + } + + // No matching location was found. + errno = ENOENT; + return NULL; +} + void prepareContentDir (const char *contentDirName, const char **addons) { - const char *testfile = "version"; - char cwd[PATH_MAX]; + const char *testFile = "version"; + const char *loc; + char path[PATH_MAX]; - if (!fileExists (testfile)) + if (contentDirName == NULL) { - if ((chdir (contentDirName) || !fileExists (testfile)) && - (chdir ("content") || !fileExists (testfile)) && - (chdir ("../../content") || !fileExists (testfile))) { - fprintf (stderr, "Fatal error: content not available, running from wrong dir?\n"); - exit (EXIT_FAILURE); - } + // Try the default content locations. + const char *locs[] = { + CONTENTDIR, /* defined in config.h */ + "" + "content", + "../../content" /* For running from MSVC */ + }; + loc = findFileInDirs (locs, sizeof locs / sizeof locs[0], testFile); } - if (getcwd(cwd, sizeof cwd) == NULL) { - fprintf (stderr, "Fatal error: Could not get the current " - "directory.\n"); + else + { + // Only use the explicitely supplied content dir. + loc = findFileInDirs (&contentDirName, 1, testFile); + } + if (loc == NULL) + { + fprintf (stderr, "Fatal error: Could not find content.\n"); exit (EXIT_FAILURE); } - mountContentDir (repository, cwd, addons); + + if (expandPath(path, sizeof path, loc, EP_ALL_SYSTEM) == -1) + { + fprintf (stderr, "Fatal error: Could not expand path to content " + "directory: %s\n", strerror (errno)); + exit (EXIT_FAILURE); + } + +#ifdef DEBUG + fprintf (stderr, "Using '%s' as base content dir.\n", path); +#endif + mountContentDir (repository, path, addons); } void @@ -99,7 +163,7 @@ prepareConfigDir (void) { uio_FSTYPE_STDIO, NULL, NULL, buf, autoMount, uio_MOUNT_TOP, NULL); if (contentHandle == NULL) { - fprintf (stderr, "Fatal error: Couldn't mount config dir: %s\n", + fprintf (stderr, "Fatal error: Could not mount config dir: %s\n", strerror (errno)); exit (EXIT_FAILURE); } @@ -173,7 +237,7 @@ mountContentDir (uio_Repository *repository, const char *contentPath, uio_FSTYPE_STDIO, NULL, NULL, contentPath, autoMount, uio_MOUNT_TOP | uio_MOUNT_RDONLY, NULL); if (contentHandle == NULL) { - fprintf (stderr, "Fatal error: Couldn't mount content dir: %s\n", + fprintf (stderr, "Fatal error: Could not mount content dir: %s\n", strerror (errno)); exit (EXIT_FAILURE); } diff --git a/sc2/src/starcon2.c b/sc2/src/starcon2.c index 1df25ab8e..59597ded8 100644 --- a/sc2/src/starcon2.c +++ b/sc2/src/starcon2.c @@ -105,13 +105,7 @@ main (int argc, char *argv[]) /* .width = */ 640, /* .height = */ 480, /* .bpp = */ 16, -#ifdef CONTENTDIR - /* .contentDir = */ CONTENTDIR, -#elif defined (win32) - /* .contentDir = */ "../../content", -#else - /* .contentDir = */ "content", -#endif + /* .contentDir = */ NULL, /* .addons = */ NULL, /* .numAddons = */ 0, /* .gammaSet = */ 0,