mirror of
https://github.com/ZDoom/gzdoom.git
synced 2024-11-25 21:41:03 +00:00
- sanitization of temporary file stuff for Timidity++.
* do not use the global temp directory. Instead create one in the AppData folder. * removed lots of unneeded code from tmpfileplus. * use C++ strings in there.
This commit is contained in:
parent
f6f17fbfb4
commit
7cbcbe66c0
7 changed files with 105 additions and 83 deletions
|
@ -53,6 +53,7 @@ FString M_ZLibError(int zerrnum);
|
|||
#ifdef __unix__
|
||||
FString GetUserFile (const char *path); // Prepends ~/.zdoom to path
|
||||
#endif
|
||||
FString M_GetAppDataPath(bool create);
|
||||
FString M_GetCachePath(bool create);
|
||||
FString M_GetAutoexecPath();
|
||||
FString M_GetCajunPath(const char *filename);
|
||||
|
|
|
@ -39,6 +39,35 @@
|
|||
#include "m_misc.h"
|
||||
#include "version.h" // for GAMENAME
|
||||
|
||||
//===========================================================================
|
||||
//
|
||||
// M_GetAppDataPath macOS
|
||||
//
|
||||
// Returns the path for the AppData folder.
|
||||
//
|
||||
//===========================================================================
|
||||
|
||||
FString M_GetAppDataPath(bool create)
|
||||
{
|
||||
FString path;
|
||||
|
||||
char pathstr[PATH_MAX];
|
||||
FSRef folder;
|
||||
|
||||
if (noErr == FSFindFolder(kUserDomain, kApplicationSupportFolderType, create ? kCreateFolder : 0, &folder) &&
|
||||
noErr == FSRefMakePath(&folder, (UInt8*)pathstr, PATH_MAX))
|
||||
{
|
||||
path = pathstr;
|
||||
}
|
||||
else
|
||||
{
|
||||
path = progdir;
|
||||
}
|
||||
path += "/" GAMENAMELOWERCASE;
|
||||
if (create) CreatePath(path);
|
||||
return path;
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
//
|
||||
// M_GetCachePath macOS
|
||||
|
@ -64,6 +93,7 @@ FString M_GetCachePath(bool create)
|
|||
path = progdir;
|
||||
}
|
||||
path += "/zdoom/cache";
|
||||
if (create) CreatePath(path);
|
||||
return path;
|
||||
}
|
||||
|
||||
|
|
|
@ -98,6 +98,26 @@ FString GetUserFile (const char *file)
|
|||
return path;
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
//
|
||||
// M_GetAppDataPath Unix
|
||||
//
|
||||
// Returns the path for the AppData folder.
|
||||
//
|
||||
//===========================================================================
|
||||
|
||||
FString M_GetAppDataPath(bool create)
|
||||
{
|
||||
// Don't use GAME_DIR and such so that ZDoom and its child ports can
|
||||
// share the node cache.
|
||||
FString path = NicePath("~/.config/" GAMENAMELOWERCASE);
|
||||
if (create)
|
||||
{
|
||||
CreatePath(path);
|
||||
}
|
||||
return path;
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
//
|
||||
// M_GetCachePath Unix
|
||||
|
|
|
@ -43,6 +43,7 @@
|
|||
#include "templates.h"
|
||||
#include "version.h"
|
||||
#include "tmpfileplus.h"
|
||||
#include "m_misc.h"
|
||||
|
||||
#ifndef _WIN32
|
||||
#include <unistd.h>
|
||||
|
@ -82,7 +83,7 @@ public:
|
|||
protected:
|
||||
bool LaunchTimidity();
|
||||
|
||||
char* DiskName;
|
||||
FString DiskName;
|
||||
#ifdef _WIN32
|
||||
HANDLE ReadWavePipe;
|
||||
HANDLE WriteWavePipe;
|
||||
|
@ -165,8 +166,7 @@ CUSTOM_CVAR (Int, timidity_frequency, 44100, CVAR_ARCHIVE|CVAR_GLOBALCONFIG)
|
|||
//
|
||||
//==========================================================================
|
||||
|
||||
TimidityPPMIDIDevice::TimidityPPMIDIDevice(const char *args)
|
||||
: DiskName(nullptr),
|
||||
TimidityPPMIDIDevice::TimidityPPMIDIDevice(const char *args) :
|
||||
#ifdef _WIN32
|
||||
ReadWavePipe(INVALID_HANDLE_VALUE), WriteWavePipe(INVALID_HANDLE_VALUE),
|
||||
ChildProcess(INVALID_HANDLE_VALUE),
|
||||
|
@ -204,10 +204,9 @@ TimidityPPMIDIDevice::TimidityPPMIDIDevice(const char *args)
|
|||
|
||||
TimidityPPMIDIDevice::~TimidityPPMIDIDevice ()
|
||||
{
|
||||
if (nullptr != DiskName)
|
||||
if (DiskName.IsNotEmpty())
|
||||
{
|
||||
remove(DiskName);
|
||||
free(DiskName);
|
||||
}
|
||||
|
||||
#if _WIN32
|
||||
|
@ -257,7 +256,10 @@ bool TimidityPPMIDIDevice::Preprocess(MIDIStreamer *song, bool looping)
|
|||
// Write MIDI song to temporary file
|
||||
song->CreateSMF(midi, looping ? 0 : 1);
|
||||
|
||||
f = tmpfileplus(nullptr, "zmid", &DiskName, 1);
|
||||
FString path = M_GetAppDataPath(false);
|
||||
path += "/tmp";
|
||||
CreatePath(path);
|
||||
f = tmpfileplus(path, "zmid", &DiskName, 1);
|
||||
if (f == NULL)
|
||||
{
|
||||
Printf(PRINT_BOLD, "Could not open temp music file\n");
|
||||
|
@ -454,7 +456,7 @@ bool TimidityPPMIDIDevice::ValidateTimidity()
|
|||
|
||||
bool TimidityPPMIDIDevice::LaunchTimidity ()
|
||||
{
|
||||
if (ExeName.IsEmpty() || nullptr == DiskName)
|
||||
if (ExeName.IsEmpty() || DiskName.IsEmpty())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
@ -565,7 +567,7 @@ bool TimidityPPMIDIDevice::LaunchTimidity ()
|
|||
arglist.push_back("-");
|
||||
arglist.push_back(outmodearg.c_str());
|
||||
arglist.push_back(ifacearg.c_str());
|
||||
arglist.push_back(DiskName);
|
||||
arglist.push_back(DiskName.GetChars());
|
||||
|
||||
DPrintf(DMSG_NOTIFY, "Timidity EXE: \x1cG%s\n", exename);
|
||||
int i = 1;
|
||||
|
|
|
@ -97,10 +97,9 @@
|
|||
|
||||
#include "m_random.h"
|
||||
#include "cmdlib.h"
|
||||
#include "zstring.h"
|
||||
|
||||
|
||||
#define FILE_SEPARATOR "/"
|
||||
|
||||
#define RANDCHARS "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"
|
||||
#define NRANDCHARS (sizeof(RANDCHARS) - 1)
|
||||
|
||||
|
@ -121,27 +120,13 @@ static char *set_randpart(char *s)
|
|||
return s;
|
||||
}
|
||||
|
||||
/** Call getenv and save a copy in buf */
|
||||
static char *getenv_save(const char *varname, char *buf, size_t bufsize)
|
||||
{
|
||||
char *ptr = getenv(varname);
|
||||
buf[0] = '\0';
|
||||
if (ptr)
|
||||
{
|
||||
strncpy(buf, ptr, bufsize);
|
||||
buf[bufsize-1] = '\0';
|
||||
return buf;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* Try and create a randomly-named file in directory `tmpdir`.
|
||||
* If successful, allocate memory and set `tmpname_ptr` to full filepath, and return file pointer;
|
||||
* otherwise return NULL.
|
||||
* If `keep` is zero then create the file as temporary and it should not exist once closed.
|
||||
*/
|
||||
static FILE *mktempfile_internal(const char *tmpdir, const char *pfx, char **tmpname_ptr, int keep)
|
||||
static FILE *mktempfile_internal(const char *tmpdir, const char *pfx, FString *tmpname_ptr, int keep)
|
||||
/* PRE:
|
||||
* pfx is not NULL and points to a valid null-terminated string
|
||||
* tmpname_ptr is not NULL.
|
||||
|
@ -150,9 +135,7 @@ static FILE *mktempfile_internal(const char *tmpdir, const char *pfx, char **tmp
|
|||
FILE *fp;
|
||||
int fd;
|
||||
char randpart[] = "1234567890";
|
||||
size_t lentempname;
|
||||
int i;
|
||||
char *tmpname = NULL;
|
||||
int oflag, pmode;
|
||||
|
||||
/* In Windows, we use the _O_TEMPORARY flag with `open` to ensure the file is deleted when closed.
|
||||
|
@ -176,18 +159,13 @@ static FILE *mktempfile_internal(const char *tmpdir, const char *pfx, char **tmp
|
|||
return NULL;
|
||||
}
|
||||
|
||||
lentempname = strlen(tmpdir) + strlen(FILE_SEPARATOR) + strlen(pfx) + strlen(randpart);
|
||||
tmpname = (char*)malloc(lentempname + 1);
|
||||
if (!tmpname)
|
||||
{
|
||||
errno = ENOMEM;
|
||||
return NULL;
|
||||
}
|
||||
FString tempname;
|
||||
|
||||
/* If we don't manage to create a file after 10 goes, there is something wrong... */
|
||||
for (i = 0; i < 10; i++)
|
||||
{
|
||||
sprintf(tmpname, "%s%s%s%s", tmpdir, FILE_SEPARATOR, pfx, set_randpart(randpart));
|
||||
fd = OPEN_(tmpname, oflag, pmode);
|
||||
tempname.Format("%s/%s%s", tmpdir, pfx, set_randpart(randpart));
|
||||
fd = OPEN_(tempname, oflag, pmode);
|
||||
if (fd != -1) break;
|
||||
}
|
||||
if (fd != -1)
|
||||
|
@ -205,13 +183,8 @@ static FILE *mktempfile_internal(const char *tmpdir, const char *pfx, char **tmp
|
|||
{ /* We failed */
|
||||
fp = NULL;
|
||||
}
|
||||
if (!fp)
|
||||
{
|
||||
free(tmpname);
|
||||
tmpname = NULL;
|
||||
}
|
||||
|
||||
*tmpname_ptr = tmpname;
|
||||
if (tmpname_ptr) *tmpname_ptr = tempname;
|
||||
return fp;
|
||||
}
|
||||
|
||||
|
@ -219,47 +192,10 @@ static FILE *mktempfile_internal(const char *tmpdir, const char *pfx, char **tmp
|
|||
/* EXPORTED FUNCTIONS */
|
||||
/**********************/
|
||||
|
||||
FILE *tmpfileplus(const char *dir, const char *prefix, char **pathname, int keep)
|
||||
FILE *tmpfileplus(const char *dir, const char *prefix, FString *pathname, int keep)
|
||||
{
|
||||
FILE *fp = NULL;
|
||||
char *tmpname = NULL;
|
||||
char *tmpdir = NULL;
|
||||
const char *pfx = (prefix ? prefix : "tmp.");
|
||||
char *tempdirs[12] = { 0 };
|
||||
char env1[FILENAME_MAX+1] = { 0 };
|
||||
char env2[FILENAME_MAX+1] = { 0 };
|
||||
char env3[FILENAME_MAX+1] = { 0 };
|
||||
int ntempdirs = 0;
|
||||
int i;
|
||||
|
||||
/* Set up a list of temp directories we will try in order */
|
||||
i = 0;
|
||||
tempdirs[i++] = (char *)dir;
|
||||
#ifdef _WIN32
|
||||
tempdirs[i++] = getenv_save("TMP", env1, sizeof(env1));
|
||||
tempdirs[i++] = getenv_save("TEMP", env2, sizeof(env2));
|
||||
#else
|
||||
tempdirs[i++] = getenv_save("TMPDIR", env3, sizeof(env3));
|
||||
tempdirs[i++] = P_tmpdir;
|
||||
#endif
|
||||
tempdirs[i++] = ".";
|
||||
ntempdirs = i;
|
||||
|
||||
errno = 0;
|
||||
|
||||
/* Work through list we set up before, and break once we are successful */
|
||||
for (i = 0; i < ntempdirs; i++)
|
||||
{
|
||||
tmpdir = tempdirs[i];
|
||||
fp = mktempfile_internal(tmpdir, pfx, &tmpname, keep);
|
||||
if (fp) break;
|
||||
}
|
||||
/* If we succeeded and the user passed a pointer, set it to the alloc'd pathname: the user must free this */
|
||||
if (fp && pathname)
|
||||
*pathname = tmpname;
|
||||
else /* Otherwise, free the alloc'd memory */
|
||||
free(tmpname);
|
||||
|
||||
FILE *fp = mktempfile_internal(dir, (prefix ? prefix : "tmp."), pathname, keep);
|
||||
if (!fp && pathname) *pathname = "";
|
||||
return fp;
|
||||
}
|
||||
|
||||
|
|
|
@ -23,6 +23,8 @@
|
|||
|
||||
#include <stdio.h>
|
||||
|
||||
class FString;
|
||||
|
||||
/** Create a unique temporary file.
|
||||
@param dir (optional) directory to create file. If NULL use default TMP directory.
|
||||
@param prefix (optional) prefix for file name. If NULL use "tmp.".
|
||||
|
@ -33,7 +35,7 @@
|
|||
@return Pointer to stream opened in binary read/write (w+b) mode, or a null pointer on error.
|
||||
@exception ENOMEM Not enough memory to allocate filename.
|
||||
*/
|
||||
FILE *tmpfileplus(const char *dir, const char *prefix, char **pathname, int keep);
|
||||
FILE *tmpfileplus(const char *dir, const char *prefix, FString *pathname, int keep);
|
||||
|
||||
|
||||
#define TMPFILE_KEEP 1
|
||||
|
|
|
@ -153,6 +153,33 @@ bool GetKnownFolder(int shell_folder, REFKNOWNFOLDERID known_folder, bool create
|
|||
}
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
//
|
||||
// M_GetAppDataPath Windows
|
||||
//
|
||||
// Returns the path for the AppData folder.
|
||||
//
|
||||
//===========================================================================
|
||||
|
||||
FString M_GetAppDataPath(bool create)
|
||||
{
|
||||
FString path;
|
||||
|
||||
if (!GetKnownFolder(CSIDL_LOCAL_APPDATA, FOLDERID_LocalAppData, create, path))
|
||||
{ // Failed (e.g. On Win9x): use program directory
|
||||
path = progdir;
|
||||
}
|
||||
// Don't use GAME_DIR and such so that ZDoom and its child ports can
|
||||
// share the node cache.
|
||||
path += "/" GAMENAMELOWERCASE;
|
||||
path.Substitute("//", "/"); // needed because progdir ends with a slash.
|
||||
if (create)
|
||||
{
|
||||
CreatePath(path);
|
||||
}
|
||||
return path;
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
//
|
||||
// M_GetCachePath Windows
|
||||
|
@ -173,6 +200,10 @@ FString M_GetCachePath(bool create)
|
|||
// share the node cache.
|
||||
path += "/zdoom/cache";
|
||||
path.Substitute("//", "/"); // needed because progdir ends with a slash.
|
||||
if (create)
|
||||
{
|
||||
CreatePath(path);
|
||||
}
|
||||
return path;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue