work towards a more secure qfs

This commit is contained in:
Bill Currie 2003-02-14 22:36:10 +00:00
parent 68d2167c9e
commit 851d203916
19 changed files with 193 additions and 167 deletions

View file

@ -46,9 +46,16 @@ typedef struct searchpath_s {
typedef struct gamedir_s {
const char *name;
const char *gamedir;
const char *path;
const char *gamecode;
const char *skinpath;
struct {
const char *def;
const char *skins;
const char *progs;
const char *sound;
const char *maps;
} dir;
} gamedir_t;
extern searchpath_t *qfs_searchpaths;
@ -60,9 +67,6 @@ extern struct cvar_s *fs_sharepath;
extern int file_from_pak;
extern int qfs_filesize;
extern char qfs_gamedir_path[MAX_OSPATH];
extern char qfs_gamedir_file[MAX_OSPATH];
struct cache_user_s;
char *QFS_CompressPath (const char *pth);
@ -78,7 +82,8 @@ void QFS_StripExtension (const char *in, char *out);
int QFS_NextFilename (char *filename, const char *prefix, const char *ext);
const char *QFS_FileExtension (const char *in);
QFile *QFS_WOpen (const char *path, int zip);
int QFS_Rename (const char *old, const char *new);
byte *QFS_LoadFile (const char *path, int usehunk);
byte *QFS_LoadStackFile (const char *path, void *buffer, int bufsize);

View file

@ -250,9 +250,10 @@ Condump_f (void)
Con_Printf ("invalid character in filename\n");
return;
}
snprintf (name, sizeof (name), "%s/%s.txt", qfs_gamedir_path, Cmd_Argv (1));
snprintf (name, sizeof (name), "%s/%s.txt", qfs_gamedir->dir.def,
Cmd_Argv (1));
if (!(file = Qopen (name, "wt"))) {
if (!(file = QFS_WOpen (name, 0))) {
Con_Printf ("could not open %s for writing: %s\n", name,
strerror (errno));
return;
@ -452,8 +453,8 @@ C_Print (const char *fmt, va_list args)
// log all messages to file
if (con_debuglog)
Sys_DebugLog (va ("%s/qconsole.log", qfs_gamedir_path),
"%s", buffer->str);
Sys_DebugLog (va ("%s/%s/qconsole.log", fs_userpath->string,
qfs_gamedir->dir.def), "%s", buffer->str);
if (!con_initialized)
return;
@ -809,9 +810,9 @@ C_NewMap (void)
{
static char old_gamedir[MAX_OSPATH];
if (!strequal (old_gamedir, qfs_gamedir_path))
if (!strequal (old_gamedir, qfs_gamedir->gamedir))
Menu_Load ();
strcpy (old_gamedir, qfs_gamedir_path);
strcpy (old_gamedir, qfs_gamedir->gamedir);
}
static general_funcs_t plugin_info_general_funcs = {

View file

@ -54,6 +54,7 @@ int fnmatch (const char *__pattern, const char *__string, int __flags);
#endif
#include "QF/csqc.h"
#include "QF/cvar.h"
#include "QF/progs.h"
#include "QF/quakefs.h"
#include "QF/va.h"
@ -158,7 +159,8 @@ bi_File_Open (progs_t *pr)
goto error;
if (do_write && !file_writeable (path))
goto error;
R_INT (pr) = QFile_open (pr, va ("%s/%s", qfs_gamedir_path, path), mode);
R_INT (pr) = QFile_open (pr, va ("%s/%s/%s", fs_userpath->string,
qfs_gamedir->dir.def, path), mode);
free (path);
return;
error:

View file

@ -605,7 +605,9 @@ GIB_File_Transform_Path_Secure (dstring_t *path)
return -1;
/* Qexpand_squiggle (fs_userpath->string, e_dir); */
dstring_insertstr (path, 0, "/");
dstring_insertstr (path, 0, /* e_dir */ qfs_gamedir_path);
dstring_insertstr (path, 0, /* e_dir */ qfs_gamedir->dir.def);
dstring_insertstr (path, 0, "/");
dstring_insertstr (path, 0, fs_userpath->string);
return 0;
}

View file

@ -431,13 +431,9 @@ Mod_MakeAliasModelDisplayLists (model_t *m, aliashdr_t *hdr, void *_m, int _s, i
if (do_cache) {
// save out the cached version
snprintf (fullpath, sizeof (fullpath), "%s/%s", qfs_gamedir_path,
cache);
f = Qopen (fullpath, "wbz9");
if (!f) {
QFS_CreatePath (fullpath);
f = Qopen (fullpath, "wb");
}
snprintf (fullpath, sizeof (fullpath), "%s/%s",
qfs_gamedir->dir.def, cache);
f = QFS_WOpen (fullpath, 9);
if (f) {
struct mdfour md;

View file

@ -118,9 +118,6 @@ cvar_t *fs_userpath;
cvar_t *fs_sharepath;
cvar_t *fs_dirconf;
char qfs_gamedir_file[MAX_OSPATH];
char qfs_gamedir_path[MAX_OSPATH];
int qfs_filesize;
searchpath_t *qfs_searchpaths;
@ -282,8 +279,14 @@ qfs_get_gd_params (plitem_t *gdpl, gamedir_t *gamedir, dstring_t *path,
}
if (!gamedir->gamecode && (p = PL_ObjectForKey (gdpl, "GameCode")))
gamedir->gamecode = qfs_var_subst (p->data, vars);
if (!gamedir->skinpath && (p = PL_ObjectForKey (gdpl, "SkinPath")))
gamedir->skinpath = qfs_var_subst (p->data, vars);
if (!gamedir->dir.skins && (p = PL_ObjectForKey (gdpl, "SkinPath")))
gamedir->dir.skins = qfs_var_subst (p->data, vars);
if (!gamedir->dir.progs && (p = PL_ObjectForKey (gdpl, "ProgPath")))
gamedir->dir.progs = qfs_var_subst (p->data, vars);
if (!gamedir->dir.sound && (p = PL_ObjectForKey (gdpl, "SoundPath")))
gamedir->dir.sound = qfs_var_subst (p->data, vars);
if (!gamedir->dir.maps && (p = PL_ObjectForKey (gdpl, "MapPath")))
gamedir->dir.maps = qfs_var_subst (p->data, vars);
}
static void
@ -396,12 +399,22 @@ qfs_build_gamedir (const char **list)
if (qfs_gamedir) {
if (qfs_gamedir->name)
free ((char *)qfs_gamedir->name);
if (qfs_gamedir->gamedir)
free ((char *)qfs_gamedir->gamedir);
if (qfs_gamedir->path)
free ((char *)qfs_gamedir->path);
if (qfs_gamedir->gamecode)
free ((char *)qfs_gamedir->gamecode);
if (qfs_gamedir->skinpath)
free ((char *)qfs_gamedir->skinpath);
if (qfs_gamedir->dir.def)
free ((char *)qfs_gamedir->dir.def);
if (qfs_gamedir->dir.skins)
free ((char *)qfs_gamedir->dir.skins);
if (qfs_gamedir->dir.progs)
free ((char *)qfs_gamedir->dir.progs);
if (qfs_gamedir->dir.sound)
free ((char *)qfs_gamedir->dir.sound);
if (qfs_gamedir->dir.maps)
free ((char *)qfs_gamedir->dir.maps);
free (qfs_gamedir);
}
@ -432,18 +445,39 @@ qfs_build_gamedir (const char **list)
continue;
}
Hash_Add (dirs, (void *) name);
if (!j)
if (!j) {
gamedir->name = strdup (name);
gamedir->gamedir = strdup (list[j]);
}
qfs_set_var (vars, "gamedir", dir);
qfs_get_gd_params (gdpl, gamedir, path, vars);
qfs_inherit (qfs_gd_plist, gdpl, gamedir, path, dirs, vars);
}
gamedir->path = path->str;
for (dir = gamedir->path; *dir && *dir != ':'; dir++)
;
gamedir->dir.def = nva ("%.*s", (int) (dir - gamedir->path),
gamedir->path);
if (!gamedir->dir.skins)
gamedir->dir.skins = nva ("%s/skins", gamedir->dir.def);
if (!gamedir->dir.progs)
gamedir->dir.progs = nva ("%s/progs", gamedir->dir.def);
if (!gamedir->dir.sound)
gamedir->dir.sound = nva ("%s/sound", gamedir->dir.def);
if (!gamedir->dir.maps)
gamedir->dir.maps = nva ("%s/maps", gamedir->dir.def);
qfs_gamedir = gamedir;
Sys_DPrintf ("%s\n", qfs_gamedir->name);
Sys_DPrintf (" %s\n", qfs_gamedir->path);
Sys_DPrintf (" %s\n", qfs_gamedir->gamecode);
Sys_DPrintf (" %s\n", qfs_gamedir->skinpath);
Sys_DPrintf (" gamedir : %s\n", qfs_gamedir->gamedir);
Sys_DPrintf (" path : %s\n", qfs_gamedir->path);
Sys_DPrintf (" gamecode: %s\n", qfs_gamedir->gamecode);
Sys_DPrintf (" def : %s\n", qfs_gamedir->dir.def);
Sys_DPrintf (" skins : %s\n", qfs_gamedir->dir.skins);
Sys_DPrintf (" progs : %s\n", qfs_gamedir->dir.progs);
Sys_DPrintf (" sound : %s\n", qfs_gamedir->dir.sound);
Sys_DPrintf (" maps : %s\n", qfs_gamedir->dir.maps);
qfs_process_path (qfs_gamedir->path, dir);
free (path);
Hash_DelTable (dirs);
@ -534,14 +568,11 @@ QFS_WriteFile (const char *filename, void *data, int len)
char name[MAX_OSPATH];
QFile *f;
snprintf (name, sizeof (name), "%s/%s", qfs_gamedir_path, filename);
snprintf (name, sizeof (name), "%s/%s", qfs_gamedir->dir.def, filename);
f = Qopen (name, "wb");
f = QFS_WOpen (name, 0);
if (!f) {
Sys_mkdir (qfs_gamedir_path);
f = Qopen (name, "wb");
if (!f)
Sys_Error ("Error opening %s", filename);
Sys_Error ("Error opening %s", filename);
}
Sys_Printf ("QFS_WriteFile: %s\n", name);
@ -563,14 +594,11 @@ QFS_WriteBuffers (const char *filename, int count, ...)
va_start (args, count);
snprintf (name, sizeof (name), "%s/%s", qfs_gamedir_path, filename);
snprintf (name, sizeof (name), "%s/%s", qfs_gamedir->dir.def, filename);
f = Qopen (name, "wb");
f = QFS_WOpen (name, 0);
if (!f) {
Sys_mkdir (qfs_gamedir_path);
f = Qopen (name, "wb");
if (!f)
Sys_Error ("Error opening %s", filename);
Sys_Error ("Error opening %s", filename);
}
Sys_Printf ("QFS_WriteBuffers: %s\n", name);
@ -1043,27 +1071,18 @@ QFS_LoadGameDirectory (const char *dir)
/*
QFS_AddDirectory
Sets qfs_gamedir_path, adds the directory to the head of the path,
then loads and adds pak1.pak pak2.pak ...
Adds the directory to the head of the path, then loads and adds pak0.pak
pak1.pak ...
*/
static void
QFS_AddDirectory (const char *dir)
{
searchpath_t *search;
char *p;
char e_dir[MAX_OSPATH];
Qexpand_squiggle (dir, e_dir);
dir = e_dir;
if ((p = strrchr (dir, '/')) != NULL) {
strcpy (qfs_gamedir_file, ++p);
strcpy (qfs_gamedir_path, dir);
} else {
strcpy (qfs_gamedir_file, dir);
strcpy (qfs_gamedir_path, va ("%s/%s", fs_userpath->string, dir));
}
// add the directory to the search path
search = calloc (1, sizeof (searchpath_t));
strcpy (search->filename, dir);
@ -1222,10 +1241,43 @@ QFS_NextFilename (char *filename, const char *prefix, const char *ext)
digits[0] = i / 100 + '0';
digits[1] = i / 10 % 10 + '0';
digits[2] = i % 10 + '0';
snprintf (checkname, sizeof (checkname), "%s/%s", qfs_gamedir_path,
snprintf (checkname, sizeof (checkname),
"%s/%s/%s", fs_userpath->string, qfs_gamedir->dir.def,
filename);
if (Sys_FileTime (checkname) == -1)
return 1; // file doesn't exist
}
return 0;
}
QFile *
QFS_WOpen (const char *path, int zip)
{
dstring_t *full_path = dstring_new ();
QFile *file;
char mode[4] = "wb\000\000";
if (zip)
mode[2] = bound (1, zip, 9);
dsprintf (full_path, "%s/%s", fs_userpath->string, path);
QFS_CreatePath (full_path->str);
file = Qopen (full_path->str, mode);
dstring_delete (full_path);
return file;
}
int
QFS_Rename (const char *old, const char *new)
{
dstring_t *full_old = dstring_new ();
dstring_t *full_new = dstring_new ();
int ret;
dsprintf (full_old, "%s/%s", fs_userpath->string, old);
dsprintf (full_new, "%s/%s", fs_userpath->string, new);
QFS_CreatePath (full_new->str);
ret = Qrename (full_old->str, full_new->str);
dstring_delete (full_old);
dstring_delete (full_new);
return ret;
}

View file

@ -243,9 +243,8 @@ VID_SetPalette (unsigned char *palette)
}
d_15to8table[i] = k;
}
snprintf (s, sizeof (s), "%s/glquake/15to8.pal", qfs_gamedir_path);
QFS_CreatePath (s);
if ((f = Qopen (s, "wb")) != NULL) {
snprintf (s, sizeof (s), "%s/glquake/15to8.pal", qfs_gamedir->dir.def);
if ((f = QFS_WOpen (s, 0)) != NULL) {
Qwrite (f, d_15to8table, 1 << 15);
Qclose (f);
}

View file

@ -253,7 +253,7 @@ CL_Record_f (void)
} else
track = -1;
snprintf (name, sizeof (name), "%s/%s", qfs_gamedir_path, Cmd_Argv (1));
snprintf (name, sizeof (name), "%s/%s", qfs_gamedir->dir.def, Cmd_Argv (1));
// start the map up
//
@ -265,13 +265,12 @@ CL_Record_f (void)
#ifdef HAVE_ZLIB
if (demo_gzip->int_val) {
QFS_DefaultExtension (name, ".dem.gz");
cls.demofile = Qopen (name, va ("wbz%d",
bound (1, demo_gzip->int_val, 9)));
cls.demofile = QFS_WOpen (name, demo_gzip->int_val);
} else
#endif
{
QFS_DefaultExtension (name, ".dem");
cls.demofile = Qopen (name, "wb");
cls.demofile = QFS_WOpen (name, 0);
}
if (!cls.demofile) {

View file

@ -285,8 +285,8 @@ Host_WriteConfiguration (void)
// dedicated servers initialize the host but don't parse and set the
// config.cfg cvars
if (host_initialized && !isDedicated && cl_writecfg->int_val) {
char *path = va ("%s/config.cfg", qfs_gamedir_path);
f = Qopen (path, "w");
char *path = va ("%s/config.cfg", qfs_gamedir->dir.def);
f = QFS_WOpen (path, 0);
if (!f) {
Con_Printf ("Couldn't write config.cfg.\n");
return;

View file

@ -465,11 +465,11 @@ Host_Savegame_f (void)
}
}
snprintf (name, sizeof (name), "%s/%s", qfs_gamedir_path, Cmd_Argv (1));
snprintf (name, sizeof (name), "%s/%s", qfs_gamedir->dir.def, Cmd_Argv (1));
QFS_DefaultExtension (name, ".sav");
Con_Printf ("Saving game to %s...\n", name);
f = Qopen (name, "w");
f = QFS_WOpen (name, 0);
if (!f) {
Con_Printf ("ERROR: couldn't open.\n");
return;
@ -528,7 +528,8 @@ Host_Loadgame_f (void)
cls.demonum = -1; // stop demo loop in case this fails
snprintf (name, sizeof (name), "%s/%s", qfs_gamedir_path, Cmd_Argv (1));
snprintf (name, sizeof (name), "%s/%s/%s", fs_userpath->string,
qfs_gamedir->dir.def, Cmd_Argv (1));
QFS_DefaultExtension (name, ".sav");
// we can't call SCR_BeginLoadingPlaque, because too much stack space has

View file

@ -539,23 +539,22 @@ CL_Record (const char *argv1)
if (mapname[k] == '.')
mapname[k] = '\0';
snprintf (name, sizeof (name), "%s/%s-%s", qfs_gamedir_path,
snprintf (name, sizeof (name), "%s/%s-%s", qfs_gamedir->dir.def,
timestring, mapname);
} else {
snprintf (name, sizeof (name), "%s/%s", qfs_gamedir_path, argv1);
snprintf (name, sizeof (name), "%s/%s", qfs_gamedir->dir.def, argv1);
}
// open the demo file
#ifdef HAVE_ZLIB
if (demo_gzip->int_val) {
QFS_DefaultExtension (name, ".qwd.gz");
cls.demofile = Qopen (name, va ("wbz%d",
bound (1, demo_gzip->int_val, 9)));
cls.demofile = QFS_WOpen (name, demo_gzip->int_val);
} else
#endif
{
QFS_DefaultExtension (name, ".qwd");
cls.demofile = Qopen (name, "wb");
cls.demofile = QFS_WOpen (name, 0);
}
if (!cls.demofile) {
Con_Printf ("ERROR: couldn't open.\n");
@ -577,7 +576,7 @@ CL_Record (const char *argv1)
MSG_WriteByte (&buf, svc_serverdata);
MSG_WriteLong (&buf, PROTOCOL_VERSION);
MSG_WriteLong (&buf, cl.servercount);
MSG_WriteString (&buf, qfs_gamedir_file);
MSG_WriteString (&buf, qfs_gamedir->gamedir);
if (cl.spectator)
MSG_WriteByte (&buf, cl.playernum | 128);
@ -844,12 +843,12 @@ CL_ReRecord_f (void)
if (cls.demorecording)
CL_Stop_f ();
snprintf (name, sizeof (name), "%s/%s", qfs_gamedir_path, Cmd_Argv (1));
snprintf (name, sizeof (name), "%s/%s", qfs_gamedir->dir.def, Cmd_Argv (1));
// open the demo file
QFS_DefaultExtension (name, ".qwd");
cls.demofile = Qopen (name, "wb");
cls.demofile = QFS_WOpen (name, 0);
if (!cls.demofile) {
Con_Printf ("ERROR: couldn't open.\n");
return;

View file

@ -1072,13 +1072,11 @@ CL_Download_f (void)
}
snprintf (cls.downloadname, sizeof (cls.downloadname), "%s/%s",
qfs_gamedir_path, Cmd_Argv (1));
QFS_CreatePath (cls.downloadname);
qfs_gamedir->dir.def, Cmd_Argv (1));
strncpy (cls.downloadtempname, cls.downloadname,
sizeof (cls.downloadtempname));
cls.download = Qopen (cls.downloadname, "wb");
cls.download = QFS_WOpen (cls.downloadname, 0);
if (cls.download) {
cls.downloadtype = dl_single;
@ -1413,10 +1411,9 @@ Host_WriteConfiguration (void)
QFile *f;
if (host_initialized && cl_writecfg->int_val) {
char *path = va ("%s/config.cfg", qfs_gamedir_path);
char *path = va ("%s/config.cfg", qfs_gamedir->dir.def);
QFS_CreatePath (path);
f = Qopen (path, "w");
f = QFS_WOpen (path, 0);
if (!f) {
Con_Printf ("Couldn't write config.cfg.\n");
return;

View file

@ -324,7 +324,7 @@ Model_NextDownload (void)
"downloaded.\n\n", cl.model_name[i]);
Con_Printf ("You may need to download or purchase a %s client "
"pack in order to play on this server.\n\n",
qfs_gamedir_file);
qfs_gamedir->gamedir);
CL_Disconnect ();
return;
}
@ -489,18 +489,14 @@ CL_ParseDownload (void)
}
// open the file if not opened yet
if (!cls.download) {
if (!qfs_gamedir->skinpath
|| !*qfs_gamedir->skinpath
|| strncmp (cls.downloadtempname, "skins/", 6))
snprintf (name, sizeof (name), "%s/%s", qfs_gamedir_path,
if (strncmp (cls.downloadtempname, "skins/", 6))
snprintf (name, sizeof (name), "%s/%s", qfs_gamedir->dir.def,
cls.downloadtempname);
else
snprintf (name, sizeof (name), "%s/%s/%s", fs_userpath->string,
qfs_gamedir->skinpath, cls.downloadtempname);
snprintf (name, sizeof (name), "%s/%s", qfs_gamedir->dir.skins,
cls.downloadtempname + 6);
QFS_CreatePath (name);
cls.download = Qopen (name, "wb");
cls.download = QFS_WOpen (name, 0);
if (!cls.download) {
cls.downloadname[0] = 0;
net_message->readcount += size;
@ -532,20 +528,18 @@ CL_ParseDownload (void)
// rename the temp file to it's final name
if (strcmp (cls.downloadtempname, cls.downloadname)) {
if (!qfs_gamedir->skinpath
|| !*qfs_gamedir->skinpath
|| strncmp (cls.downloadtempname, "skins/", 6)) {
snprintf (oldn, sizeof (oldn), "%s/%s", qfs_gamedir_path,
if (strncmp (cls.downloadtempname, "skins/", 6)) {
snprintf (oldn, sizeof (oldn), "%s/%s", qfs_gamedir->dir.def,
cls.downloadtempname);
snprintf (newn, sizeof (newn), "%s/%s", qfs_gamedir_path,
snprintf (newn, sizeof (newn), "%s/%s", qfs_gamedir->dir.def,
cls.downloadname);
} else {
snprintf (oldn, sizeof (oldn), "%s/%s/%s", fs_userpath->string,
qfs_gamedir->skinpath, cls.downloadtempname);
snprintf (newn, sizeof (newn), "%s/%s/%s", fs_userpath->string,
qfs_gamedir->skinpath, cls.downloadname);
snprintf (oldn, sizeof (oldn), "%s/%s", qfs_gamedir->dir.skins,
cls.downloadtempname + 6);
snprintf (newn, sizeof (newn), "%s/%s", qfs_gamedir->dir.skins,
cls.downloadname + 6);
}
r = Qrename (oldn, newn);
r = QFS_Rename (oldn, newn);
if (r)
Con_Printf ("failed to rename, %s.\n", strerror (errno));
}
@ -679,7 +673,7 @@ CL_ParseServerData (void)
// game directory
str = MSG_ReadString (net_message);
if (!strequal (qfs_gamedir_file, str)) {
if (!strequal (qfs_gamedir->gamedir, str)) {
// save current config
Host_WriteConfiguration ();
cflag = true;

View file

@ -46,9 +46,11 @@ static __attribute__ ((unused)) const char rcsid[] =
#include <sys/stat.h>
#include "QF/console.h"
#include "QF/dstring.h"
#include "QF/sys.h"
#include "QF/cvar.h"
#include "QF/quakefs.h"
#include "QF/va.h"
#include "QF/zone.h"
#include "compat.h"
@ -136,30 +138,22 @@ CF_GetFileSize (const char *path)
static void
CF_BuildQuota (void)
{
char *file, *path;
static dstring_t *path;
struct dirent *i;
DIR *dir;
path = Hunk_TempAlloc (strlen (qfs_gamedir_path) + 1 + strlen (CF_DIR) + 256 +
1);
if (!path)
return;
path = dstring_new ();
dsprintf (path, "%s/%s/%s", fs_userpath->string, qfs_gamedir->dir.def, CF_DIR);
strcpy(path, qfs_gamedir_path);
strcpy(path + strlen(path), "/");
strcpy(path + strlen(path), CF_DIR);
dir = opendir (path);
dir = opendir (path->str);
if (!dir)
return;
file = path + strlen(path);
cf_cursize = 0;
while ((i = readdir(dir))) {
strcpy (file, i->d_name);
cf_cursize += CF_GetFileSize (path);
cf_cursize += CF_GetFileSize (va ("%s/%s", path->str, i->d_name));
}
closedir (dir);
}
@ -207,7 +201,8 @@ CF_CloseAllFiles ()
int
CF_Open (const char *path, const char *mode)
{
char *fullpath, *j;
char *j;
dstring_t *fullpath = dstring_new ();
int desc, oldsize, i;
QFile *file;
@ -232,31 +227,25 @@ CF_Open (const char *path, const char *mode)
return -1;
}
fullpath = malloc(strlen(qfs_gamedir_path) + 1 + strlen(CF_DIR)
+ strlen(path) + 1);
if (!fullpath) {
return -1;
}
dsprintf (fullpath, "%s/%s/%s/%s", fs_userpath->string,
qfs_gamedir->dir.def, CF_DIR, path);
strcpy(fullpath, qfs_gamedir_path);
strcpy(fullpath + strlen(fullpath), "/");
strcpy(fullpath + strlen(fullpath), CF_DIR);
j = fullpath + strlen(fullpath);
j = fullpath->str + strlen(fullpath->str) - strlen (path);
for (i = 0; path[i]; i++, j++) // strcpy, but force lowercase
*j = tolower(path[i]);
*j = '\0';
if (CF_AlreadyOpen(fullpath, mode[0])) {
free (fullpath);
if (CF_AlreadyOpen(fullpath->str, mode[0])) {
dstring_delete (fullpath);
return -1;
}
if (mode[0] == 'w')
oldsize = CF_GetFileSize (fullpath);
oldsize = CF_GetFileSize (fullpath->str);
else
oldsize = 0;
file = Qopen (fullpath, mode);
file = Qopen (fullpath->str, mode);
if (file) {
if (cf_openfiles >= cf_filepcount) {
cf_filepcount++;
@ -269,7 +258,7 @@ CF_Open (const char *path, const char *mode)
for (desc = 0; cf_filep[desc].file; desc++)
;
cf_filep[desc].path = fullpath;
cf_filep[desc].path = fullpath->str;
cf_filep[desc].file = file;
cf_filep[desc].buf = 0;
cf_filep[desc].size = 0;

View file

@ -59,7 +59,7 @@ SV_Gamedir_f (void)
const char *dir;
if (Cmd_Argc () == 1) {
Con_Printf ("Current gamedir: %s\n", qfs_gamedir_file);
Con_Printf ("Current gamedir: %s\n", qfs_gamedir->gamedir);
return;
}

View file

@ -200,7 +200,6 @@ static void
SV_Fraglogfile_f (void)
{
char name[MAX_OSPATH];
int i;
if (sv_fraglogfile) {
SV_Printf ("Frag file logging off.\n");
@ -208,19 +207,7 @@ SV_Fraglogfile_f (void)
sv_fraglogfile = NULL;
return;
}
// find an unused name
for (i = 0; i < 1000; i++) {
snprintf (name, sizeof (name), "%s/frag_%i.log", qfs_gamedir_path, i);
sv_fraglogfile = Qopen (name, "r");
if (!sv_fraglogfile) { // can't read it, so create this one
sv_fraglogfile = Qopen (name, "w");
if (!sv_fraglogfile)
i = 1000; // give error
break;
}
Qclose (sv_fraglogfile);
}
if (i == 1000) {
if (!QFS_NextFilename (name, "frag_", ".log")) {
SV_Printf ("Can't open any logfiles.\n");
sv_fraglogfile = NULL;
return;
@ -1070,14 +1057,15 @@ SV_Snap (int uid)
snprintf (pcxname, sizeof (pcxname), "%d-00.pcx", uid);
snprintf (checkname, sizeof (checkname), "%s/snap", qfs_gamedir_path);
snprintf (checkname, sizeof (checkname), "%s/%s/snap", fs_userpath->string,
qfs_gamedir->dir.def);
QFS_CreatePath (va ("%s/dummy", checkname));
for (i = 0; i <= 99; i++) {
pcxname[strlen (pcxname) - 6] = i / 10 + '0';
pcxname[strlen (pcxname) - 5] = i % 10 + '0';
snprintf (checkname, sizeof (checkname), "%s/snap/%s",
qfs_gamedir_path, pcxname);
snprintf (checkname, sizeof (checkname), "%s/%s/snap/%s",
fs_userpath->string, qfs_gamedir->dir.def, pcxname);
if (Sys_FileTime (checkname) == -1)
break; // file doesn't exist
}

View file

@ -593,7 +593,7 @@ SV_Stop (int reason)
if (demo.disk)
Qclose (demo.file);
sprintf (path, "%s/%s/%s", qfs_gamedir_path, demo.path->str, demo.name->str);
sprintf (path, "%s/%s/%s/%s", fs_userpath->string, qfs_gamedir->dir.def, demo.path->str, demo.name->str);
unlink (path);
strcpy (path + strlen (path) - 3, "txt");
@ -1102,7 +1102,7 @@ SV_Record_f (void)
if (sv.demorecording)
SV_Stop_f ();
dsprintf (name, "%s/%s/%s%s%s", qfs_gamedir_path, sv_demoDir->string,
dsprintf (name, "%s/%s/%s/%s%s%s", fs_userpath->string, qfs_gamedir->dir.def, sv_demoDir->string,
sv_demoPrefix->string, SV_CleanName (Cmd_Argv (1)),
sv_demoSuffix->string);
@ -1223,7 +1223,7 @@ SV_EasyRecord_f (void)
}
// Make sure the filename doesn't contain illegal characters
dsprintf (name2, "%s/%s/%s%s%s", qfs_gamedir_path, sv_demoDir->string,
dsprintf (name2, "%s/%s/%s/%s%s%s", fs_userpath->string, qfs_gamedir->dir.def, sv_demoDir->string,
sv_demoPrefix->string, SV_CleanName (name->str),
sv_demoSuffix->string);
QFS_CreatePath (name2->str);
@ -1266,8 +1266,8 @@ SV_DemoList_f (void)
dir_t dir;
file_t *list;
Con_Printf ("content of %s/%s/ *.mvd\n", qfs_gamedir_path, sv_demoDir->string);
dir = Sys_listdir (va ("%s/%s", qfs_gamedir_path, sv_demoDir->string), ".mvd");
Con_Printf ("content of %s/%s/%s/ *.mvd\n", fs_userpath->string, qfs_gamedir->dir.def, sv_demoDir->string);
dir = Sys_listdir (va ("%s/%s/%s", fs_userpath->string, qfs_gamedir->dir.def, sv_demoDir->string), ".mvd");
list = dir.files;
if (!list->name[0]) {
Con_Printf ("no demos\n");
@ -1307,7 +1307,7 @@ SV_DemoNum (int num)
file_t *list;
dir_t dir;
dir = Sys_listdir (va ("%s/%s", qfs_gamedir_path, sv_demoDir->string), ".mvd");
dir = Sys_listdir (va ("%s/%s/%s", fs_userpath->string, qfs_gamedir->dir.def, sv_demoDir->string), ".mvd");
list = dir.files;
if (num <= 0)
@ -1376,7 +1376,7 @@ SV_DemoRemove_f (void)
ptr++;
dir =
Sys_listdir (va ("%s/%s", qfs_gamedir_path, sv_demoDir->string), ".mvd");
Sys_listdir (va ("%s/%s/%s", fs_userpath->string, qfs_gamedir->dir.def, sv_demoDir->string), ".mvd");
list = dir.files;
for (i = 0; list->name[0]; list++) {
if (strstr (list->name, ptr)) {
@ -1384,7 +1384,7 @@ SV_DemoRemove_f (void)
SV_Stop_f ();
// stop recording first;
sprintf (path, "%s/%s/%s", qfs_gamedir_path, sv_demoDir->string,
sprintf (path, "%s/%s/%s/%s", fs_userpath->string, qfs_gamedir->dir.def, sv_demoDir->string,
list->name);
if (!unlink (path)) {
Con_Printf ("removing %s...\n", list->name);
@ -1407,7 +1407,7 @@ SV_DemoRemove_f (void)
dsprintf (name, "%s", Cmd_Argv (1));
QFS_DefaultExtension (name->str, ".mvd");
sprintf (path, "%s/%s/%s", qfs_gamedir_path, sv_demoDir->string, name->str);
sprintf (path, "%s/%s/%s/%s", fs_userpath->string, qfs_gamedir->dir.def, sv_demoDir->string, name->str);
if (sv.demorecording && !strcmp (name->str, demo.name->str))
SV_Stop_f ();
@ -1459,7 +1459,7 @@ SV_DemoRemoveNum_f (void)
if (sv.demorecording && !strcmp (name, demo.name->str))
SV_Stop_f ();
sprintf (path, "%s/%s/%s", qfs_gamedir_path, sv_demoDir->string, name);
sprintf (path, "%s/%s/%s/%s", fs_userpath->string, qfs_gamedir->dir.def, sv_demoDir->string, name);
if (!unlink (path)) {
Con_Printf ("demo %s succesfully removed\n", name);
/*
@ -1504,7 +1504,7 @@ SV_DemoInfoAdd_f (void)
return;
}
sprintf (path, "%s/%s/%s", qfs_gamedir_path, demo.path->str,
sprintf (path, "%s/%s/%s/%s", fs_userpath->string, qfs_gamedir->dir.def, demo.path->str,
SV_DemoName2Txt (demo.name->str));
} else {
name = SV_DemoTxTNum (atoi (Cmd_Argv (1)));
@ -1514,7 +1514,7 @@ SV_DemoInfoAdd_f (void)
return;
}
sprintf (path, "%s/%s/%s", qfs_gamedir_path, sv_demoDir->string, name);
sprintf (path, "%s/%s/%s/%s", fs_userpath->string, qfs_gamedir->dir.def, sv_demoDir->string, name);
}
if ((f = Qopen (path, "a+t")) == NULL) {
@ -1551,7 +1551,7 @@ SV_DemoInfoRemove_f (void)
return;
}
sprintf (path, "%s/%s/%s", qfs_gamedir_path, demo.path->str,
sprintf (path, "%s/%s/%s/%s", fs_userpath->string, qfs_gamedir->dir.def, demo.path->str,
SV_DemoName2Txt (demo.name->str));
} else {
name = SV_DemoTxTNum (atoi (Cmd_Argv (1)));
@ -1561,7 +1561,7 @@ SV_DemoInfoRemove_f (void)
return;
}
sprintf (path, "%s/%s/%s", qfs_gamedir_path, sv_demoDir->string, name);
sprintf (path, "%s/%s/%s/%s", fs_userpath->string, qfs_gamedir->dir.def, sv_demoDir->string, name);
}
if (unlink (path))
@ -1589,7 +1589,7 @@ SV_DemoInfo_f (void)
return;
}
sprintf (path, "%s/%s/%s", qfs_gamedir_path, demo.path->str,
sprintf (path, "%s/%s/%s/%s", fs_userpath->string, qfs_gamedir->dir.def, demo.path->str,
SV_DemoName2Txt (demo.name->str));
} else {
name = SV_DemoTxTNum (atoi (Cmd_Argv (1)));
@ -1599,7 +1599,7 @@ SV_DemoInfo_f (void)
return;
}
sprintf (path, "%s/%s/%s", qfs_gamedir_path, sv_demoDir->string, name);
sprintf (path, "%s/%s/%s/%s", fs_userpath->string, qfs_gamedir->dir.def, sv_demoDir->string, name);
}
if ((f = Qopen (path, "rt")) == NULL) {

View file

@ -1536,7 +1536,8 @@ SV_WriteIP_f (void)
QFile *f;
const char *type;
snprintf (name, sizeof (name), "%s/listip.cfg", qfs_gamedir_path);
snprintf (name, sizeof (name), "%s/%s/listip.cfg", fs_userpath->string,
qfs_gamedir->dir.def);
SV_Printf ("Writing IP Filters to %s.\n", name);

View file

@ -353,7 +353,8 @@ locs_loc (void)
if (!mapname)
Sys_Error ("Can't duplicate mapname!");
map_to_loc (cl.worldmodel->name,mapname);
snprintf (locfile, sizeof (locfile), "%s/%s", qfs_gamedir_path, mapname);
snprintf (locfile, sizeof (locfile), "%s/%s/%s", fs_userpath->string,
qfs_gamedir->dir.def, mapname);
free(mapname);
if (strcasecmp (Cmd_Argv(1),"save") == 0) {