|
|
@ -13,14 +13,23 @@ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|
|
|
GNU General Public License for more details. |
|
|
|
GNU General Public License for more details. |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#include "build.h" |
|
|
|
#include <sys/types.h> |
|
|
|
#include <sys/types.h> |
|
|
|
#include <sys/stat.h> |
|
|
|
#include <sys/stat.h> |
|
|
|
#include <fcntl.h> |
|
|
|
#include <fcntl.h> |
|
|
|
|
|
|
|
#include <errno.h> |
|
|
|
|
|
|
|
#include <stddef.h> |
|
|
|
#if XASH_POSIX |
|
|
|
#if XASH_POSIX |
|
|
|
#include <unistd.h> |
|
|
|
#include <unistd.h> |
|
|
|
|
|
|
|
#include <sys/ioctl.h> |
|
|
|
#endif |
|
|
|
#endif |
|
|
|
#include <errno.h> |
|
|
|
#if XASH_LINUX |
|
|
|
#include <stddef.h> |
|
|
|
#include <linux/fs.h> |
|
|
|
|
|
|
|
#ifndef FS_CASEFOLD_FL // for compatibility with older distros
|
|
|
|
|
|
|
|
#define FS_CASEFOLD_FL 0x40000000 |
|
|
|
|
|
|
|
#endif // FS_CASEFOLD_FL
|
|
|
|
|
|
|
|
#endif // XASH_LINUX
|
|
|
|
|
|
|
|
|
|
|
|
#include "port.h" |
|
|
|
#include "port.h" |
|
|
|
#include "filesystem_internal.h" |
|
|
|
#include "filesystem_internal.h" |
|
|
|
#include "crtlib.h" |
|
|
|
#include "crtlib.h" |
|
|
@ -41,6 +50,29 @@ typedef struct dir_s |
|
|
|
struct dir_s *entries; // sorted
|
|
|
|
struct dir_s *entries; // sorted
|
|
|
|
} dir_t; |
|
|
|
} dir_t; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
static qboolean Platform_GetDirectoryCaseSensitivity( const char *dir ) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
#if XASH_WIN32 |
|
|
|
|
|
|
|
return false; |
|
|
|
|
|
|
|
#elif XASH_LINUX && defined( FS_IOC_GETFLAGS ) |
|
|
|
|
|
|
|
int flags = 0; |
|
|
|
|
|
|
|
int fd; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
fd = open( dir, O_RDONLY | O_NONBLOCK ); |
|
|
|
|
|
|
|
if( fd < 0 ) |
|
|
|
|
|
|
|
return true; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if( ioctl( fd, FS_IOC_GETFLAGS, &flags ) < 0 ) |
|
|
|
|
|
|
|
return true; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
close( fd ); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return !FBitSet( flags, FS_CASEFOLD_FL ); |
|
|
|
|
|
|
|
#else |
|
|
|
|
|
|
|
return true; |
|
|
|
|
|
|
|
#endif |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
static int FS_SortDirEntries( const void *_a, const void *_b ) |
|
|
|
static int FS_SortDirEntries( const void *_a, const void *_b ) |
|
|
|
{ |
|
|
|
{ |
|
|
|
const dir_t *a = _a; |
|
|
|
const dir_t *a = _a; |
|
|
@ -82,10 +114,6 @@ static void FS_InitDirEntries( dir_t *dir, const stringlist_t *list ) |
|
|
|
|
|
|
|
|
|
|
|
static void FS_PopulateDirEntries( dir_t *dir, const char *path ) |
|
|
|
static void FS_PopulateDirEntries( dir_t *dir, const char *path ) |
|
|
|
{ |
|
|
|
{ |
|
|
|
#if XASH_WIN32 // Windows is always case insensitive
|
|
|
|
|
|
|
|
dir->numentries = DIRENTRY_CASEINSENSITIVE; |
|
|
|
|
|
|
|
dir->entries = NULL; |
|
|
|
|
|
|
|
#else |
|
|
|
|
|
|
|
stringlist_t list; |
|
|
|
stringlist_t list; |
|
|
|
|
|
|
|
|
|
|
|
if( !FS_SysFolderExists( path )) |
|
|
|
if( !FS_SysFolderExists( path )) |
|
|
@ -95,6 +123,13 @@ static void FS_PopulateDirEntries( dir_t *dir, const char *path ) |
|
|
|
return; |
|
|
|
return; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if( !Platform_GetDirectoryCaseSensitivity( path )) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
dir->numentries = DIRENTRY_CASEINSENSITIVE; |
|
|
|
|
|
|
|
dir->entries = NULL; |
|
|
|
|
|
|
|
return; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
stringlistinit( &list ); |
|
|
|
stringlistinit( &list ); |
|
|
|
listdirectory( &list, path ); |
|
|
|
listdirectory( &list, path ); |
|
|
|
if( !list.numstrings ) |
|
|
|
if( !list.numstrings ) |
|
|
@ -107,7 +142,6 @@ static void FS_PopulateDirEntries( dir_t *dir, const char *path ) |
|
|
|
FS_InitDirEntries( dir, &list ); |
|
|
|
FS_InitDirEntries( dir, &list ); |
|
|
|
} |
|
|
|
} |
|
|
|
stringlistfreecontents( &list ); |
|
|
|
stringlistfreecontents( &list ); |
|
|
|
#endif |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
static int FS_FindDirEntry( dir_t *dir, const char *name ) |
|
|
|
static int FS_FindDirEntry( dir_t *dir, const char *name ) |
|
|
|