Moved the path conversion code to lx_loader.c, and use it.

Fixes loading "emx.dll" when the loader asked for "EMX.dll", etc.
This commit is contained in:
Ryan C. Gordon committed 2016-10-17 21:10:29 -04:00
1 parent 2016af81a2
commit 60e62a1306
3 files changed
+110 -96

No files matched your search

+1 -96
View File
@@ -752,104 +752,9 @@ APIRET DosGetDateTime(PDATETIME pdt)
return NO_ERROR; // never returns failure.
} // DosGetDateTime
// based on case-insensitive search code from PhysicsFS:
// https://icculus.org/physfs/
// It's also zlib-licensed, plus I wrote it. :) --ryan.
// !!! FIXME: this doesn't work as-is for UTF-8 case folding, since string
// !!! FIXNE: length can change!
static int locateOneElement(char *buf)
{
if (access(buf, F_OK) == 0)
return 1; // quick rejection: exists in current case.
DIR *dirp;
char *ptr = strrchr(buf, '/'); // find entry at end of path.
if ((ptr == NULL) || (ptr == buf)) {
dirp = opendir("/");
ptr = buf;
} else {
*ptr = '\0';
dirp = opendir(buf);
*ptr = '/';
ptr++; // point past dirsep to entry itself.
} // else
for (struct dirent *dent = readdir(dirp); dent; dent = readdir(dirp)) {
if (strcasecmp(dent->d_name, ptr) == 0) {
strcpy(ptr, dent->d_name); // found a match. Overwrite with this case.
closedir(dirp);
return 1;
} // if
} // for
// no match at all...
closedir(dirp);
return 0;
} // locateOneElement
static int locatePathCaseInsensitive(char *buf)
{
int rc;
char *ptr = buf;
if (*ptr == '\0')
return 0; // Uh...I guess that's success?
if (access(buf, F_OK) == 0)
return 0; // quick rejection: exists in current case.
while ( (ptr = strchr(ptr + 1, '/')) != NULL ) {
*ptr = '\0'; // block this path section off
rc = locateOneElement(buf);
*ptr = '/'; // restore path separator
if (!rc)
return -2; // missing element in path.
} // while
// check final element...
return locateOneElement(buf) ? 0 : -1;
} // locatePathCaseInsensitive
static char *makeUnixPath(const char *os2path, APIRET *err)
{
if ((strcasecmp(os2path, "NUL") == 0) || (strcasecmp(os2path, "\\DEV\\NUL") == 0))
os2path = "/dev/null";
// !!! FIXME: emulate other OS/2 device names (CON, etc).
//else if (strcasecmp(os2path, "CON") == 0)
else {
char drive = os2path[0];
if ((drive >= 'a') && (drive <= 'z'))
drive += 'A' - 'a';
if ((drive >= 'A') && (drive <= 'Z')) {
if (os2path[1] == ':') { // it's a drive letter.
if (drive == 'C')
os2path += 2; // skip "C:" if it's there.
else {
*err = ERROR_NOT_DOS_DISK;
return NULL;
} // else
} // if
} // if
} // else
const size_t len = strlen(os2path);
char *retval = (char *) malloc(len + 1);
if (!retval) {
*err = ERROR_NOT_ENOUGH_MEMORY;
return NULL;
} // else
strcpy(retval, os2path);
for (char *ptr = strchr(retval, '\\'); ptr; ptr = strchr(ptr + 1, '\\'))
*ptr = '/'; // convert to Unix-style path separators.
locatePathCaseInsensitive(retval);
return retval;
return GLoaderState->makeUnixPath(os2path, (uint32 *) err);
} // makeUnixPath
static APIRET doDosOpen(PSZ pszFileName, PHFILE pHf, PULONG pulAction, LONGLONG cbFile, ULONG ulAttribute, ULONG fsOpenFlags, ULONG fsOpenMode, PEAOP2 peaop2)