From 2cbfd57208b7e0050bf532456dedae601670af88 Mon Sep 17 00:00:00 2001 From: havoc Date: Thu, 4 Sep 2008 05:51:51 +0000 Subject: [PATCH] split FS_Open into FS_OpenRealFile and FS_OpenVirtualFile (read-only), this allows the savegame menu to only display savegames from the current save directory (not other directories in the virtual filesystem) added b (binary) flag to a few FS_OpenRealFile calls, and removed from a few others (so that logs and QuakeC-written files use OS line endings) git-svn-id: svn://svn.icculus.org/twilight/trunk/darkplaces@8487 d7cf8633-e32d-0410-b094-e92efae38249 --- cl_demo.c | 6 +++--- cl_main.c | 2 +- cl_parse.c | 4 ++-- cl_screen.c | 2 +- console.c | 8 ++++---- dpvsimpledecode.c | 2 +- fs.c | 49 ++++++++++++++++++++++++++++++----------------- fs.h | 5 +++-- gl_rmain.c | 2 +- host.c | 2 +- host_cmd.c | 2 +- jpeg.c | 2 +- libcurl.c | 8 ++++---- menu.c | 2 +- prvm_cmds.c | 15 ++++++++------- sv_demo.c | 2 +- sv_main.c | 2 +- wad.c | 2 +- 18 files changed, 66 insertions(+), 51 deletions(-) diff --git a/cl_demo.c b/cl_demo.c index 5be4e808..5e77cad1 100644 --- a/cl_demo.c +++ b/cl_demo.c @@ -136,7 +136,7 @@ void CL_CutDemo (unsigned char **buf, fs_offset_t *filesize) *buf = FS_LoadFile(cls.demoname, tempmempool, false, filesize); // restart the demo recording - cls.demofile = FS_Open(cls.demoname, "wb", false, false); + cls.demofile = FS_OpenRealFile(cls.demoname, "wb", false); if(!cls.demofile) Host_Error("failed to reopen the demo file"); FS_Printf(cls.demofile, "%i\n", cls.forcetrack); @@ -365,7 +365,7 @@ void CL_Record_f (void) // open the demo file Con_Printf("recording to %s.\n", name); - cls.demofile = FS_Open (name, "wb", false, false); + cls.demofile = FS_OpenRealFile(name, "wb", false); if (!cls.demofile) { Con_Print("ERROR: couldn't open.\n"); @@ -414,7 +414,7 @@ void CL_PlayDemo_f (void) cls.protocol = PROTOCOL_QUAKE; Con_Printf("Playing demo %s.\n", name); - cls.demofile = FS_Open (name, "rb", false, false); + cls.demofile = FS_OpenVirtualFile(name, false); if (!cls.demofile) { Con_Print("ERROR: couldn't open.\n"); diff --git a/cl_main.c b/cl_main.c index 7e8d834b..dbb23b4a 100644 --- a/cl_main.c +++ b/cl_main.c @@ -1992,7 +1992,7 @@ void CL_Locs_Save_f(void) FS_StripExtension(cl.worldmodel->name, locfilename, sizeof(locfilename)); strlcat(locfilename, ".loc", sizeof(locfilename)); - outfile = FS_Open(locfilename, "w", false, false); + outfile = FS_OpenRealFile(locfilename, "w", false); if (!outfile) return; // if any boxes are used then this is a proquake-format loc file, which diff --git a/cl_parse.c b/cl_parse.c index 07ae54f4..d5cb5896 100644 --- a/cl_parse.c +++ b/cl_parse.c @@ -434,7 +434,7 @@ static qboolean QW_CL_CheckOrDownloadFile(const char *filename) qfile_t *file; // see if the file already exists - file = FS_Open(filename, "rb", true, false); + file = FS_OpenVirtualFile(filename, true); if (file) { FS_Close(file); @@ -1640,7 +1640,7 @@ void CL_ParseServerInfo (void) Con_Printf ("Auto-recording to %s.\n", demofile); - cls.demofile = FS_Open (demofile, "wb", false, false); + cls.demofile = FS_OpenRealFile(demofile, "wb", false); if (cls.demofile) { cls.forcetrack = -1; diff --git a/cl_screen.c b/cl_screen.c index 0c055939..702635a2 100644 --- a/cl_screen.c +++ b/cl_screen.c @@ -1270,7 +1270,7 @@ Cr = R * .500 + G * -.419 + B * -.0813 + 128.; //else { cls.capturevideo.format = CAPTUREVIDEOFORMAT_AVI_I420; - cls.capturevideo.videofile = FS_Open (va("%s.avi", cls.capturevideo.basename), "wb", false, true); + cls.capturevideo.videofile = FS_OpenRealFile(va("%s.avi", cls.capturevideo.basename), "wb", false); SCR_CaptureVideo_RIFF_Start(); // enclosing RIFF chunk (there can be multiple of these in >1GB files, the later ones are "AVIX" instead of "AVI " and have no header/stream info) SCR_CaptureVideo_RIFF_Push("RIFF", "AVI "); diff --git a/console.c b/console.c index 07e65de3..feb70bac 100644 --- a/console.c +++ b/console.c @@ -229,7 +229,7 @@ void Log_Open (void) if (logfile != NULL || log_file.string[0] == '\0') return; - logfile = FS_Open (log_file.string, "ab", false, false); + logfile = FS_OpenRealFile(log_file.string, "a", false); if (logfile != NULL) { strlcpy (crt_log_file, log_file.string, sizeof (crt_log_file)); @@ -363,7 +363,7 @@ void Log_Printf (const char *logfilename, const char *fmt, ...) { qfile_t *file; - file = FS_Open (logfilename, "ab", true, false); + file = FS_OpenRealFile(logfilename, "a", true); if (file != NULL) { va_list argptr; @@ -501,7 +501,7 @@ void Con_ConDump_f (void) Con_Printf("usage: condump \n"); return; } - file = FS_Open(Cmd_Argv(1), "wb", false, false); + file = FS_OpenRealFile(Cmd_Argv(1), "w", false); if (!file) { Con_Printf("condump: unable to write file \"%s\"\n", Cmd_Argv(1)); @@ -1639,7 +1639,7 @@ qboolean GetMapList (const char *s, char *completedname, int completednamebuffer char entfilename[MAX_QPATH]; strlcpy(message, "^1**ERROR**^7", sizeof(message)); p = 0; - f = FS_Open(t->filenames[i], "rb", true, false); + f = FS_OpenVirtualFile(t->filenames[i], true); if(f) { memset(buf, 0, 1024); diff --git a/dpvsimpledecode.c b/dpvsimpledecode.c index 6cbc44ea..202cd6a7 100644 --- a/dpvsimpledecode.c +++ b/dpvsimpledecode.c @@ -38,7 +38,7 @@ hz_bitstream_read_t *hz_bitstream_read_open(char *filename) { qfile_t *file; hz_bitstream_read_t *stream; - if ((file = FS_Open (filename, "rb", false, false))) + if ((file = FS_OpenVirtualFile(filename, false))) { stream = (hz_bitstream_read_t *)Z_Malloc(sizeof(hz_bitstream_read_t)); memset(stream, 0, sizeof(*stream)); diff --git a/fs.c b/fs.c index 7a80304d..4d720f36 100644 --- a/fs.c +++ b/fs.c @@ -741,7 +741,7 @@ static packfile_t* FS_AddFileToPack (const char* name, pack_t* pack, ============ FS_CreatePath -Only used for FS_Open. +Only used for FS_OpenRealFile. ============ */ void FS_CreatePath (char *path) @@ -1982,35 +1982,48 @@ MAIN PUBLIC FUNCTIONS /* ==================== -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); } @@ -2491,7 +2504,7 @@ unsigned char *FS_LoadFile (const char *path, mempool_t *pool, qboolean quiet, f 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; @@ -2520,7 +2533,7 @@ qboolean FS_WriteFile (const char *filename, void *data, fs_offset_t len) { 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); diff --git a/fs.h b/fs.h index 8f31b7cc..cf2290fa 100644 --- a/fs.h +++ b/fs.h @@ -53,11 +53,12 @@ extern char fs_gamedirs[MAX_GAMEDIRS][MAX_QPATH]; // ------ Main functions ------ // // IMPORTANT: the file path is automatically prefixed by the current game directory for -// each file created by FS_WriteFile, or opened in "write" or "append" mode by FS_Open +// each file created by FS_WriteFile, or opened in "write" or "append" mode by FS_OpenRealFile qboolean FS_AddPack(const char *pakfile, qboolean *already_loaded, qboolean keep_plain_dirs); // already_loaded may be NULL if caller does not care const char *FS_WhichPack(const char *filename); -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); +qfile_t* FS_OpenVirtualFile (const char* filepath, qboolean quiet); int FS_Close (qfile_t* file); fs_offset_t FS_Write (qfile_t* file, const void* data, size_t datasize); fs_offset_t FS_Read (qfile_t* file, void* buffer, size_t buffersize); diff --git a/gl_rmain.c b/gl_rmain.c index 04b376be..a568885d 100644 --- a/gl_rmain.c +++ b/gl_rmain.c @@ -1392,7 +1392,7 @@ void R_GLSL_DumpShader_f(void) { int i; - qfile_t *file = FS_Open("glsl/default.glsl", "w", false, false); + qfile_t *file = FS_OpenRealFile("glsl/default.glsl", "w", false); if(!file) { Con_Printf("failed to write to glsl/default.glsl\n"); diff --git a/host.c b/host.c index 1e62ec9e..f1b21842 100644 --- a/host.c +++ b/host.c @@ -248,7 +248,7 @@ void Host_SaveConfig_to(const char *file) // LordHavoc: don't save a config if it crashed in startup if (host_framecount >= 3 && cls.state != ca_dedicated && !COM_CheckParm("-benchmark") && !COM_CheckParm("-capturedemo")) { - f = FS_Open (file, "wb", false, false); + f = FS_OpenRealFile(file, "wb", false); if (!f) { Con_Printf("Couldn't write %s.\n", file); diff --git a/host_cmd.c b/host_cmd.c index 1a1b3d8d..9e3228c8 100644 --- a/host_cmd.c +++ b/host_cmd.c @@ -445,7 +445,7 @@ void Host_Savegame_to (const char *name) isserver = !strcmp(PRVM_NAME, "server"); Con_Printf("Saving game to %s...\n", name); - f = FS_Open (name, "wb", false, false); + f = FS_OpenRealFile(name, "wb", false); if (!f) { Con_Print("ERROR: couldn't open.\n"); diff --git a/jpeg.c b/jpeg.c index 6b21c232..49ebfd95 100644 --- a/jpeg.c +++ b/jpeg.c @@ -785,7 +785,7 @@ qboolean JPEG_SaveImage_preflipped (const char *filename, int width, int height, } // Open the file - file = FS_Open (filename, "wb", true, false); + file = FS_OpenRealFile(filename, "wb", true); if (!file) return false; diff --git a/libcurl.c b/libcurl.c index b19229b3..28240a82 100644 --- a/libcurl.c +++ b/libcurl.c @@ -415,7 +415,7 @@ static void Curl_EndDownload(downloadinfo *di, CurlStatus status, CURLcode error // reopen to enforce it to have zero bytes again FS_Close(di->stream); - di->stream = FS_Open(di->filename, "w", false, false); + di->stream = FS_OpenRealFile(di->filename, "wb", false); break; } @@ -478,7 +478,7 @@ static void CheckPendingDownloads() { Con_Printf("Downloading %s -> %s", di->url, di->filename); - di->stream = FS_Open(di->filename, "ab", false, false); + di->stream = FS_OpenRealFile(di->filename, "ab", false); if(!di->stream) { Con_Printf("\nFAILED: Could not open output file %s\n", di->filename); @@ -659,7 +659,7 @@ void Curl_Begin(const char *URL, const char *name, qboolean ispak, qboolean fort } else { - qfile_t *f = FS_Open(fn, "rb", false, false); + qfile_t *f = FS_OpenVirtualFile(fn, false); if(f) { char buf[4] = {0}; @@ -669,7 +669,7 @@ void Curl_Begin(const char *URL, const char *name, qboolean ispak, qboolean fort { Con_DPrintf("Detected non-PAK %s, clearing and NOT resuming.\n", fn); FS_Close(f); - f = FS_Open(fn, "w", false, false); + f = FS_OpenRealFile(fn, "wb", false); if(f) FS_Close(f); } diff --git a/menu.c b/menu.c index 44b17df3..c2a1d5ab 100644 --- a/menu.c +++ b/menu.c @@ -830,7 +830,7 @@ static void M_ScanSaves (void) strlcpy (m_filenames[i], "--- UNUSED SLOT ---", sizeof(m_filenames[i])); loadable[i] = false; dpsnprintf (name, sizeof(name), "s%i.sav", (int)i); - f = FS_Open (name, "rb", false, false); + f = FS_OpenRealFile (name, "rb", false); if (!f) continue; // read enough to get the comment diff --git a/prvm_cmds.c b/prvm_cmds.c index 28a09d92..82cbb3fe 100644 --- a/prvm_cmds.c +++ b/prvm_cmds.c @@ -1585,28 +1585,29 @@ void VM_fopen(void) VM_Warning("VM_fopen: %s ran out of file handles (%i)\n", PRVM_NAME, PRVM_MAX_OPENFILES); return; } + filename = PRVM_G_STRING(OFS_PARM0); mode = (int)PRVM_G_FLOAT(OFS_PARM1); switch(mode) { case 0: // FILE_READ modestring = "rb"; + prog->openfiles[filenum] = FS_OpenVirtualFile(va("data/%s", filename), false); + if (prog->openfiles[filenum] == NULL) + prog->openfiles[filenum] = FS_OpenVirtualFile(va("%s", filename), false); break; case 1: // FILE_APPEND - modestring = "ab"; + modestring = "a"; + prog->openfiles[filenum] = FS_OpenRealFile(va("data/%s", filename), modestring, false); break; case 2: // FILE_WRITE - modestring = "wb"; + modestring = "w"; + prog->openfiles[filenum] = FS_OpenRealFile(va("data/%s", filename), modestring, false); break; default: PRVM_G_FLOAT(OFS_RETURN) = -3; VM_Warning("VM_fopen: %s: no such mode %i (valid: 0 = read, 1 = append, 2 = write)\n", PRVM_NAME, mode); return; } - filename = PRVM_G_STRING(OFS_PARM0); - - prog->openfiles[filenum] = FS_Open(va("data/%s", filename), modestring, false, false); - if (prog->openfiles[filenum] == NULL && mode == 0) - prog->openfiles[filenum] = FS_Open(va("%s", filename), modestring, false, false); if (prog->openfiles[filenum] == NULL) { diff --git a/sv_demo.c b/sv_demo.c index d8f2bea9..c5627470 100644 --- a/sv_demo.c +++ b/sv_demo.c @@ -13,7 +13,7 @@ void SV_StartDemoRecording(client_t *client, const char *filename, int forcetrac Con_Printf("Recording demo for # %d (%s) to %s\n", PRVM_NUM_FOR_EDICT(client->edict), client->netaddress, name); - client->sv_demo_file = FS_Open(name, "wb", false, false); + client->sv_demo_file = FS_OpenRealFile(name, "wb", false); if(!client->sv_demo_file) { Con_Print("ERROR: couldn't open.\n"); diff --git a/sv_main.c b/sv_main.c index 8c8c5cab..bc6de193 100644 --- a/sv_main.c +++ b/sv_main.c @@ -2221,7 +2221,7 @@ static void SV_Download_f(void) } } - host_client->download_file = FS_Open(host_client->download_name, "rb", true, false); + host_client->download_file = FS_OpenVirtualFile(host_client->download_name, true); if (!host_client->download_file) { SV_ClientPrintf("Download rejected: server could not open the file \"%s\"\n", host_client->download_name); diff --git a/wad.c b/wad.c index 25dd95cf..b73717e2 100644 --- a/wad.c +++ b/wad.c @@ -164,7 +164,7 @@ void W_LoadTextureWadFile (char *filename, int complain) int numlumps; mwad_t *w; - file = FS_Open (filename, "rb", false, false); + file = FS_OpenVirtualFile(filename, false); if (!file) { if (complain) -- 2.39.2