UFO: Alien Invasion
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
files.cpp File Reference

All of UFO's data access is through a hierarchical file system, but the contents of the file system can be transparently merged from several sources. The "base directory" is the path to the directory holding the ufo binary and the game directory (base). The base directory is only used during filesystem initialization. The "game directory" is the first tree on the search path and directory that all generated files (savegames, screenshots, config files) will be saved to. More...

#include "common.h"
#include "qfiles.h"
#include "unzip.h"
#include "../ports/system.h"
#include "../shared/defines.h"
#include "../shared/parse.h"
#include <unistd.h>

Go to the source code of this file.

Data Structures

struct  listBlock_s
 

Macros

#define MODS_DIR   "mods"
 
#define PK3_SEEK_BUFFER_SIZE   65536
 
#define MAX_READ   0x10000 /* read in blocks of 64k */
 
#define MAX_PACKFILES   1024
 

Typedefs

typedef struct listBlock_s listBlock_t
 

Functions

void FS_CreateOpenPipeFile (const char *filename, qFILE *f)
 
const char * FS_Gamedir (void)
 Called to find where to write a file (savegames, etc) More...
 
void FS_NormPath (char *path)
 Convert operating systems path separators to ufo virtual filesystem separators (/) More...
 
int FS_FileLength (qFILE *f)
 Returns the size of a given file or -1 if no file is opened. More...
 
void FS_CreatePath (const char *path)
 Creates any directories needed to store the given filename. More...
 
void FS_CloseFile (qFILE *f)
 Closes a file handle. More...
 
int FS_OpenFile (const char *filename, qFILE *file, filemode_t mode)
 Finds and opens the file in the search path. More...
 
int FS_Seek (qFILE *f, long offset, int origin)
 Sets the file position of the given file. More...
 
int FS_CheckFile (const char *fmt,...)
 Just returns the filelength and -1 if the file wasn't found. More...
 
int FS_Read2 (void *buffer, int len, qFILE *f, bool failOnEmptyRead)
 Read a file into a given buffer in memory. More...
 
int FS_Read (void *buffer, int len, qFILE *f)
 
int FS_LoadFile (const char *path, byte **buffer)
 Filenames are relative to the quake search path. More...
 
void FS_FreeFile (void *buffer)
 
static pack_tFS_LoadPackFile (const char *packfile)
 Takes an explicit (not game tree related) path to a pak file. Adding the files at the beginning of the list so they override previous pack files. More...
 
void FS_AddGameDirectory (const char *dir, bool write)
 Adds the directory to the head of the search path. More...
 
char ** FS_ListFiles (const char *findname, int *numfiles, unsigned musthave, unsigned canthave)
 Builds a qsorted filelist. More...
 
const char * FS_NextPath (const char *prevpath)
 Allows enumerating all of the directories in the search path. More...
 
static bool FS_GetHomeDirectory (char *gdir, size_t length)
 
void FS_AddHomeAsGameDirectory (const char *dir, bool write)
 
int FS_GetModList (linkedList_t **mods)
 Searches and builds a list of mod directories. More...
 
void FS_InitFilesystem (bool writeToHomeDir)
 
static void _AddToListBlock (linkedList_t **fl, const char *name, bool stripPath)
 Add one name to the filelist. More...
 
int FS_BuildFileList (const char *fileList)
 Build a filelist. More...
 
const char * FS_NextFileFromFileList (const char *files)
 Returns the next file that is found in the virtual filesystem identified by the given file pattern. More...
 
const char * FS_GetFileData (const char *files)
 Returns the buffer of a file. More...
 
char * FS_NextScriptHeader (const char *files, const char **name, const char **text)
 
static int FS_MapDefSort (const void *map1, const void *map2)
 
static int CheckBSPFile (const char *filename)
 Checks for valid BSP-file. More...
 
void FS_GetMaps (bool reset)
 File the fs_maps array with valid maps. More...
 
int FS_Printf (qFILE *f, const char *msg,...)
 Can print chunks for 1024 chars into a file. More...
 
int FS_Write (const void *buffer, int len, qFILE *f)
 Properly handles partial writes. More...
 
int FS_WriteFile (const void *buffer, size_t len, const char *filename)
 
const char * FS_GetCwd (void)
 Return current working dir. More...
 
bool FS_FileExists (const char *filename,...)
 Checks whether a file exists (not in virtual filesystem) More...
 
void FS_Shutdown (void)
 Cleanup function. More...
 
void FS_RestartFilesystem (const char *gamedir)
 Restart the filesystem (reload all pk3 files) More...
 
void FS_CopyFile (const char *fromOSPath, const char *toOSPath)
 Copy a fully specified file from one place to another. More...
 
void FS_RemoveFile (const char *osPath)
 
bool FS_RenameFile (const char *from, const char *to, bool relative)
 Renames a file. More...
 

Variables

static int fs_openedFiles
 
static filelink_tfs_links
 
static searchpath_tfs_searchpaths
 
static char const *const pakFileExt []
 
static listBlock_tfs_blocklist = nullptr
 
char * fs_maps [MAX_MAPS]
 
int fs_numInstalledMaps = -1
 
static bool fs_mapsInstalledInit = false
 

Detailed Description

All of UFO's data access is through a hierarchical file system, but the contents of the file system can be transparently merged from several sources. The "base directory" is the path to the directory holding the ufo binary and the game directory (base). The base directory is only used during filesystem initialization. The "game directory" is the first tree on the search path and directory that all generated files (savegames, screenshots, config files) will be saved to.

Definition in file files.cpp.

Macro Definition Documentation

#define MAX_PACKFILES   1024

Definition at line 483 of file files.cpp.

Referenced by FS_AddGameDirectory().

#define MAX_READ   0x10000 /* read in blocks of 64k */

Definition at line 311 of file files.cpp.

Referenced by FS_Read2().

#define MODS_DIR   "mods"

Definition at line 45 of file files.cpp.

Referenced by FS_GetModList(), and FS_InitFilesystem().

#define PK3_SEEK_BUFFER_SIZE   65536

Definition at line 238 of file files.cpp.

Referenced by FS_Seek().

Typedef Documentation

typedef struct listBlock_s listBlock_t
Todo:
This block list code is broken in terms of filename order To see the bug reduce the FL_BLOCKSIZE to 1024 and verify the order of the filenames FS_NextScriptHeader gives you - you will see that the last files will be in reversed order

Function Documentation

static void _AddToListBlock ( linkedList_t **  fl,
const char *  name,
bool  stripPath 
)
static

Add one name to the filelist.

Note
also checks for duplicates
See also
FS_BuildFileList

Definition at line 939 of file files.cpp.

References Com_SkipPath(), f, LIST_AddStringSorted(), LIST_ContainsString(), and name.

Referenced by FS_BuildFileList().

static int CheckBSPFile ( const char *  filename)
static

Checks for valid BSP-file.

Parameters
[in]filenameBSP-file to check
Returns
0 if valid
1 could not open file
2 if magic number is bad
3 if version of bsp-file is bad

Definition at line 1342 of file files.cpp.

References BSPVERSION, Com_sprintf(), FILE_READ, FS_OpenFile(), FS_Read(), i, IDBSPHEADER, LittleLong, and MAX_QPATH.

Referenced by FS_GetMaps().

void FS_AddGameDirectory ( const char *  dir,
bool  write 
)

Adds the directory to the head of the search path.

Note
No ending slash here
Parameters
[in]dirThe directory name relative to the game dir
[in]writeAdd this directory as writable (config files, save games)

Definition at line 495 of file files.cpp.

References com_fileSysPool, Com_Printf(), Com_sprintf(), searchpath_s::filename, FS_ListFiles(), FS_LoadPackFile(), fs_searchpaths, i, MAX_OSPATH, MAX_PACKFILES, Mem_Free, Mem_PoolAllocType, searchpath_s::next, searchpath_s::pack, pakFileExt, Q_streq, Q_StringSort(), Q_strncpyz(), SFF_HIDDEN, SFF_SUBDIR, SFF_SYSTEM, and searchpath_s::write.

Referenced by FS_AddHomeAsGameDirectory(), FS_InitFilesystem(), main(), and TEST_Init().

void FS_AddHomeAsGameDirectory ( const char *  dir,
bool  write 
)
Note
e.g. *nix: Use ~/.ufoai/dir as gamedir
Parameters
[in]dirThe directory name relative to the game dir
[in]writeAdd this directory as writable (config files, save games)
See also
Sys_GetHomeDirectory

Definition at line 655 of file files.cpp.

References FS_AddGameDirectory(), FS_CreatePath(), FS_GetHomeDirectory(), MAX_OSPATH, Q_strcat(), and va().

Referenced by FS_InitFilesystem(), and TEST_Init().

void FS_CloseFile ( qFILE f)

Closes a file handle.

See also
FS_OpenFile

Definition at line 137 of file files.cpp.

References cgi, qFILE_s::f, fs_openedFiles, unzCloseCurrentFile(), and qFILE_s::z.

Referenced by ScopedFile::~ScopedFile().

void FS_CopyFile ( const char *  fromOSPath,
const char *  toOSPath 
)

Copy a fully specified file from one place to another.

Todo:
Allow copy of pk3 file content

Definition at line 1652 of file files.cpp.

References com_fileSysPool, Com_Printf(), f, FILE, FS_CreatePath(), len, Mem_Free, Mem_PoolAllocTypeN, SEEK_END, SEEK_SET, Sys_Error(), and Sys_Fopen().

void FS_CreateOpenPipeFile ( const char *  filename,
qFILE f 
)
void FS_CreatePath ( const char *  path)

Creates any directories needed to store the given filename.

See also
Sys_Mkdir
Note
Paths should already be normalized
See also
FS_NormPath

Definition at line 117 of file files.cpp.

References MAX_OSPATH, Q_strncpyz(), and Sys_Mkdir().

Referenced by CL_StartHTTPDownload(), FS_AddHomeAsGameDirectory(), FS_CopyFile(), and FS_OpenFile().

bool FS_FileExists ( const char *  filename,
  ... 
)

Checks whether a file exists (not in virtual filesystem)

See also
FS_CheckFile
Parameters
[in]filenameFull filesystem path to the file

Definition at line 1581 of file files.cpp.

References MAX_OSPATH, Q_vsnprintf(), and Sys_Access().

Referenced by CL_LanguageTest(), FS_InitFilesystem(), GAME_TeamSlotComments_f(), TEST_F(), and WEB_CGameUpload().

int FS_FileLength ( qFILE f)

Returns the size of a given file or -1 if no file is opened.

Definition at line 91 of file files.cpp.

References qFILE_s::f, qFILE_s::name, SEEK_END, SEEK_SET, Sys_Error(), unz_file_info_s::uncompressed_size, UNZ_OK, unzGetCurrentFileInfo(), and qFILE_s::z.

Referenced by ASE_Load(), FS_OpenFile(), FS_WriteFile(), and GAME_LoadTeam().

const char* FS_Gamedir ( void  )
const char* FS_GetCwd ( void  )

Return current working dir.

Definition at line 1568 of file files.cpp.

References FS_NormPath(), MAX_OSPATH, Q_strncpyz(), and Sys_Cwd().

Referenced by CL_Init(), and CL_LanguageTest().

const char* FS_GetFileData ( const char *  files)

Returns the buffer of a file.

Parameters
[in]filesIf nullptr, reset the filelist If not nullptr it may be something like *.cfg to get a list of all config files in base/. Calling FS_GetFileData("*.cfg"); until it returns nullptr is sufficient to get one buffer after another.
Note
You don't have to free the file buffer on the calling side. This is done in this function, too

Definition at line 1135 of file files.cpp.

References Com_Printf(), linkedList_t::data, listBlock_s::files, FS_BuildFileList(), FS_FreeFile(), FS_LoadFile(), MAX_QPATH, linkedList_t::next, listBlock_s::next, listBlock_s::path, Q_streq, and Q_strncpyz().

Referenced by Com_GetScriptChecksum().

static bool FS_GetHomeDirectory ( char *  gdir,
size_t  length 
)
static

Definition at line 631 of file files.cpp.

References Com_Printf(), Com_sprintf(), Sys_GetHomeDirectory(), and UFO_VERSION.

Referenced by FS_AddHomeAsGameDirectory(), and FS_GetModList().

void FS_GetMaps ( bool  reset)

File the fs_maps array with valid maps.

Parameters
[in]resetIf true the directory is scanned every time for new maps (useful for dedicated servers). If false we only use the maps array (for clients e.g.)
Todo:
paths are normalized here?

Definition at line 1373 of file files.cpp.

References CheckBSPFile(), com_fileSysPool, Com_Printf(), Com_SkipPath(), Com_sprintf(), Com_StripExtension(), pack_s::files, FS_ListFiles(), FS_MapDefSort(), FS_NormPath(), fs_numInstalledMaps, i, MAX_MAPS, MAX_OSPATH, MAX_QPATH, Mem_Free, Mem_PoolAllocTypeN, packfile_t::name, searchpath_s::next, pack_s::numfiles, Q_strncpyz(), SFF_HIDDEN, and SFF_SYSTEM.

Referenced by SV_CompleteMapCommand(), and SV_ListMaps_f().

int FS_GetModList ( linkedList_t **  mods)

Searches and builds a list of mod directories.

Definition at line 669 of file files.cpp.

References BASEDIRNAME, FS_GetHomeDirectory(), FS_ListFiles(), i, LIST_AddString(), MAX_OSPATH, Mem_Free, MODS_DIR, PKGDATADIR, Q_strcat(), SFF_HIDDEN, SFF_SUBDIR, SFF_SYSTEM, and va().

Referenced by CLMN_Mods_f().

char** FS_ListFiles ( const char *  findname,
int numfiles,
unsigned  musthave,
unsigned  canthave 
)

Builds a qsorted filelist.

See also
Sys_FindFirst
Sys_FindNext
Sys_FindClose
Note
Don't forget to free the filelist array and the file itself

Definition at line 562 of file files.cpp.

References com_fileSysPool, i, MAX_FILES, MAX_OSPATH, Mem_PoolAllocTypeN, Mem_PoolStrDup, OBJZERO, Q_StringSort(), Q_strlwr(), Q_strncpyz(), Sys_FindClose(), Sys_FindFirst(), and Sys_FindNext().

Referenced by FS_AddGameDirectory(), FS_BuildFileList(), FS_GetMaps(), and FS_GetModList().

static pack_t* FS_LoadPackFile ( const char *  packfile)
static

Takes an explicit (not game tree related) path to a pak file. Adding the files at the beginning of the list so they override previous pack files.

Parameters
[in]packfileThe pack filename
Note
pk3 and zip are valid extensions

Definition at line 422 of file files.cpp.

References com_fileSysPool, Com_GetExtension(), Com_Printf(), unz_file_info_s::compressed_size, qFILE_s::f, packfile_t::filelen, pack_s::filename, pack_s::files, gi, pack_s::handle, i, MAX_QPATH, Mem_PoolAllocType, Mem_PoolAllocTypeN, name, unz_global_info_s::number_entry, pack_s::numfiles, Q_streq, Q_StringSort(), Q_strlwr(), Q_strncpyz(), UNZ_OK, unzGetCurrentFileInfo(), unzGetCurrentFileInfoPosition(), unzGetGlobalInfo(), unzGoToFirstFile(), unzGoToNextFile(), unzOpen(), and qFILE_s::z.

Referenced by FS_AddGameDirectory().

static int FS_MapDefSort ( const void map1,
const void map2 
)
static
See also
Com_MapDefSort

Definition at line 1318 of file files.cpp.

References Q_StringSort().

Referenced by FS_GetMaps().

const char* FS_NextFileFromFileList ( const char *  files)

Returns the next file that is found in the virtual filesystem identified by the given file pattern.

Parameters
[in]filesThe file pattern to search for. This can e.g. be "*.ogg" or "**.ufo" to also include subdirectories.
Returns
The next found filename or NULL if the end of the list was reached.
Note
Keep in mind that the list is cached and also the position in the list is not reset until you explicitly want this by calling this function with a NULL parameter for the pattern.
If you have to rebuild a file list, use FS_BuildFileList manually. Following calls will then use the new file list.

Definition at line 1079 of file files.cpp.

References Com_Printf(), linkedList_t::data, listBlock_s::files, FS_BuildFileList(), MAX_QPATH, linkedList_t::next, listBlock_s::next, and listBlock_s::path.

Referenced by Cmd_CompleteExecCommand(), GAME_GetImportData(), GAME_GetTeamFileName(), GAME_TeamSlotComments_f(), M_CompleteMusic(), M_RandomTrack_f(), MD2Visitor(), PrecalcNormalsAndTangentsBatch(), S_CompleteSounds(), and TEST_F().

const char* FS_NextPath ( const char *  prevpath)

Allows enumerating all of the directories in the search path.

Note
ignore pk3 here

Definition at line 614 of file files.cpp.

References FS_Gamedir(), searchpath_s::next, and Q_streq.

Referenced by GAME_GetCGameAPI(), and SV_GetGameAPI().

char* FS_NextScriptHeader ( const char *  files,
const char **  name,
const char **  text 
)
void FS_NormPath ( char *  path)

Convert operating systems path separators to ufo virtual filesystem separators (/)

See also
Sys_NormPath

Definition at line 83 of file files.cpp.

References Sys_NormPath().

Referenced by FS_BuildFileList(), FS_GetCwd(), FS_GetMaps(), main(), and U2M_Parameter().

int FS_OpenFile ( const char *  filename,
qFILE file,
filemode_t  mode 
)

Finds and opens the file in the search path.

Parameters
[in]filename
[out]fileThe file pointer
[in]moderead, write, append as an enum
Returns
the filesize or -1 in case of an error
Note
Used for streaming data out of either a pak file or a separate file.

Definition at line 162 of file files.cpp.

References Com_Printf(), Com_sprintf(), qFILE_s::f, FILE_APPEND, FILE_WRITE, packfile_t::filelen, pack_s::filename, qFILE_s::filepos, pack_s::files, FS_CreatePath(), FS_FileLength(), FS_Gamedir(), fs_openedFiles, FS_OpenFile(), pack_s::handle, i, length, MAX_OSPATH, qFILE_s::name, packfile_t::name, filelink_s::next, searchpath_s::next, pack_s::numfiles, Q_strcasecmp, Q_strncpyz(), Sys_Error(), Sys_Fopen(), unz_file_info_s::uncompressed_size, UNZ_OK, unzGetCurrentFileInfo(), unzGetCurrentFileInfoPosition(), unzLocateFile(), unzOpenCurrentFile(), and qFILE_s::z.

Referenced by ASE_Load(), CheckBSPFile(), CIN_OGM_OpenCinematic(), CIN_ROQ_OpenCinematic(), CL_LogEvent(), Com_MD5File(), Com_SHA1File(), Com_SHA2File(), Com_vPrintf(), Com_WriteConfigToFile(), Con_LoadConsoleHistory(), Con_SaveConsoleHistory(), FS_CheckFile(), FS_LoadFile(), FS_OpenFile(), FS_WriteFile(), GAME_GetImportData(), GAME_LoadTeam(), GAME_TeamSlotComments_f(), GenerateFootstepList(), GenerateMaterialFile(), Key_WriteBindings(), MD2SkinEdit(), MD2SkinNum(), R_ScreenShot(), RT_WriteCSVFiles(), SL_CreatePNGFile(), UI_EditorNodeExtract_f(), WEB_CGameDownloadFromUser(), WriteBSPFile(), WriteMapFile(), WriteTGA24(), and WriteToFile().

int FS_Printf ( qFILE f,
const char *  msg,
  ... 
)

Can print chunks for 1024 chars into a file.

Note
The file must already be opened and may not be a zip file handle

Definition at line 1495 of file files.cpp.

References qFILE_s::f, len, and Q_vsnprintf().

Referenced by CL_LogEvent(), Cmd_WriteAliases(), Com_WriteConfigToFile(), Cvar_WriteVariables(), GenerateFootstepList(), GenerateMaterialFile(), Key_WriteBindings(), RT_WriteCSVFiles(), UI_EditorNodeExtractNode(), WriteMapBrush(), WriteMapEntities(), and WriteMapFile().

int FS_Read2 ( void buffer,
int  len,
qFILE f,
bool  failOnEmptyRead 
)

Read a file into a given buffer in memory.

Parameters
[out]bufferPointer to memory where file contents are written to.
[in]lenThe length of the supplied memory area.
[in]fThe file which is to be read into the memory area.
[in]failOnEmptyReadidk Must have something to with certain readstates that can happen with removable media ?
Returns
The length of the file contents successfully read and written to memory.
Note
buffer is not null-terminated at the end of file reading
This function properly handles partial reads so check that the returned length matches len.
Reads in blocks of 64k.
See also
FS_LoadFile
FS_OpenFile

Definition at line 327 of file files.cpp.

References qFILE_s::f, len, MAX_READ, Sys_Error(), unzReadCurrentFile(), and qFILE_s::z.

Referenced by Com_ReadFromPipe(), and FS_Read().

void FS_RemoveFile ( const char *  osPath)
bool FS_RenameFile ( const char *  from,
const char *  to,
bool  relative 
)

Renames a file.

See also
FS_RemoveFile
FS_CopyFile
Parameters
[in]fromThe source filename
[in]toThe filename we want after the rename
[in]relativeIf relative is true we have to add the FS_Gamedir path for writing

Definition at line 1707 of file files.cpp.

References Com_sprintf(), FS_Gamedir(), MAX_OSPATH, Sys_Error(), and Sys_Rename().

Referenced by CL_FinishHTTPDownload().

void FS_RestartFilesystem ( const char *  gamedir)

Restart the filesystem (reload all pk3 files)

Note
Call this after you finished a download
See also
FS_Shutdown
FS_InitFilesystem

Definition at line 1641 of file files.cpp.

References Com_Printf().

Referenced by CL_FinishHTTPDownload().

int FS_Seek ( qFILE f,
long  offset,
int  origin 
)

Sets the file position of the given file.

Parameters
[in]fThe opened file handle
[in]originfsOrigin_t
[in]offsetThe offset you want to do the
See also
FS_Read

Definition at line 246 of file files.cpp.

References qFILE_s::f, qFILE_s::filepos, FS_Read(), FS_SEEK_CUR, FS_SEEK_END, FS_SEEK_SET, PK3_SEEK_BUFFER_SIZE, SEEK_CUR, SEEK_END, SEEK_SET, Sys_Error(), unzOpenCurrentFile(), unzSetCurrentFileInfoPosition(), and qFILE_s::z.

void FS_Shutdown ( void  )

Cleanup function.

cleanup function

See also
FS_InitFilesystem
FS_RestartFilesystem

Definition at line 1602 of file files.cpp.

References com_fileSysPool, Com_Printf(), fs_openedFiles, Mem_Free, Mem_FreePool, searchpath_s::next, listBlock_s::next, and unzClose().

Referenced by Qcommon_Shutdown(), and TEST_Shutdown().

int FS_Write ( const void buffer,
int  len,
qFILE f 
)

Properly handles partial writes.

Definition at line 1511 of file files.cpp.

References Com_Printf(), qFILE_s::f, and len.

Referenced by AddLump(), Com_vPrintf(), Con_SaveConsoleHistory(), FS_WriteFile(), MD2SkinEdit(), MD2SkinNum(), R_WriteCompressedTGA(), WriteBSPFile(), WriteTGA24(), and WriteToFile().

int FS_WriteFile ( const void buffer,
size_t  len,
const char *  filename 
)

Variable Documentation

listBlock_t* fs_blocklist = nullptr
static

Definition at line 932 of file files.cpp.

Referenced by FS_BuildFileList().

filelink_t* fs_links
static

Definition at line 43 of file files.cpp.

char* fs_maps[MAX_MAPS]

Definition at line 1311 of file files.cpp.

Referenced by SV_CompleteMapCommand(), and SV_ListMaps_f().

bool fs_mapsInstalledInit = false
static

Definition at line 1313 of file files.cpp.

int fs_numInstalledMaps = -1

Definition at line 1312 of file files.cpp.

Referenced by FS_GetMaps(), SV_CompleteMapCommand(), and SV_ListMaps_f().

int fs_openedFiles
static

counter for opened files - used to check against missing close calls

Definition at line 42 of file files.cpp.

Referenced by FS_CloseFile(), FS_CreateOpenPipeFile(), FS_OpenFile(), and FS_Shutdown().

searchpath_t* fs_searchpaths
static

Definition at line 44 of file files.cpp.

Referenced by FS_AddGameDirectory().

char const* const pakFileExt[]
static
Initial value:
= {
"pk3", "zip", nullptr
}

Definition at line 485 of file files.cpp.

Referenced by FS_AddGameDirectory().