From 5f287be4a74858793ea36ca8144e2b1720d99d9f Mon Sep 17 00:00:00 2001 From: molivier Date: Sun, 9 Jan 2005 09:07:08 +0000 Subject: [PATCH] - Sys_LoadLibrary now accepts several possible names for a DLL (it fixes the PK3 and Vorbis supports on NetBSD) - Added a check for absolute paths in FS_CheckNastyPath - Moved "COM_Shutdown" after "Log_Close" in the shutdown process to make sure the FS code is still active when we close the log file - Factorized some code in the FS module - Made the "listdirectory" parameter "const" - Fixed a warning in "prvm_cmds.c" when compiling with GCC git-svn-id: svn://svn.icculus.org/twilight/trunk/darkplaces@4909 d7cf8633-e32d-0410-b094-e92efae38249 --- common.h | 2 +- filematch.c | 4 +-- fs.c | 73 +++++++++++++++++++++++----------------------------- host.c | 2 +- jpeg.c | 26 +++++++++---------- prvm_cmds.c | 2 +- snd_ogg.c | 40 ++++++++++++++++++---------- sys.h | 3 ++- sys_shared.c | 26 ++++++++++++------- 9 files changed, 95 insertions(+), 83 deletions(-) diff --git a/common.h b/common.h index d58387ba..9d0ee53d 100644 --- a/common.h +++ b/common.h @@ -228,7 +228,7 @@ int matchpattern(char *in, char *pattern, int caseinsensitive); stringlist_t *stringlistappend(stringlist_t *current, char *text); void stringlistfree(stringlist_t *current); stringlist_t *stringlistsort(stringlist_t *start); -stringlist_t *listdirectory(char *path); +stringlist_t *listdirectory(const char *path); void freedirectory(stringlist_t *list); char *SearchInfostring(const char *infostring, const char *key); diff --git a/filematch.c b/filematch.c index e4a81fdb..a4f670f9 100644 --- a/filematch.c +++ b/filematch.c @@ -118,7 +118,7 @@ stringlist_t *stringlistsort(stringlist_t *start) // operating system specific code #ifdef WIN32 #include -stringlist_t *listdirectory(char *path) +stringlist_t *listdirectory(const char *path) { char pattern[4096], *c; struct _finddata_t n_file; @@ -152,7 +152,7 @@ stringlist_t *listdirectory(char *path) } #else #include -stringlist_t *listdirectory(char *path) +stringlist_t *listdirectory(const char *path) { DIR *dir; struct dirent *ent; diff --git a/fs.c b/fs.c index c9359a20..233800ef 100644 --- a/fs.c +++ b/fs.c @@ -346,22 +346,25 @@ Try to load the Zlib DLL */ qboolean PK3_OpenLibrary (void) { - const char* dllname; - - // Already loaded? - if (zlib_dll) - return true; - + const char* dllnames [] = + { #ifdef WIN32 - dllname = "zlib.dll"; + "zlib.dll", #elif defined(MACOSX) - dllname = "libz.dylib"; + "libz.dylib", #else - dllname = "libz.so.1"; + "libz.so.1", + "libz.so", #endif + NULL + }; + + // Already loaded? + if (zlib_dll) + return true; // Load the DLL - if (! Sys_LoadLibrary (dllname, &zlib_dll, zlibfuncs)) + if (! Sys_LoadLibrary (dllnames, &zlib_dll, zlibfuncs)) { Con_Printf ("Compressed files support disabled\n"); return false; @@ -848,7 +851,7 @@ Sets fs_gamedir, adds the directory to the head of the path, then loads and adds pak1.pak pak2.pak ... ================ */ -void FS_AddGameDirectory (char *dir) +void FS_AddGameDirectory (const char *dir) { stringlist_t *list, *current; searchpath_t *search; @@ -909,31 +912,22 @@ void FS_AddGameDirectory (char *dir) /* ================ -FS_AddHomeAsGameDirectory - -Use ~/.games/darkplaces/dir as fs_gamedir +FS_AddGameHierarchy ================ */ -void FS_AddHomeAsGameDirectory (const char *dir) +void FS_AddGameHierarchy (const char *dir) { -#ifndef _WIN32 - char *homedir=getenv("HOME"); - char gdir[MAX_OSPATH]; - if(homedir) - { - int len = snprintf(gdir,sizeof(gdir),"%s/.darkplaces/%s/", homedir, dir); - Con_Printf("using %s for writing\n",gdir); - FS_CreatePath (gdir); + const char *homedir; - if ((len > 0) && (len < sizeof(gdir)) && (gdir[len-1] == '/')) - gdir[len-1] = 0; + strlcpy (com_modname, dir, sizeof (com_modname)); - strncpy(fs_gamedir,gdir,sizeof(fs_gamedir)-1); - fs_gamedir[sizeof(fs_gamedir)-1] = 0; - - FS_AddGameDirectory (gdir); - } -#endif + // Add the common game directory + FS_AddGameDirectory (va("%s/%s", fs_basedir, dir)); + + // Add the personal game directory + homedir = getenv ("HOME"); + if (homedir != NULL && homedir[0] != '\0') + FS_AddGameDirectory (va("%s/.darkplaces/%s", homedir, dir)); } @@ -1037,18 +1031,14 @@ void FS_Init (void) } // start up with GAMENAME by default (id1) - strlcpy (com_modname, GAMENAME, sizeof (com_modname)); - FS_AddGameDirectory (va("%s/"GAMENAME, fs_basedir)); - FS_AddHomeAsGameDirectory(GAMENAME); + FS_AddGameHierarchy (GAMENAME); Cvar_SetQuick (&scr_screenshot_name, gamescreenshotname); // add the game-specific path, if any if (gamedirname[0]) { fs_modified = true; - strlcpy (com_modname, gamedirname, sizeof (com_modname)); - FS_AddGameDirectory (va("%s/%s", fs_basedir, gamedirname)); - FS_AddHomeAsGameDirectory(gamedirname); + FS_AddGameHierarchy (gamedirname); } // -game @@ -1062,9 +1052,7 @@ void FS_Init (void) { i++; fs_modified = true; - strlcpy (com_modname, com_argv[i], sizeof (com_modname)); - FS_AddGameDirectory (va("%s/%s", fs_basedir, com_argv[i])); - FS_AddHomeAsGameDirectory(com_argv[i]); + FS_AddGameHierarchy (com_argv[i]); Cvar_SetQuick (&scr_screenshot_name, com_modname); } } @@ -1200,7 +1188,10 @@ int FS_CheckNastyPath (const char *path) return 1; // non-portable attempt to go to parent directory // all: don't allow going to current directory (./) or parent directory (../ or /../) if (strstr(path, "./")) - return 2; // attempt to go to parent directory + return 2; // attempt to go outside the game directory + // Windows and UNIXes: don't allow absolute paths + if (path[0] == '/') + return 2; // attempt to go outside the game directory // after all these checks we're pretty sure it's a / separated filename // and won't do much if any harm return false; diff --git a/host.c b/host.c index c7f92fa2..a6b1e8c2 100644 --- a/host.c +++ b/host.c @@ -1017,7 +1017,6 @@ void Host_Shutdown(void) S_Terminate (); NetConn_Shutdown (); PR_Shutdown (); - COM_Shutdown (); Cbuf_Shutdown (); if (cls.state != ca_dedicated) @@ -1030,6 +1029,7 @@ void Host_Shutdown(void) CL_Shutdown(); Sys_Shutdown(); Log_Close (); + COM_Shutdown (); Memory_Shutdown(); } diff --git a/jpeg.c b/jpeg.c index 964b170c..70bd13da 100644 --- a/jpeg.c +++ b/jpeg.c @@ -395,25 +395,25 @@ Try to load the JPEG DLL */ qboolean JPEG_OpenLibrary (void) { - const char* dllname; - - // Already loaded? - if (jpeg_dll) - return true; - -// TODO: make Sys_LoadLibrary support multiple names + const char* dllnames [] = + { #ifdef WIN32 - dllname = "libjpeg.dll"; -#elif defined(__FreeBSD__) - dllname = "libjpeg.so"; + "libjpeg.dll", #elif defined(MACOSX) - dllname = "libjpeg.62.dylib"; + "libjpeg.62.dylib", #else - dllname = "libjpeg.so.62"; + "libjpeg.so.62", + "libjpeg.so", #endif + NULL + }; + + // Already loaded? + if (jpeg_dll) + return true; // Load the DLL - if (! Sys_LoadLibrary (dllname, &jpeg_dll, jpegfuncs)) + if (! Sys_LoadLibrary (dllnames, &jpeg_dll, jpegfuncs)) { Con_Printf ("JPEG support disabled\n"); return false; diff --git a/prvm_cmds.c b/prvm_cmds.c index 4bf7209b..323b5377 100644 --- a/prvm_cmds.c +++ b/prvm_cmds.c @@ -3106,7 +3106,7 @@ void VM_altstr_set( void ) for( ; *str; *out++ = *str++ ); // now jump over the old contents for( ; *in ; in++ ) - if( *in == '\'' || *in == '\\' && !*++in ) + if( *in == '\'' || (*in == '\\' && !*++in) ) break; if( !in ) { diff --git a/snd_ogg.c b/snd_ogg.c index fd4e362a..61390198 100644 --- a/snd_ogg.c +++ b/snd_ogg.c @@ -294,7 +294,30 @@ Try to load the VorbisFile DLL */ qboolean OGG_OpenLibrary (void) { - const char *dllname_vo, *dllname_vf; + const char* dllnames_vo [] = + { +#ifdef WIN32 + "vorbis.dll", +#elif defined(MACOSX) + "libvorbis.dylib", +#else + "libvorbis.so.0", + "libvorbis.so", +#endif + NULL + }; + const char* dllnames_vf [] = + { +#ifdef WIN32 + "vorbisfile.dll", +#elif defined(MACOSX) + "libvorbisfile.dylib", +#else + "libvorbisfile.so.3", + "libvorbisfile.so", +#endif + NULL + }; // Already loaded? if (vf_dll) @@ -304,22 +327,11 @@ qboolean OGG_OpenLibrary (void) if (COM_CheckParm("-novorbis")) return false; -#ifdef WIN32 - dllname_vo = "vorbis.dll"; - dllname_vf = "vorbisfile.dll"; -#elif defined(MACOSX) - dllname_vo = "libvorbis.dylib"; - dllname_vf = "libvorbisfile.dylib"; -#else - dllname_vo = "libvorbis.so.0"; - dllname_vf = "libvorbisfile.so.3"; -#endif - // Load the DLLs // We need to load both by hand because some OSes seem to not load // the vorbis DLL automatically when loading the VorbisFile DLL - if (! Sys_LoadLibrary (dllname_vo, &vo_dll, NULL) || - ! Sys_LoadLibrary (dllname_vf, &vf_dll, oggvorbisfuncs)) + if (! Sys_LoadLibrary (dllnames_vo, &vo_dll, NULL) || + ! Sys_LoadLibrary (dllnames_vf, &vf_dll, oggvorbisfuncs)) { Sys_UnloadLibrary (&vo_dll); Con_Printf ("Ogg Vorbis support disabled\n"); diff --git a/sys.h b/sys.h index 1890fce2..4a992f6d 100644 --- a/sys.h +++ b/sys.h @@ -44,7 +44,8 @@ typedef struct } dllfunction_t; -qboolean Sys_LoadLibrary (const char* dllname, dllhandle_t* handle, const dllfunction_t *fcts); +// "dllnames" is an NULL terminated array of possible names for the DLL you want to load +qboolean Sys_LoadLibrary (const char** dllnames, dllhandle_t* handle, const dllfunction_t *fcts); void Sys_UnloadLibrary (dllhandle_t* handle); void* Sys_GetProcAddress (dllhandle_t handle, const char* name); diff --git a/sys_shared.c b/sys_shared.c index 28529c59..e876daf1 100644 --- a/sys_shared.c +++ b/sys_shared.c @@ -74,10 +74,11 @@ DLL MANAGEMENT =============================================================================== */ -qboolean Sys_LoadLibrary (const char* dllname, dllhandle_t* handle, const dllfunction_t *fcts) +qboolean Sys_LoadLibrary (const char** dllnames, dllhandle_t* handle, const dllfunction_t *fcts) { const dllfunction_t *func; - dllhandle_t dllhandle; + dllhandle_t dllhandle = 0; + unsigned int i; if (handle == NULL) return false; @@ -86,17 +87,25 @@ qboolean Sys_LoadLibrary (const char* dllname, dllhandle_t* handle, const dllfun for (func = fcts; func && func->name != NULL; func++) *func->funcvariable = NULL; - // Load the DLL + // Try every possible name + for (i = 0; dllnames[i] != NULL; i++) + { #ifdef WIN32 - dllhandle = LoadLibrary (dllname); + dllhandle = LoadLibrary (dllnames[i]); #else - dllhandle = dlopen (dllname, RTLD_LAZY); + dllhandle = dlopen (dllnames[i], RTLD_LAZY); #endif + if (dllhandle) + break; + + Con_Printf ("Can't load \"%s\".\n", dllnames[i]); + } + + // No DLL found if (! dllhandle) - { - Con_Printf ("Can't load \"%s\".\n", dllname); return false; - } + + Con_Printf("\"%s\" loaded.\n", dllnames[i]); // Get the function adresses for (func = fcts; func && func->name != NULL; func++) @@ -108,7 +117,6 @@ qboolean Sys_LoadLibrary (const char* dllname, dllhandle_t* handle, const dllfun } *handle = dllhandle; - Con_Printf("\"%s\" loaded.\n", dllname); return true; } -- 2.39.2