mirror of
https://github.com/id-Software/DOOM-3-BFG.git
synced 2024-12-11 13:11:47 +00:00
Fix Sys_ListFiles() on POSIX as needed for savegames
In Sys_ListFiles() the extension was abused to match whole filenames (of savegames), not just their extensions - that didn't work with the POSIX backend, now it does. Sys_ListFiles() now also supports "*" as a wildcard that matches all files - needed for deleting savegames. However, things like "bl*" or "*ub" don't work. While at it, I replaced readdir() with the thread-safe readdir_r()
This commit is contained in:
parent
f77ca851d5
commit
1e3bc3429b
1 changed files with 35 additions and 9 deletions
|
@ -359,8 +359,11 @@ int Sys_ListFiles( const char* directory, const char* extension, idStrList& list
|
||||||
|
|
||||||
debug = cvarSystem->GetCVarBool( "fs_debug" );
|
debug = cvarSystem->GetCVarBool( "fs_debug" );
|
||||||
|
|
||||||
if( !extension )
|
// DG: handle "*" as special case that matches everything
|
||||||
|
// FIXME: handle * properly as a wildcase somewhere in the string?
|
||||||
|
if( !extension || ( extension[0] == '*' && extension[1] == '\0' ) )
|
||||||
extension = "";
|
extension = "";
|
||||||
|
// DG end
|
||||||
|
|
||||||
// passing a slash as extension will find directories
|
// passing a slash as extension will find directories
|
||||||
if( extension[0] == '/' && extension[1] == 0 )
|
if( extension[0] == '/' && extension[1] == 0 )
|
||||||
|
@ -380,20 +383,42 @@ int Sys_ListFiles( const char* directory, const char* extension, idStrList& list
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
while( ( d = readdir( fdir ) ) != NULL )
|
// DG: use readdir_r instead of readdir for thread safety
|
||||||
|
// the following lines are from the readdir_r manpage.. fscking ugly.
|
||||||
|
int nameMax = pathconf( directory, _PC_NAME_MAX );
|
||||||
|
if( nameMax == -1 )
|
||||||
|
nameMax = 255;
|
||||||
|
int direntLen = offsetof( struct dirent, d_name ) + nameMax + 1;
|
||||||
|
|
||||||
|
struct dirent* entry = ( struct dirent* )Mem_Alloc( direntLen, TAG_CRAP );
|
||||||
|
|
||||||
|
if( entry == NULL )
|
||||||
{
|
{
|
||||||
|
common->Warning( "Sys_ListFiles: Mem_Alloc for entry failed!" );
|
||||||
|
closedir( fdir );
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int extLen = idStr::Length( extension );
|
||||||
|
|
||||||
|
while( readdir_r( fdir, entry, &d ) == 0 && d != NULL )
|
||||||
|
{
|
||||||
|
// DG end
|
||||||
idStr::snPrintf( search, sizeof( search ), "%s/%s", directory, d->d_name );
|
idStr::snPrintf( search, sizeof( search ), "%s/%s", directory, d->d_name );
|
||||||
if( stat( search, &st ) == -1 )
|
if( stat( search, &st ) == -1 )
|
||||||
continue;
|
continue;
|
||||||
if( !dironly )
|
if( !dironly )
|
||||||
{
|
{
|
||||||
idStr look( search );
|
// DG: the original code didn't work because d3 bfg abuses the extension
|
||||||
idStr ext;
|
// to match whole filenames in the savegame-code, not just file extensions...
|
||||||
look.ExtractFileExtension( ext );
|
// the extension must be the last chars of the filename
|
||||||
if( extension[0] != '\0' && ext.Icmp( &extension[1] ) != 0 )
|
// so start matching at startPos = strlen(d->d_name) - strlen(extension)
|
||||||
{
|
int startPos = idStr::Length( d->d_name ) - extLen;
|
||||||
|
// of course the extension can't match if it's longer than the filename, i.e. startPos < 0
|
||||||
|
if( startPos < 0 || idStr::FindText( d->d_name, extension, true, startPos ) < 0 )
|
||||||
continue;
|
continue;
|
||||||
}
|
|
||||||
|
// DG end
|
||||||
}
|
}
|
||||||
if( ( dironly && !( st.st_mode & S_IFDIR ) ) ||
|
if( ( dironly && !( st.st_mode & S_IFDIR ) ) ||
|
||||||
( !dironly && ( st.st_mode & S_IFDIR ) ) )
|
( !dironly && ( st.st_mode & S_IFDIR ) ) )
|
||||||
|
@ -403,6 +428,7 @@ int Sys_ListFiles( const char* directory, const char* extension, idStrList& list
|
||||||
}
|
}
|
||||||
|
|
||||||
closedir( fdir );
|
closedir( fdir );
|
||||||
|
Mem_Free( entry );
|
||||||
|
|
||||||
if( debug )
|
if( debug )
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in a new issue