summaryrefslogtreecommitdiff
path: root/source/files.c
diff options
context:
space:
mode:
Diffstat (limited to 'source/files.c')
-rw-r--r--source/files.c433
1 files changed, 189 insertions, 244 deletions
diff --git a/source/files.c b/source/files.c
index 8be2bac..bc77e7d 100644
--- a/source/files.c
+++ b/source/files.c
@@ -41,9 +41,6 @@ QUAKE FILESYSTEM
#define MAX_FILES_IN_PK2 0x4000
#define MAX_FILE_HANDLES 8
-#define FS_Malloc( size ) Z_TagMalloc( size, TAG_FILESYSTEM )
-#define FS_CopyString( string ) Z_TagCopyString( string, TAG_FILESYSTEM )
-
// macros for dealing portably with files at OS level
#ifdef _WIN32
#define FS_strcmp Q_strcasecmp
@@ -879,7 +876,7 @@ static char *FS_ExpandLinks( const char *filename ) {
FS_FOpenFile
============
*/
-int FS_FOpenFile( const char *name, fileHandle_t *f, uint32 mode ) {
+int FS_FOpenFile( const char *name, fileHandle_t *f, int mode ) {
fsFile_t *file;
fileHandle_t hFile;
int ret = -1;
@@ -1017,7 +1014,7 @@ Filenames are relative to the quake search path
a null buffer will just return the file length without loading
============
*/
-int FS_LoadFileEx( const char *path, void **buffer, uint32 flags ) {
+int FS_LoadFileEx( const char *path, void **buffer, int flags ) {
fsFile_t *file;
fileHandle_t f;
byte *buf;
@@ -1343,7 +1340,7 @@ static pack_t *FS_LoadPakFile( const char *packfile ) {
names += len;
}
- FS_DPrintf( "Added pakfile %s, %d files, %d hash table entries\n",
+ FS_DPrintf( "%s: %d files, %d hash table entries\n",
packfile, numpackfiles, hashSize );
return pack;
@@ -1456,7 +1453,7 @@ static pack_t *FS_LoadZipFile( const char *packfile ) {
}
}
- FS_DPrintf( "Added zipfile '%s', %d files, %d hash table entries\n",
+ FS_DPrintf( "%s: %d files, %d hash table entries\n",
packfile, numFiles, hashSize );
return pack;
@@ -1500,11 +1497,11 @@ static void FS_LoadPackFiles( const char *extension, pack_t *(loadfunc)( const c
int i;
searchpath_t *search;
pack_t *pak;
- char ** list;
+ void **list;
int numFiles;
char path[MAX_OSPATH];
- list = Sys_ListFiles( fs_gamedir, extension, FS_SEARCH_NOSORT, &numFiles );
+ list = Sys_ListFiles( fs_gamedir, extension, FS_SEARCH_NOSORT, 0, &numFiles );
if( !list ) {
return;
}
@@ -1521,8 +1518,7 @@ static void FS_LoadPackFiles( const char *extension, pack_t *(loadfunc)( const c
fs_searchpaths = search;
}
- Sys_FreeFileList( list );
-
+ FS_FreeList( list );
}
/*
@@ -1574,81 +1570,40 @@ static void q_printf( 1, 2 ) FS_AddGameDirectory( const char *fmt, ... ) {
#endif
}
-
/*
=================
-FS_GetModList
+FS_CopyInfo
=================
*/
-#define MAX_LISTED_MODS 32
-
-static void FS_GetModList( char **list, int *count ) {
- char path[MAX_OSPATH];
- FILE *fp;
- char **dirlist;
- int numDirs;
- int i;
+fsFileInfo_t *FS_CopyInfo( const char *name, int size, time_t ctime, time_t mtime ) {
+ fsFileInfo_t *out;
+ int len;
- if( !( dirlist = Sys_ListFiles( sys_basedir->string, NULL, FS_SEARCHDIRS_ONLY, &numDirs ) ) ) {
- return;
+ if( !name ) {
+ return NULL;
}
- for( i = 0; i < numDirs; i++ ) {
- if( !strcmp( dirlist[i], BASEGAME ) ) {
- continue;
- }
-
-#ifdef _WIN32
- Com_sprintf( path, sizeof( path ), "%s/%s/gamex86.dll", sys_basedir->string, dirlist[i] );
-#else
- Com_sprintf( path, sizeof( path ), "%s/%s/gamei386.so", sys_basedir->string, dirlist[i] );
-#endif
+ len = strlen( name );
+ out = FS_Malloc( sizeof( *out ) + len );
+ out->size = size;
+ out->ctime = ctime;
+ out->mtime = mtime;
+ memcpy( out->name, name, len + 1 );
- if( !( fp = fopen( path, "rb" ) ) ) {
- continue;
- }
- fclose( fp );
-
- Com_sprintf( path, sizeof( path ), "%s/%s/description.txt", sys_basedir->string, dirlist[i] );
-
- if( ( fp = fopen( path, "r" ) ) != NULL ) {
- Q_strncpyz( path, va( "%s\n", dirlist[i] ), sizeof( path ) - MAX_QPATH );
- fgets( path + strlen( path ), MAX_QPATH, fp );
- fclose( fp );
- list[*count] = FS_CopyString( path );
- } else {
- list[*count] = FS_CopyString( dirlist[i] );
- }
-
- if( (*count)++ == MAX_LISTED_MODS ) {
- break;
- }
- }
-
- Sys_FreeFileList( dirlist );
+ return out;
}
-/*
-=================
-FS_CopyExtraInfo
-=================
-*/
-char *FS_CopyExtraInfo( const char *name, const fsFileInfo_t *info ) {
- char *out;
- int length;
+void **FS_CopyList( void **list, int count ) {
+ void **out;
+ int i;
- if( !name ) {
- return NULL;
+ out = FS_Malloc( sizeof( void * ) * ( count + 1 ) );
+ for( i = 0; i < count; i++ ) {
+ out[i] = list[i];
}
+ out[i] = NULL;
- length = strlen( name ) + 1;
-
- out = FS_Malloc( sizeof( *info ) + length );
- strcpy( out, name );
-
- memcpy( out + length, info, sizeof( *info ) );
-
- return out;
+ return out;
}
#if 0
@@ -1757,19 +1712,20 @@ rescan:
FS_ListFiles
=================
*/
-char **FS_ListFiles( const char *path, const char *extension,
- uint32 flags, int *numFiles )
+void **FS_ListFiles( const char *path,
+ const char *extension,
+ int flags,
+ int *numFiles )
{
searchpath_t *search;
- char *listedFiles[MAX_LISTED_FILES];
+ void *listedFiles[MAX_LISTED_FILES];
int count, total;
char buffer[MAX_OSPATH];
- char **dirlist;
- int numFilesInDir;
- char **list;
- int i, length;
- char *name, *filename;
- fsFileInfo_t info;
+ void **dirlist;
+ int dircount;
+ void **list;
+ int i, len, pathlen;
+ char *s;
if( flags & FS_SEARCH_BYFILTER ) {
if( !extension ) {
@@ -1779,7 +1735,10 @@ char **FS_ListFiles( const char *path, const char *extension,
if( !path ) {
path = "";
- }
+ pathlen = 0;
+ } else {
+ pathlen = strlen( path );
+ }
count = 0;
@@ -1787,161 +1746,155 @@ char **FS_ListFiles( const char *path, const char *extension,
*numFiles = 0;
}
- if( !strcmp( path, "$modlist" ) ) {
- FS_GetModList( listedFiles, &count );
- } else {
- memset( &info, 0, sizeof( info ) );
+ for( search = FS_SearchPath( flags ); search; search = search->next ) {
+ if( ( flags & FS_PATH_MASK ) == FS_PATH_GAME ) {
+ if( fs_searchpaths != fs_base_searchpaths && search == fs_base_searchpaths ) {
+ // consider baseq2 a gamedir if no gamedir loaded
+ break;
+ }
+ }
+ if( search->pack ) {
+ if( ( flags & FS_TYPE_MASK ) == FS_TYPE_REAL ) {
+ // don't search in paks
+ continue;
+ }
- for( search = FS_SearchPath( flags ); search; search = search->next ) {
- if( ( flags & FS_PATH_MASK ) == FS_PATH_GAME ) {
- if( fs_searchpaths != fs_base_searchpaths && search == fs_base_searchpaths ) {
- // consider baseq2 a gamedir if no gamedir loaded
- break;
- }
- }
- if( search->pack ) {
- if( ( flags & FS_TYPE_MASK ) == FS_TYPE_REAL ) {
- // don't search in paks
- continue;
- }
+ // TODO: add directory search support for pak files
+ if( ( flags & FS_SEARCHDIRS_MASK ) == FS_SEARCHDIRS_ONLY ) {
+ continue;
+ }
- // TODO: add directory search support for pak files
- if( ( flags & FS_SEARCHDIRS_MASK ) == FS_SEARCHDIRS_ONLY ) {
- continue;
- }
+ if( flags & FS_SEARCH_BYFILTER ) {
+ for( i = 0; i < search->pack->numfiles; i++ ) {
+ s = search->pack->files[i].name;
+
+ // check path
+ if( pathlen ) {
+ if( Q_stricmpn( s, path, pathlen ) ) {
+ continue;
+ }
+ s += pathlen + 1;
+ }
- if( flags & FS_SEARCH_BYFILTER ) {
- for( i = 0; i < search->pack->numfiles; i++ ) {
- name = search->pack->files[i].name;
-
- // check path
- filename = name;
- if( *path ) {
- length = strlen( path );
- if( Q_stricmpn( name, path, length ) ) {
- continue;
- }
- filename += length + 1;
- }
+ // check filter
+ if( !FS_WildCmp( extension, s ) ) {
+ continue;
+ }
- // check filter
- if( !FS_WildCmp( extension, filename ) ) {
- continue;
- }
+ // copy filename
+ if( count == MAX_LISTED_FILES ) {
+ break;
+ }
- // copy filename
- if( count == MAX_LISTED_FILES ) {
- break;
- }
+ if( !( flags & FS_SEARCH_SAVEPATH ) ) {
+ s = COM_SkipPath( s );
+ }
+ if( flags & FS_SEARCH_EXTRAINFO ) {
+ listedFiles[count++] = FS_CopyInfo( s,
+ search->pack->files[i].filelen, 0, 0 );
+ } else {
+ listedFiles[count++] = FS_CopyString( s );
+ }
+ }
+ } else {
+ for( i = 0; i < search->pack->numfiles; i++ ) {
+ s = search->pack->files[i].name;
+
+ // check path
+ if( pathlen && Q_stricmpn( s, path, pathlen ) ) {
+ continue;
+ }
- if( !( flags & FS_SEARCH_SAVEPATH ) ) {
- filename = COM_SkipPath( filename );
- }
- if( flags & FS_SEARCH_EXTRAINFO ) {
- info.fileSize = search->pack->files[i].filelen;
- listedFiles[count++] = FS_CopyExtraInfo( filename, &info );
- } else {
- listedFiles[count++] = FS_CopyString( filename );
- }
+ // check extension
+ if( extension && !FS_ExtCmp( extension, s ) ) {
+ continue;
}
- } else {
- for( i = 0; i < search->pack->numfiles; i++ ) {
- name = search->pack->files[i].name;
-
- // check path
- if( *path ) {
- COM_FilePath( name, buffer, sizeof( buffer ) );
- if( Q_stricmp( path, buffer ) ) {
- continue;
- }
- }
+
+ // copy filename
+ if( count == MAX_LISTED_FILES ) {
+ break;
+ }
+ if( !( flags & FS_SEARCH_SAVEPATH ) ) {
+ s = COM_SkipPath( s );
+ }
+ if( flags & FS_SEARCH_EXTRAINFO ) {
+ listedFiles[count++] = FS_CopyInfo( s,
+ search->pack->files[i].filelen, 0, 0 );
+ } else {
+ listedFiles[count++] = FS_CopyString( s );
+ }
+ }
+ }
+ } else {
+ if( ( flags & FS_TYPE_MASK ) == FS_TYPE_PAK ) {
+ // don't search in OS filesystem
+ continue;
+ }
- // check extension
- if( extension && !FS_ExtCmp( extension, name ) ) {
- continue;
- }
-
- // copy filename
- if( count == MAX_LISTED_FILES ) {
- break;
- }
- if( !( flags & FS_SEARCH_SAVEPATH ) ) {
- name = COM_SkipPath( name );
- }
- if( flags & FS_SEARCH_EXTRAINFO ) {
- info.fileSize = search->pack->files[i].filelen;
- listedFiles[count++] = FS_CopyExtraInfo( name, &info );
- } else {
- listedFiles[count++] = FS_CopyString( name );
- }
- }
- }
- } else {
- if( ( flags & FS_TYPE_MASK ) == FS_TYPE_PAK ) {
- // don't search in OS filesystem
- continue;
- }
+ len = strlen( search->filename );
- if( *path ) {
- Q_concat( buffer, sizeof( buffer ), search->filename, "/", path, NULL );
- } else {
- Q_strncpyz( buffer, search->filename, sizeof( buffer ) );
+ if( pathlen ) {
+ if( len + pathlen + 1 >= MAX_OSPATH ) {
+ continue;
}
+ memcpy( buffer, search->filename, len );
+ buffer[len] = '/';
+ memcpy( buffer + len + 1, path, pathlen + 1 );
+ s = buffer;
+ } else {
+ s = search->filename;
+ }
- if( flags & FS_SEARCH_BYFILTER ) {
- dirlist = Sys_ListFiles( buffer, extension, flags|FS_SEARCH_NOSORT, &numFilesInDir );
- } else {
- dirlist = Sys_ListFiles( buffer, extension, flags|FS_SEARCH_NOSORT, &numFilesInDir );
- }
+ if( flags & FS_SEARCH_BYFILTER ) {
+ len += len + pathlen + 1;
+ }
- if( !dirlist ) {
- continue;
- }
+ dirlist = Sys_ListFiles( s, extension,
+ flags|FS_SEARCH_NOSORT, len + 1, &dircount );
+ if( !dirlist ) {
+ continue;
+ }
- for( i = 0; i < numFilesInDir; i++ ) {
- if( count == MAX_LISTED_FILES ) {
- break;
- }
- name = dirlist[i];
- if( ( flags & FS_SEARCH_SAVEPATH ) && !( flags & FS_SEARCH_BYFILTER ) ) {
- // skip search path
- name += strlen( search->filename ) + 1;
- }
- if( flags & FS_SEARCH_EXTRAINFO ) {
- listedFiles[count++] = FS_CopyExtraInfo( name, ( fsFileInfo_t * )( dirlist[i] + strlen( dirlist[i] ) + 1 ) );
- } else {
- listedFiles[count++] = FS_CopyString( name );
- }
- }
- Sys_FreeFileList( dirlist );
-
- }
- if( count == MAX_LISTED_FILES ) {
- break;
- }
- }
- }
+ if( count + dircount > MAX_LISTED_FILES ) {
+ dircount = MAX_LISTED_FILES - count;
+ }
+ for( i = 0; i < dircount; i++ ) {
+ listedFiles[count++] = dirlist[i];
+ }
+
+ Z_Free( dirlist );
+
+ }
+ if( count == MAX_LISTED_FILES ) {
+ break;
+ }
+ }
if( !count ) {
return NULL;
}
- // sort alphabetically (ignoring FS_SEARCH_NOSORT)
- qsort( listedFiles, count, sizeof( listedFiles[0] ), SortStrcmp );
-
- // remove duplicates
- total = 1;
- for( i = 1; i < count; i++ ) {
- // FIXME: use Q_stricmp instead of FS_strcmp here?
- if( !FS_strcmp( listedFiles[ i - 1 ], listedFiles[i] ) ) {
- Z_Free( listedFiles[ i - 1 ] );
- listedFiles[i-1] = NULL;
- } else {
- total++;
- }
- }
+ if( flags & FS_SEARCH_EXTRAINFO ) {
+ // TODO
+ total = count;
+ } else {
+ // sort alphabetically (ignoring FS_SEARCH_NOSORT)
+ qsort( listedFiles, count, sizeof( listedFiles[0] ), SortStrcmp );
+
+ // remove duplicates
+ total = 1;
+ for( i = 1; i < count; i++ ) {
+ // FIXME: use Q_stricmp instead of FS_strcmp here?
+ if( !FS_strcmp( listedFiles[ i - 1 ], listedFiles[i] ) ) {
+ Z_Free( listedFiles[ i - 1 ] );
+ listedFiles[i-1] = NULL;
+ } else {
+ total++;
+ }
+ }
+ }
- list = FS_Malloc( sizeof( char * ) * ( total + 1 ) );
+ list = FS_Malloc( sizeof( void * ) * ( total + 1 ) );
total = 0;
for( i = 0; i < count; i++ ) {
@@ -1956,23 +1909,16 @@ char **FS_ListFiles( const char *path, const char *extension,
}
return list;
-
-
}
/*
=================
-FS_FreeFileList
+FS_FreeList
=================
*/
-void FS_FreeFileList( char **list ) {
- char **p;
+void FS_FreeList( void **list ) {
+ void **p = list;
- if( !list ) {
- Com_Error( ERR_FATAL, "FS_FreeFileList: NULL" );
- }
-
- p = list;
while( *p ) {
Z_Free( *p++ );
}
@@ -2006,7 +1952,7 @@ FS_FDir_f
============
*/
static void FS_FDir_f( void ) {
- char **dirnames;
+ void **list;
int ndirs = 0;
int i;
char *filter;
@@ -2022,15 +1968,14 @@ static void FS_FDir_f( void ) {
if( Cmd_Argc() > 2 ) {
i |= FS_SEARCH_SAVEPATH;
}
-
- if( ( dirnames = FS_ListFiles( NULL, filter, i, &ndirs ) ) != NULL ) {
+
+ if( ( list = FS_ListFiles( NULL, filter, i, &ndirs ) ) != NULL ) {
for( i = 0; i < ndirs; i++ ) {
- Com_Printf( "%s\n", dirnames[i] );
+ Com_Printf( "%s\n", ( char * )list[i] );
}
- FS_FreeFileList( dirnames );
+ FS_FreeList( list );
}
Com_Printf( "%i files listed\n", ndirs );
-
}
/*
@@ -2039,7 +1984,7 @@ FS_Dir_f
============
*/
static void FS_Dir_f( void ) {
- char **dirnames;
+ void **list;
int ndirs = 0;
int i;
char *ext;
@@ -2053,15 +1998,14 @@ static void FS_Dir_f( void ) {
} else {
ext = NULL;
}
- dirnames = FS_ListFiles( Cmd_Argv( 1 ), ext, 0, &ndirs );
- if( dirnames ) {
+ list = FS_ListFiles( Cmd_Argv( 1 ), ext, 0, &ndirs );
+ if( list ) {
for( i = 0; i < ndirs; i++ ) {
- Com_Printf( "%s\n", dirnames[i] );
+ Com_Printf( "%s\n", ( char * )list[i] );
}
- FS_FreeFileList( dirnames );
+ FS_FreeList( list );
}
Com_Printf( "%i files listed\n", ndirs );
-
}
/*
@@ -2116,8 +2060,7 @@ static void FS_WhereIs_f( void ) {
search->filename, "/", path, NULL );
//FS_ConvertToSysPath( fullpath );
if( Sys_GetFileInfo( fullpath, &info ) ) {
- Com_Printf( "%s/%s (%d bytes)\n", search->filename, filename,
- info.fileSize );
+ Com_Printf( "%s/%s (%d bytes)\n", search->filename, filename, info.size );
if( Cmd_Argc() < 3 ) {
return;
}
@@ -2588,7 +2531,9 @@ void FS_FillAPI( fsAPI_t *api ) {
api->Read = FS_Read;
api->Write = FS_Write;
api->ListFiles = FS_ListFiles;
- api->FreeFileList = FS_FreeFileList;
+ api->FreeList = FS_FreeList;
+ api->FPrintf = FS_FPrintf;
+ api->ReadLine = FS_ReadLine;
}
static const cmdreg_t c_fs[] = {