From 6b452a8da7312e27be628a712d3ac68f7cf7ebbc Mon Sep 17 00:00:00 2001 From: Taylor Richards Date: Sun, 17 Nov 2013 16:51:38 -0500 Subject: [PATCH] filesystem cleanup and consolidation: - use user writable location on all platforms, via SDL - use SDL to determine exec location instead of relying on cwd --- include/cfile.h | 6 +- include/osapi.h | 4 -- include/osregistry.h | 7 --- src/cfile/cfile.cpp | 101 ++++++++++++++++++++-------------- src/cfile/cfilesystem.cpp | 31 ++++------- src/freespace2/freespace.cpp | 55 +----------------- src/freespace2/unixmain.cpp | 14 ----- src/osapi/os_unix.cpp | 6 -- src/osapi/osregistry-unix.cpp | 24 +------- 9 files changed, 78 insertions(+), 170 deletions(-) diff --git a/include/cfile.h b/include/cfile.h index 100bf9f..41c5dd3 100644 --- a/include/cfile.h +++ b/include/cfile.h @@ -433,13 +433,11 @@ extern int (*Get_file_list_filter)(const char *filename); // cfile directory. valid after cfile_init() returns successfully #define CFILE_ROOT_DIRECTORY_LEN 256 extern char Cfile_root_dir[CFILE_ROOT_DIRECTORY_LEN]; -#ifdef PLAT_UNIX extern char Cfile_user_dir[CFILE_ROOT_DIRECTORY_LEN]; -#endif //================= LOW-LEVEL FUNCTIONS ================== // Call this once at the beginning of the program -int cfile_init(const char *exe_dir, const char *cdrom_dir=NULL); +int cfile_init(const char *cdrom_dir = NULL); // Call this if pack files got added or removed or the // cdrom changed. This will refresh the list of filenames @@ -617,6 +615,8 @@ int cfile_push_chdir(int type); // restore directory on top of the stack int cfile_pop_dir(); +// initializes Cfile_root_dir[] and Cfile_user_dir[] +int cfile_init_paths(); #endif /* __CFILE_H__ */ diff --git a/include/osapi.h b/include/osapi.h index ed0d3c3..f2c3cd8 100644 --- a/include/osapi.h +++ b/include/osapi.h @@ -37,10 +37,6 @@ extern int Os_debugger_running; // initialization/shutdown functions ----------------------------------------------- -#ifdef PLAT_UNIX -extern const char *detect_home(void); -#endif - // If app_name is NULL or ommited, then TITLE is used // for the app name, which is where registry keys are stored. void os_init(const char *wclass, const char *title, const char *app_name = NULL, const char *version_string = NULL); diff --git a/include/osregistry.h b/include/osregistry.h index 42c2249..ec0c433 100644 --- a/include/osregistry.h +++ b/include/osregistry.h @@ -20,9 +20,6 @@ extern const char *Osreg_company_name; extern const char *Osreg_class_name; extern const char *Osreg_app_name; extern const char *Osreg_title; -#ifdef PLAT_UNIX -extern const char *Osreg_user_dir; -#endif // ------------------------------------------------------------------------------------------------------------ // REGISTRY FUNCTIONS @@ -62,9 +59,5 @@ unsigned int os_config_read_uint( const char *section, const char *name, unsign // uses Ex versions of Windows registry functions const char * os_config_read_string_ex( const char *keyname, const char *name, const char *default_value ); -#if defined(__APPLE__) && !defined(MACOSX) -extern char full_path[]; -#endif - #endif diff --git a/src/cfile/cfile.cpp b/src/cfile/cfile.cpp index a61fb85..2aa4ed0 100644 --- a/src/cfile/cfile.cpp +++ b/src/cfile/cfile.cpp @@ -233,12 +233,10 @@ #include "cfilesystem.h" #include "cfilearchive.h" #include "osapi.h" -#include "osregistry.h" // for Osreg_user_dir +#include "osregistry.h" -#ifdef PLAT_UNIX -char Cfile_user_dir[CFILE_ROOT_DIRECTORY_LEN] = ""; -#endif char Cfile_root_dir[CFILE_ROOT_DIRECTORY_LEN] = ""; +char Cfile_user_dir[CFILE_ROOT_DIRECTORY_LEN] = ""; // During cfile_init, verify that Pathtypes[n].index == n for each item // Each path must have a valid parent that can be tracable all the way back to the root @@ -400,7 +398,7 @@ int cfile_in_root_dir(char *exe_path) // returns: success ==> 0 // error ==> non-zero // -int cfile_init(const char *exe_dir, const char *cdrom_dir) +int cfile_init(const char *cdrom_dir) { int i; @@ -408,55 +406,26 @@ int cfile_init(const char *exe_dir, const char *cdrom_dir) encrypt_init(); if ( !cfile_inited ) { - char buf[128]; - - cfile_inited = 1; - - strcpy(buf, exe_dir); - i = strlen(buf); - -#ifndef PLAT_UNIX - // are we in a root directory? - if(cfile_in_root_dir(buf)){ - MessageBox((HWND)NULL, "Freespace2/Fred2 cannot be run from a drive root directory!", "Error", MB_OK); - return 1; - } -#endif - - while (i--) { - if (buf[i] == DIR_SEPARATOR_CHAR){ - break; - } - } - - if (i >= 2) { - buf[i] = 0; - cfile_chdir(buf); - } else { -#ifdef PLAT_UNIX - fprintf (stderr, "Error trying to determine executable root directory!"); -#else - MessageBox((HWND)NULL, "Error trying to determine executable root directory!", "Error", MB_OK); -#endif + // initialize root and user paths (may have been done already) + if ( cfile_init_paths() ) { return 1; } - // set root directory - strncpy(Cfile_root_dir, buf, CFILE_ROOT_DIRECTORY_LEN-1); + cfile_inited = 1; -#ifdef PLAT_UNIX - snprintf(Cfile_user_dir, MAX_PATH, "%s/%s/", detect_home(), Osreg_user_dir); -#endif for ( i = 0; i < MAX_CFILE_BLOCKS; i++ ) { Cfile_block_list[i].type = CFILE_BLOCK_UNUSED; } Cfile_cdrom_dir = (char *)cdrom_dir; + cf_build_secondary_filelist(Cfile_cdrom_dir); // 32 bit CRC table init cf_chksum_long_init(); + + atexit( cfile_close ); } @@ -1804,9 +1773,61 @@ int cflush(CFILE *cfile) return fflush(cb->fp); } +// fill in Cfile_root_dir[] and Cfile_user_dir[] +// this can be called at any time, even before cfile_init() +// returns: non-zero on error +int cfile_init_paths() +{ + if ( strlen(Cfile_root_dir) && strlen(Cfile_user_dir) ) { + return 0; + } + char *t_path = SDL_GetBasePath(); + // make sure we have something + if (t_path == NULL) { + SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_ERROR, "Error", "Error trying to determine executable directory!", NULL); + return 1; + } + // size check + if ( strlen(t_path) >= CFILE_ROOT_DIRECTORY_LEN ) { + SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_ERROR, "Error", "Executable path is too long!", NULL); + return 1; + } + // set root directory + strcpy(Cfile_root_dir, t_path); + // free SDL copy + SDL_free(t_path); + t_path = NULL; + // are we in a root directory? + if ( cfile_in_root_dir(Cfile_root_dir) ) { + SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_ERROR, "Error", "Freespace2/Fred2 cannot be run from a drive root directory!", NULL); + return 1; + } + // now for the user/pref directory, the writable location + char *u_path = SDL_GetPrefPath(Osreg_company_name, Osreg_title); + + // make sure we have something + if (u_path == NULL) { + SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_ERROR, "Error", "Error trying to determine preferences directory!", NULL); + return 1; + } + + // size check + if ( strlen(u_path) >= CFILE_ROOT_DIRECTORY_LEN ) { + SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_ERROR, "Error", "Preferences path is too long!", NULL); + return 1; + } + + // set user/pref directory + strcpy(Cfile_user_dir, u_path); + // free SDL copy + SDL_free(u_path); + u_path = NULL; + + return 0; +} diff --git a/src/cfile/cfilesystem.cpp b/src/cfile/cfilesystem.cpp index 0da2901..940eb0f 100644 --- a/src/cfile/cfilesystem.cpp +++ b/src/cfile/cfilesystem.cpp @@ -477,32 +477,25 @@ void cf_build_root_list(const char *cdrom_dir) cf_root *root; -#ifdef PLAT_UNIX // ================================================================ - // use users HOME directory as default for loading and saving files + // have user's writable directory as default for loading and saving files root = cf_create_root(); strcpy( root->path, Cfile_user_dir ); // do we already have a slash? as in the case of a root directory install - if(strlen(root->path) && (root->path[strlen(root->path)-1] != '/')){ - strcat(root->path, "/"); // put trailing backslash on for easier path construction + if(strlen(root->path) && (root->path[strlen(root->path)-1] != DIR_SEPARATOR_CHAR)){ + strcat(root->path, DIR_SEPARATOR_STR); // put trailing backslash on for easier path construction } root->roottype = CF_ROOTTYPE_PATH; - //====================================================== - // Next, check any VP files under the current directory. + //====================================================== + // then check any VP files under the directory. cf_build_pack_list(root); -#endif - - //====================================================== - // First, check the current directory. - // strcpy( root->path, "d:\\projects\\freespace\\" ); + //====================================================== + // Next, use the executable's directory for game data root = cf_create_root(); - - if ( !_getcwd(root->path, CF_MAX_PATHNAME_LENGTH ) ) { - Error(LOCATION, "Can't get current working directory -- %d", errno ); - } + strcpy( root->path, Cfile_root_dir ); // do we already have a slash? as in the case of a root directory install if(strlen(root->path) && (root->path[strlen(root->path)-1] != DIR_SEPARATOR_CHAR)){ @@ -510,12 +503,12 @@ void cf_build_root_list(const char *cdrom_dir) } root->roottype = CF_ROOTTYPE_PATH; - //====================================================== - // Next, check any VP files under the current directory. + //====================================================== + // then check any VP files under the current directory. cf_build_pack_list(root); - //====================================================== + //====================================================== // Check the real CD if one... if ( cdrom_dir && strlen(cdrom_dir) ) { root = cf_create_root(); @@ -525,9 +518,7 @@ void cf_build_root_list(const char *cdrom_dir) //====================================================== // Next, check any VP files in the CD-ROM directory. cf_build_pack_list(root); - } - } // Given a lower case list of file extensions diff --git a/src/freespace2/freespace.cpp b/src/freespace2/freespace.cpp index f26d931..3dadcc7 100644 --- a/src/freespace2/freespace.cpp +++ b/src/freespace2/freespace.cpp @@ -764,10 +764,6 @@ float Viewer_zoom = VIEWER_ZOOM_DEFAULT; #define LAUNCHER_FNAME ("freespace2.exe") -#if defined(__APPLE__) && !defined(MACOSX) -extern char full_path[1024]; -#endif - // JAS: Code for warphole camera. // Needs to be cleaned up. vector Camera_pos = ZERO_VECTOR; @@ -2373,33 +2369,9 @@ void game_init() int s1, e1; // int s2, e2; - char whee[1024]; -#ifndef PLAT_UNIX - GetCurrentDirectory(1024, whee); - strcat(whee, "\\"); -#elif defined(__APPLE__) && !defined(MACOSX) - // some OSX hackery to drop us out of the APP the binary is run from - char *c = NULL; - c = strstr(full_path, ".app"); - - if ( c != NULL) { - while (c && (*c != '/')) - c--; - - *c = '\0'; - } - - strncpy(whee, full_path, 1024); - strcat(whee, "/"); -#else - getcwd (whee, 1024); - strcat(whee, "/"); -#endif - strcat(whee, EXE_FNAME); - //Initialize the libraries s1 = timer_get_milliseconds(); - if(cfile_init(whee, Game_CDROM_dir)){ // initialize before calling any cfopen stuff!!! + if(cfile_init(Game_CDROM_dir)){ // initialize before calling any cfopen stuff!!! exit(1); } e1 = timer_get_milliseconds(); @@ -7129,32 +7101,7 @@ int PASCAL WinMainSub(HINSTANCE hInst, HINSTANCE hPrev, LPSTR szCmdLine, int nCm return 0; } */ - //===================================================== - // Make sure we're running in the right directory. -#ifndef PLAT_UNIX - char exe_dir[1024]; - if ( GetModuleFileName( hInst, exe_dir, 1023 ) > 0 ) { - char *p = exe_dir + strlen(exe_dir); - - // chop off the filename - while( (p>exe_dir) && (*p!='\\') && (*p!='/') && (*p!=':') ) { - p--; - } - *p = 0; - - // Set directory - if ( strlen(exe_dir) > 0 ) { - SetCurrentDirectory(exe_dir); - } - - // check for updated freespace.exe - game_maybe_update_launcher(exe_dir); - } -#else - STUB_FUNCTION; -#endif - #ifndef NDEBUG { extern void windebug_memwatch_init(); diff --git a/src/freespace2/unixmain.cpp b/src/freespace2/unixmain.cpp index 3dcc4ea..308a2a5 100644 --- a/src/freespace2/unixmain.cpp +++ b/src/freespace2/unixmain.cpp @@ -9,25 +9,11 @@ int PASCAL WinMain(HINSTANCE hInst, HINSTANCE hPrev, LPSTR szCmdLine, int nCmdShow); -#if defined(__APPLE__) && !defined(MACOSX) -char full_path[1024]; -#endif - void vm_dump(); int main(int argc, char **argv) { - char userdir[MAX_PATH] = { 0 }; - -#if defined(__APPLE__) && !defined(MACOSX) - strcpy( full_path, *argv ); -#endif - - // create user game directory - snprintf(userdir, MAX_PATH, "%s/%s/", detect_home(), Osreg_user_dir); - _mkdir(userdir); - char *argptr = NULL; int i; int len = 0; diff --git a/src/osapi/os_unix.cpp b/src/osapi/os_unix.cpp index 508e9ef..f3560bd 100644 --- a/src/osapi/os_unix.cpp +++ b/src/osapi/os_unix.cpp @@ -188,12 +188,6 @@ void os_deinit(); // initialization/shutdown functions ----------------------------------------------- -// detect users home directory -const char *detect_home(void) -{ - return (getenv("HOME")); -} - // If app_name is NULL or ommited, then TITLE is used // for the app name, which is where registry keys are stored. void os_init(const char *wclass, const char *title, const char *app_name, const char *version_string) diff --git a/src/osapi/osregistry-unix.cpp b/src/osapi/osregistry-unix.cpp index 4de2d1b..384da2a 100644 --- a/src/osapi/osregistry-unix.cpp +++ b/src/osapi/osregistry-unix.cpp @@ -12,27 +12,17 @@ const char *Osreg_company_name = "Volition"; #if defined(MAKE_FS1) -const char *Osreg_class_name = "FreespaceClass"; +const char *Osreg_class_name = "FreeSpaceClass"; #else const char *Osreg_class_name = "Freespace2Class"; #endif #if defined(FS1_DEMO) const char *Osreg_app_name = "FreeSpaceDemo"; -const char *Osreg_title = "Freespace Demo"; -#ifndef __APPLE__ -const char *Osreg_user_dir = ".freespace_demo"; -#else -const char *Osreg_user_dir = "Library/Application Support/FreeSpace Demo"; -#endif +const char *Osreg_title = "FreeSpace Demo"; #define PROFILE_NAME "FreeSpaceDemo.ini" #elif defined(FS2_DEMO) const char *Osreg_app_name = "FreeSpace2Demo"; const char *Osreg_title = "Freespace 2 Demo"; -#ifndef __APPLE__ -const char *Osreg_user_dir = ".freespace2_demo"; -#else -const char *Osreg_user_dir = "Library/Application Support/Freespace 2 Demo"; -#endif #define PROFILE_NAME "FreeSpace2Demo.ini" #elif defined(OEM_BUILD) const char *Osreg_app_name = "FreeSpace2OEM"; @@ -41,20 +31,10 @@ const char *Osreg_title = "Freespace 2 OEM"; #elif defined(MAKE_FS1) const char *Osreg_app_name = "FreeSpace"; const char *Osreg_title = "FreeSpace"; -#ifndef __APPLE__ -const char *Osreg_user_dir = ".freespace"; -#else -const char *Osreg_user_dir = "Library/Application Support/FreeSpace"; -#endif #define PROFILE_NAME "FreeSpace.ini" #else const char *Osreg_app_name = "FreeSpace2"; const char *Osreg_title = "Freespace 2"; -#ifndef __APPLE__ -const char *Osreg_user_dir = ".freespace2"; -#else -const char *Osreg_user_dir = "Library/Application Support/Freespace 2"; -#endif #define PROFILE_NAME "FreeSpace2.ini" #endif -- 2.39.2