1
0
forked from 0ad/0ad

fixed current directory problem. added healthy does of paranoia to file_rel_chdir, and removed bogus chdir from main.cpp (from test code)

This was SVN commit r238.
This commit is contained in:
janwas 2004-05-17 13:23:39 +00:00
parent b709de582d
commit 556afb4a5c
6 changed files with 122 additions and 261 deletions

View File

@ -96,49 +96,67 @@ static int mk_native_path(const char* const path, char* const n_path)
}
// rationale for data dir being root: untrusted scripts must not be allowed
// to overwrite critical game (or worse, OS) files. the VFS prevents any
// accesses to files above this directory.
int file_set_root_dir(const char* argv0, const char* root_dir)
// set current directory to rel_path, relative to the path to the executable,
// which is taken from argv0.
//
// example: executable in "$install_dir/system"; desired root dir is
// "$install_dir/data" => rel_path = "../data".
//
// this is necessary because the current directory is unknown at startup
// (e.g. it isn't set when invoked via batch file), and this is the
// easiest portable way to find our install directory.
//
// can only be called once, by design (see below). rel_path is trusted.
int file_rel_chdir(const char* argv0, const char* rel_path)
{
// security check: only allow attempting to set root dir once
// (this is called early at startup, so any subsequent
// call is most likely malicious).
const char* msg = 0;
// security check: only allow attempting to chdir once, so that malicious
// code cannot circumvent the VFS checks that disallow access to anything
// above the current directory (set here).
// this routine is called early at startup, so any subsequent attempts
// are likely bogus.
static bool already_attempted;
if(already_attempted)
{
debug_warn("vfs_set_root called more than once");
return -1;
msg = "called more than once";
goto fail;
}
already_attempted = true;
// get full path to executable
if(access(argv0, X_OK) < 0)
return -errno;
goto fail;
char n_path[PATH_MAX+1];
n_path[PATH_MAX] = '\0';
if(!realpath(argv0, n_path))
goto fail;
const size_t n_path_len = strlen(n_path);
char path[PATH_MAX+1];
path[PATH_MAX] = '\0';
if(!realpath(argv0, path))
return -errno;
// remove executable name
char* fn = strrchr(path, DIR_SEP);
// strip executable name and append rel_path
char* fn = strrchr(n_path, DIR_SEP);
if(!fn)
return -1;
*fn = 0;
{
msg = "realpath returned an invalid path?";
goto fail;
}
char* pos = fn+1; // will overwrite executable name
CHECK_ERR(mk_native_path(rel_path, pos));
// path is now the absolute path to the executable.
if(chdir(path) < 0)
return -errno;
char* n_root = path; // reuse path[] (no longer needed)
CHECK_ERR(mk_native_path(root_dir, n_root));
if(chdir(n_root) < 0)
return -errno;
if(chdir(n_path) < 0)
goto fail;
return 0;
fail:
debug_warn("file_rel_chdir failed");
if(msg)
{
debug_out("file_rel_chdir: %s\n", msg);
return -1;
}
return -errno;
}

View File

@ -63,7 +63,19 @@ enum FILE_CB_FLAGS
LOC_DIR = BIT(0),
};
extern int file_set_root_dir(const char* argv0, const char* root);
// set current directory to rel_path, relative to the path to the executable,
// which is taken from argv0.
//
// example: executable in "$install_dir/system"; desired root dir is
// "$install_dir/data" => rel_path = "../data".
//
// this is necessary because the current directory is unknown at startup
// (e.g. it isn't set when invoked via batch file), and this is the
// easiest portable way to find our install directory.
//
// can only be called once, by design (see source). rel_path is trusted.
extern int file_rel_chdir(const char* argv0, const char* rel_path);
typedef int(*FileCB)(const char* name, uint flags, ssize_t size, uintptr_t user);

View File

@ -39,7 +39,7 @@ static const char* g_MapFile=0;
static Handle font;
static Handle tex;
extern CCamera g_Camera;
@ -95,6 +95,7 @@ static int write_sys_info()
}
fclose(f);
return 0;
}
@ -231,7 +232,8 @@ void RenderNoCull()
g_Renderer.EndFrame();
}
static void render()
static void Render()
{
// start new frame
g_Renderer.BeginFrame();
@ -262,29 +264,6 @@ static void render()
glMatrixMode(GL_MODELVIEW);
glPushMatrix();
// logo
/* glLoadIdentity();
glTranslatef(50, 100, 0);
tex_bind(tex);
glBegin(GL_QUADS);
const float u = 0.585f, v = 1.0f;
const float x = 600.0f, y = 512.0f;
glTexCoord2f(0, 0); glVertex2f(0, 0);
glTexCoord2f(u, 0); glVertex2f(x, 0);
glTexCoord2f(u, v); glVertex2f(x, y);
glTexCoord2f(0, v); glVertex2f(0, y);
glEnd();
*/
/* glDisable(GL_TEXTURE_2D);
glLoadIdentity();
glBegin(GL_QUADS);
glVertex2i(0, 0);
glVertex2i(111, 0);
glVertex2i(111, 111);
glVertex2i(0, 111);
glEnd();
*/
// FPS counter
glLoadIdentity();
glTranslatef(10, 30, 0);
@ -349,68 +328,42 @@ void ParseArgs(int argc, char* argv[])
}
}
int main(int argc, char* argv[])
{
file_set_root_dir(argv[0], "../data");
const int ERR_MSG_SIZE = 1000;
wchar_t err_msg[ERR_MSG_SIZE];
argc=2;
argv[1] = "-m=test01.pmp";
ParseArgs(argc,argv);
/*
chdir("\\games\\bf\\ScreenShots");
int a,b;
char fn[100];
__asm cpuid __asm rdtsc __asm mov a, eax
int i=0;
/*
int guess=4;
for(;;)
{
sprintf(fn, "ScreenShot%d.jpg", i);
if(access(fn, F_OK) < 0)
{
int lo = guess/2;
int hi = guess;
for(;;)
// set current directory to "$game_dir/data".
// this is necessary because it is otherwise unknown,
// especially if run from a shortcut, batch file, or symlink.
//
// "../data" is relative to the executable (in "$game_dir/system").
//
// rationale for data/ being root: untrusted scripts must not be
// allowed to overwrite critical game (or worse, OS) files.
// the VFS prevents any accesses to files above this directory.
int err = file_rel_chdir(argv[0], "../data");
if(err < 0)
{
int test = (lo+hi)/2;
sprintf(fn, "ScreenShot%d.jpg", i);
if(access(fn, F_OK) < 0)
;
swprintf(err_msg, ERR_MSG_SIZE, L"error setting current directory.\n"\
L"argv[0] is probably incorrect. please start the game via command-line.");
display_startup_error(err_msg);
}
}
else
guess *= 2;
break;
}
*/
/*
DIR* d = opendir(".");
while(readdir(d))
i++;
closedir(d);
*/
/*
for(i = 0; i < 100; i++)
// default to loading map for convenience during development
// override by passing any parameter.
if(argc < 2)
{
sprintf(fn, "ScreenShot%d.jpg", i);
if(access(fn, F_OK) < 0)
break;
argc = 2;
argv[1] = "-m=test01.pmp";
}
ParseArgs(argc, argv);
__asm cpuid __asm rdtsc __asm mov b, eax
int c = b-a;
*/
lib_init();
// set 24 bit (float) FPU precision for faster divides / sqrts
@ -425,8 +378,6 @@ int c = b-a;
new CGUI;
#endif
const int ERR_MSG_SIZE = 1000;
wchar_t err_msg[ERR_MSG_SIZE];
// init SDL
if(SDL_Init(SDL_INIT_VIDEO|SDL_INIT_TIMER|SDL_INIT_NOPARACHUTE) < 0)
@ -473,8 +424,6 @@ int c = b-a;
#endif
// tex = tex_load("0adlogo2.bmp");
// tex_upload(tex);
font = font_load("verdana.fnt");
// set renderer options from command line options - NOVBO must be set before opening the renderer
@ -532,7 +481,7 @@ in_add_handler(terr_handler);
}
UpdateWorld(float(time1-time0));
terr_update(float(time1-time0));
render();
Render();
SDL_GL_SwapBuffers();
calc_fps();
@ -544,7 +493,7 @@ in_add_handler(terr_handler);
in_get_events();
UpdateWorld(float(time1-time0));
terr_update(float(time1-time0));
render();
Render();
SDL_GL_SwapBuffers();
calc_fps();

View File

@ -1,28 +0,0 @@
Win2k SP 4 (5.00.2195)
IA-32, AMD Athlon , 1.80 GHz
512 MB RAM; 209 MB free
RADEON 9600 SERIES
ATI Radeon Family
barton
192.168.1.64
Tex_reload for verdana.raw.
Tex_reload for art/textures/terrain/types/sand/Base2.tga.
Tex_reload for art/textures/terrain/types/road/Base4.tga.
Tex_reload for art/textures/terrain/types/grass/Base1.tga.
Tex_reload for art/textures/terrain/types/grass/Base3.tga.
Tex_reload for art/textures/terrain/types/grass/Base5.tga.
Tex_reload for art/textures/terrain/alphamaps/special/blendcircle.png.
Tex_reload for art/textures/terrain/alphamaps/special/blendlshape.png.
Tex_reload for art/textures/terrain/alphamaps/special/blendedge.png.
Tex_reload for art/textures/terrain/alphamaps/special/blendedgecorner.png.
Tex_reload for art/textures/terrain/alphamaps/special/blendedgetwocorners.png.
Tex_reload for art/textures/terrain/alphamaps/special/blendfourcorners.png.
Tex_reload for art/textures/terrain/alphamaps/special/blendtwooppositecorners.png.
Tex_reload for art/textures/terrain/alphamaps/special/blendlshapecorner.png.
Tex_reload for art/textures/terrain/alphamaps/special/blendtwocorners.png.
Tex_reload for art/textures/terrain/alphamaps/special/blendcorner.png.
Tex_reload for art/textures/terrain/alphamaps/special/blendtwoedges.png.
Tex_reload for art/textures/terrain/alphamaps/special/blendthreecorners.png.
Tex_reload for art/textures/terrain/alphamaps/special/blendushape.png.
Tex_reload for art/textures/terrain/alphamaps/special/blendbad.png.
Tex_reload for terrain.raw.

View File

@ -23,7 +23,7 @@ void CTextureManager::AddTextureType(const char* name)
m_TerrainTextures.resize(m_TerrainTextures.size()+1);
STextureType& ttype=m_TerrainTextures.back();
ttype.m_Name=name;
ttype.m_Index=m_TerrainTextures.size()-1;
ttype.m_Index=(int)m_TerrainTextures.size()-1;
}
CTextureEntry* CTextureManager::FindTexture(const char* filename)

View File

@ -23,25 +23,20 @@ void RenderScene ();
extern bool keys[512]; // SDL also defines non-ascii keys; 512 should be enough
CMatrix3D g_WorldMat;
//CMatrix3D g_WorldMat;
CRenderer g_Renderer;
CTerrain g_Terrain;
CCamera g_Camera;
CLightEnv g_LightEnv;
int SelPX, SelPY, SelTX, SelTY;
int g_BaseTexCounter = 0;
int g_SecTexCounter = 1;
int g_TransTexCounter = 0;
int g_TickCounter = 0;
double g_LastTime;
const int NUM_ALPHA_MAPS = 13;
int mouse_x=50, mouse_y=50;
float ViewScrollSpeed = 60.0f;
float ViewZoomFactor = 1.0f;
void terr_init()
{
int xres,yres;
@ -59,32 +54,47 @@ void terr_init()
InitScene ();
}
void terr_update(float time)
void terr_update(const float DeltaTime)
{
CVector3D right(time*60,0,time*60);
CVector3D up(time*60,0,-time*60);
const float dx = ViewScrollSpeed * DeltaTime;
const CVector3D Right(dx,0, dx);
const CVector3D Up (dx,0,-dx);
if (mouse_x >= g_xres-2)
g_Camera.m_Orientation.Translate(right);
g_Camera.m_Orientation.Translate(Right);
if (mouse_x <= 3)
g_Camera.m_Orientation.Translate(right*-1);
g_Camera.m_Orientation.Translate(Right*-1);
if (mouse_y >= g_yres-2)
g_Camera.m_Orientation.Translate(up);
g_Camera.m_Orientation.Translate(Up);
if (mouse_y <= 3)
g_Camera.m_Orientation.Translate(up*-1);
g_Camera.m_Orientation.Translate(Up*-1);
const float s30 = sin(DEGTORAD(30.0f));
const float c30 = cos(DEGTORAD(30.0f));
const float s45 = sin(DEGTORAD(45.0f));
const float c45 = cos(DEGTORAD(45.0f));
const float s60 = sin(DEGTORAD(60.0f));
const float c60 = cos(DEGTORAD(60.0f));
const CVector3D vert (c30*c45, s45*0, -s30*c45*0);
float fov = g_Camera.GetFOV();
float d = DEGTORAD(0.4f);
if(keys[SDLK_KP_MINUS])
if (fov+d < DEGTORAD(90))
// g_Camera.m_Orientation.Translate(vert);
if (fov < DEGTORAD(90.f))
g_Camera.SetProjection(1, 1000, fov + d);
if(keys[SDLK_KP_PLUS])
// g_Camera.m_Orientation.Translate(vert*-1);
if (fov-d > DEGTORAD(20))
g_Camera.SetProjection(1, 1000, fov - d);
g_Camera.UpdateFrustum ();
}
@ -118,104 +128,6 @@ bool terr_handler(const SDL_Event& ev)
g_Camera.m_Orientation.RotateY(DEGTORAD(-45));
g_Camera.m_Orientation.Translate (100, 150, -100);
break;
/* case 'L':
g_HillShading = !g_HillShading;
break;*/
// tile selection
case SDLK_DOWN:
if(++SelTX > 15)
if(SelPX == g_Terrain.GetPatchesPerSide()-1)
SelTX = 15;
else
SelTX = 0, SelPX++;
break;
case SDLK_UP:
if(--SelTX < 0)
if(SelPX == 0)
SelTX = 0;
else
SelTX = 15, SelPX--;
break;
case SDLK_RIGHT:
if(++SelTY > 15)
if(SelPY == g_Terrain.GetPatchesPerSide()-1)
SelTY = 15;
else
SelTY = 0, SelPY++;
break;
case SDLK_LEFT:
if(--SelTY < 0)
if(SelPY == 0)
SelTY = 0;
else
SelTY = 15, SelPY--;
break;
case SDLK_KP0:
{
CMiniPatch *MPatch = &g_Terrain.GetPatch(SelPY, SelPX)->m_MiniPatches[SelTY][SelTX];
/*if (!MPatch->Tex2)
{
MPatch->m_AlphaMap = AlphaMaps[g_TransTexCounter];
MPatch->Tex2 = BaseTexs[g_SecTexCounter];
}
else
{
MPatch->Tex2 = 0;
MPatch->m_AlphaMap = 0;
}*/
break;
}
/*case SDLK_KP1:
{
CMiniPatch *MPatch = &g_Terrain.GetPatch(SelPY, SelPX)->m_MiniPatches[SelTY][SelTX];
g_BaseTexCounter++;
if (g_BaseTexCounter > 4)
g_BaseTexCounter = 0;
MPatch->Tex1 = BaseTexs[g_BaseTexCounter];
break;
}
case SDLK_KP2:
{
CMiniPatch *MPatch = &g_Terrain.m_Patches[SelPY][SelPX].m_MiniPatches[SelTY][SelTX];
if (MPatch->Tex2)
{
g_SecTexCounter++;
if (g_SecTexCounter > 4)
g_SecTexCounter = 0;
MPatch->Tex2 = BaseTexs[g_SecTexCounter];
}
break;
}
case SDLK_KP3:
{
CMiniPatch *MPatch = &g_Terrain.m_Patches[SelPY][SelPX].m_MiniPatches[SelTY][SelTX];
if (MPatch->m_AlphaMap)
{
g_TransTexCounter++;
if (g_TransTexCounter >= NUM_ALPHA_MAPS)
g_TransTexCounter = 0;
MPatch->m_AlphaMap = AlphaMaps[g_TransTexCounter];
}
break;
}*/
}
}
@ -243,7 +155,7 @@ void InitScene ()
int w;
int h;
tex_info(ht, &w, &h, NULL, NULL, (void **)&p);
tex_info(ht, &w, &h, NULL, NULL, (void**)&p);
printf("terrain.raw: %dx%d\n", w, h);
@ -290,8 +202,6 @@ for (uint ii=0;ii<g_TexMan.m_TerrainTextures.size();ii++) {
g_Camera.m_Orientation.RotateY(DEGTORAD(-45));
g_Camera.m_Orientation.Translate (100, 150, -100);
SelPX = SelPY = SelTX = SelTY = 0;
}
void InitResources()