X-Git-Url: https://git.jsancho.org/?a=blobdiff_plain;f=Source%2FMacCompatibility.cpp;h=e1226b608dc32edd854176e8d7b2bd56888b3257;hb=c33352410441ce5656f7c65eea696b5f799fefeb;hp=b05d2b91bc27541fbc6ebec0459dce6a648b6685;hpb=68db9594c12cd81dd246c2c0c511a499ac04b2fd;p=lugaru.git diff --git a/Source/MacCompatibility.cpp b/Source/MacCompatibility.cpp index b05d2b9..e1226b6 100644 --- a/Source/MacCompatibility.cpp +++ b/Source/MacCompatibility.cpp @@ -122,9 +122,13 @@ Duration AbsoluteDeltaToDuration( AbsoluteTime& a, AbsoluteTime& b) #if PLATFORM_UNIX #include +#include +#include +#include #include -// public domain code from PhysicsFS: http://icculus.org/physfs/ +// some but not all of this is code from PhysicsFS: http://icculus.org/physfs/ +// the zlib license on physfs allows this cut-and-pasting. static int locateOneElement(char *buf) { char *ptr; @@ -167,34 +171,93 @@ static int locateOneElement(char *buf) } /* locateOneElement */ -static inline int PHYSFSEXT_locateCorrectCase(char *buf) +static inline const char *getUserDirByUID(void) +{ + struct passwd *pw = getpwuid(getuid()); + if (pw != NULL) + return(pw->pw_dir); + return(NULL); +} /* getUserDirByUID */ + + +static inline const char *getPrefPath(void) +{ + static char *prefpath = NULL; + if (prefpath == NULL) + { + const char *homedir = getenv("HOME"); + if (homedir == NULL) + homedir = getUserDirByUID(); + if (homedir == NULL) + homedir = "."; // oh well. + + const char *PREFPATHNAME = ".lugaru"; + size_t len = strlen(homedir) + strlen(PREFPATHNAME) + 2; + prefpath = new char[len]; + snprintf(prefpath, len, "%s/%s", homedir, PREFPATHNAME); + } + return(prefpath); +} + +static int locateCorrectCase(char *buf, bool makedirs) { int rc; char *ptr; char *prevptr; ptr = prevptr = buf; - if (*ptr == '\0') - return(0); /* Uh...I guess that's success. */ - while (ptr = strchr(ptr + 1, '/')) { *ptr = '\0'; /* block this path section off */ rc = locateOneElement(buf); - *ptr = '/'; /* restore path separator */ if (!rc) - return(-2); /* missing element in path. */ + { + if (makedirs) /* normal if we're writing; build dirs! */ + mkdir(buf, S_IRWXU); + else + { + *ptr = '/'; /* restore path separator */ + return(-2); /* missing element in path. */ + } /* else */ + } /* if */ + *ptr = '/'; /* restore path separator */ } /* while */ /* check final element... */ return(locateOneElement(buf) ? 0 : -1); -} /* PHYSFSEXT_locateCorrectCase */ +} + + +static int locateCorrectFile(char *buf, const char *mode) +{ + if (*buf == '\0') + return(0); /* Uh...I guess that's failure. */ + + assert((mode[0] == 'w') || (mode[0] == 'r')); + + bool iswriting = (mode[0] == 'w'); + const char *prefpath = getPrefPath(); + size_t len = strlen(buf) + strlen(prefpath) + 2; + char *prefpathfile = (char *) alloca(len); + snprintf(prefpathfile, len, "%s/%s", prefpath, buf); + + int rc = locateCorrectCase(prefpathfile, iswriting); /* favor prefpath. */ + if ( (rc == 0) || ((rc == -1) && (iswriting)) ) // found or create? + strcpy(buf, prefpathfile); + else if ((rc < 0) && (!iswriting)) /* not writing? Try game dir... */ + rc = locateCorrectCase(buf, iswriting); + + return(rc); +} /* locateCorrectFile */ #endif -static char g_filename[ 256]; -char* ConvertFileName( const char* orgfilename) +static char g_filename[4096]; +char* ConvertFileName( const char* orgfilename, const char *mode) { + if (orgfilename == g_filename) // recursion? + return g_filename; + // translate filename into proper path name if (orgfilename[ 0] == ':') orgfilename++; @@ -204,10 +267,13 @@ char* ConvertFileName( const char* orgfilename) { if (g_filename[ n] == ':') g_filename[ n] = '/'; + + else if (g_filename[ n] == '\\') + g_filename[ n] = '/'; } #if PLATFORM_UNIX - PHYSFSEXT_locateCorrectCase(g_filename); + locateCorrectFile(g_filename, mode); #endif return g_filename;