typedef struct pack_s
{
char filename [MAX_OSPATH];
+ char shortname [MAX_QPATH];
int handle;
int ignorecase; // PK3 ignores case
int numfiles;
// Load the central directory in memory
central_dir = (unsigned char *)Mem_Alloc (tempmempool, eocd->cdir_size);
lseek (pack->handle, eocd->cdir_offset, SEEK_SET);
- read (pack->handle, central_dir, eocd->cdir_size);
+ if(read (pack->handle, central_dir, eocd->cdir_size) != (ssize_t) eocd->cdir_size)
+ {
+ Mem_Free (central_dir);
+ return -1;
+ }
// Extract the files properties
// The parsing is done "by hand" because some fields have variable sizes and
============
FS_CreatePath
-Only used for FS_Open.
+Only used for FS_OpenRealFile.
============
*/
void FS_CreatePath (char *path)
#endif
if (packhandle < 0)
return NULL;
- read (packhandle, (void *)&header, sizeof(header));
+ if(read (packhandle, (void *)&header, sizeof(header)) != sizeof(header))
+ {
+ Con_Printf ("%s is not a packfile\n", packfile);
+ close(packhandle);
+ return NULL;
+ }
if (memcmp(header.id, "PACK", 4))
{
Con_Printf ("%s is not a packfile\n", packfile);
plain directories.
================
*/
-static qboolean FS_AddPack_Fullpath(const char *pakfile, qboolean *already_loaded, qboolean keep_plain_dirs)
+static qboolean FS_AddPack_Fullpath(const char *pakfile, const char *shortname, qboolean *already_loaded, qboolean keep_plain_dirs)
{
searchpath_t *search;
pack_t *pak = NULL;
if (pak)
{
+ strlcpy(pak->shortname, shortname, sizeof(pak->shortname));
+ //Con_DPrintf(" Registered pack with short name %s\n", shortname);
if(keep_plain_dirs)
{
// find the first item whose next one is a pack or NULL
dpsnprintf(fullpath, sizeof(fullpath), "%s%s", search->filename, pakfile);
- return FS_AddPack_Fullpath(fullpath, already_loaded, keep_plain_dirs);
+ return FS_AddPack_Fullpath(fullpath, pakfile, already_loaded, keep_plain_dirs);
}
{
if (!strcasecmp(FS_FileExtension(list.strings[i]), "pak"))
{
- FS_AddPack_Fullpath(list.strings[i], NULL, false);
+ FS_AddPack_Fullpath(list.strings[i], list.strings[i] + strlen(dir), NULL, false);
}
}
{
if (!strcasecmp(FS_FileExtension(list.strings[i]), "pk3"))
{
- FS_AddPack_Fullpath(list.strings[i], NULL, false);
+ FS_AddPack_Fullpath(list.strings[i], list.strings[i] + strlen(dir), NULL, false);
}
}
/*
====================
-FS_Open
+FS_OpenRealFile
-Open a file. The syntax is the same as fopen
+Open a file in the userpath. The syntax is the same as fopen
+Used for savegame scanning in menu, and all file writing.
====================
*/
-qfile_t* FS_Open (const char* filepath, const char* mode, qboolean quiet, qboolean nonblocking)
+qfile_t* FS_OpenRealFile (const char* filepath, const char* mode, qboolean quiet)
{
+ char real_path [MAX_OSPATH];
+
if (FS_CheckNastyPath(filepath, false))
{
- Con_Printf("FS_Open(\"%s\", \"%s\", %s): nasty filename rejected\n", filepath, mode, quiet ? "true" : "false");
+ Con_Printf("FS_OpenRealFile(\"%s\", \"%s\", %s): nasty filename rejected\n", filepath, mode, quiet ? "true" : "false");
return NULL;
}
- // If the file is opened in "write", "append", or "read/write" mode
+ dpsnprintf (real_path, sizeof (real_path), "%s/%s", fs_gamedir, filepath);
+
+ // If the file is opened in "write", "append", or "read/write" mode,
+ // create directories up to the file.
if (mode[0] == 'w' || mode[0] == 'a' || strchr (mode, '+'))
- {
- char real_path [MAX_OSPATH];
+ FS_CreatePath (real_path);
+ return FS_SysOpen (real_path, mode, false);
+}
- // Open the file on disk directly
- dpsnprintf (real_path, sizeof (real_path), "%s/%s", fs_gamedir, filepath);
- // Create directories up to the file
- FS_CreatePath (real_path);
+/*
+====================
+FS_OpenVirtualFile
- return FS_SysOpen (real_path, mode, nonblocking);
+Open a file. The syntax is the same as fopen
+====================
+*/
+qfile_t* FS_OpenVirtualFile (const char* filepath, qboolean quiet)
+{
+ if (FS_CheckNastyPath(filepath, false))
+ {
+ Con_Printf("FS_OpenVirtualFile(\"%s\", %s): nasty filename rejected\n", filepath, quiet ? "true" : "false");
+ return NULL;
}
- // Else, we look at the various search paths and open the file in read-only mode
- else
- return FS_OpenReadFile (filepath, quiet, nonblocking, 16);
+
+ return FS_OpenReadFile (filepath, quiet, false, 16);
}
unsigned char *buf = NULL;
fs_offset_t filesize = 0;
- file = FS_Open (path, "rb", quiet, false);
+ file = FS_OpenVirtualFile(path, quiet);
if (file)
{
filesize = file->real_length;
{
qfile_t *file;
- file = FS_Open (filename, "wb", false, false);
+ file = FS_OpenRealFile(filename, "wb", false);
if (!file)
{
Con_Printf("FS_WriteFile: failed on %s\n", filename);
int index;
searchpath_t *sp = FS_FindFile(filename, &index, true);
if(sp && sp->pack)
- return sp->pack->filename;
+ return sp->pack->shortname;
else
return 0;
}