diff options
-rw-r--r-- | src/cmd.c | 93 | ||||
-rw-r--r-- | src/com_local.h | 3 | ||||
-rw-r--r-- | src/common.c | 26 | ||||
-rw-r--r-- | src/files.c | 7 | ||||
-rw-r--r-- | src/sys_unix.c | 7 |
5 files changed, 98 insertions, 38 deletions
@@ -1558,7 +1558,7 @@ void Cmd_ExecuteCommand( cmdbuf_t *buf ) { // check aliases a = Cmd_AliasFind( cmd_argv[0] ); if( a ) { - if( buf->aliasCount == ALIAS_LOOP_COUNT ) { + if( buf->aliasCount >= ALIAS_LOOP_COUNT ) { Com_WPrintf( "Runaway alias loop\n" ); return; } @@ -1604,6 +1604,56 @@ void Cmd_ExecuteString( cmdbuf_t *buf, const char *text ) { Cmd_ExecuteCommand( buf ); } +qerror_t Cmd_ExecuteFile( const char *path, unsigned flags ) { + char *f; + ssize_t len; + qerror_t ret; + cmdbuf_t *buf; + + len = FS_LoadFileEx( path, ( void ** )&f, flags ); + if( !f ) { + return len; + } + + // check for binary file + if( memchr( f, 0, len ) ) { + ret = Q_ERR_INVALID_FORMAT; + goto finish; + } + + // sanity check file size after stripping off comments + len = COM_Compress( f ); + if( len > CMD_BUFFER_SIZE ) { + ret = Q_ERR_FBIG; + goto finish; + } + + // FIXME: always insert into main command buffer, + // no matter where command came from? + buf = &cmd_buffer; + + // check for exec loop + if( ++buf->aliasCount > ALIAS_LOOP_COUNT ) { + ret = Q_ERR_RUNAWAY_LOOP; + goto finish; + } + + // check for overflow + if( buf->cursize + len + 1 > buf->maxsize ) { + ret = Q_ERR_STRING_TRUNCATED; + goto finish; + } + + // everything ok, execute it + Com_Printf( "Execing %s\n", path ); + Cbuf_InsertText( buf, f ); + ret = Q_ERR_SUCCESS; + +finish: + FS_FreeFile( f ); + return ret; +} + /* =============== Cmd_Exec_f @@ -1611,42 +1661,33 @@ Cmd_Exec_f */ static void Cmd_Exec_f( void ) { char buffer[MAX_QPATH]; - char *f; - ssize_t len; + size_t len; + qerror_t ret; if( Cmd_Argc() != 2 ) { Com_Printf( "%s <filename> : execute a script file\n", Cmd_Argv( 0 ) ); return; } - Cmd_ArgvBuffer( 1, buffer, sizeof( buffer ) ); + len = Cmd_ArgvBuffer( 1, buffer, sizeof( buffer ) ); + if( len >= sizeof( buffer ) ) { + ret = Q_ERR_NAMETOOLONG; + goto fail; + } - len = FS_LoadFile( buffer, ( void ** )&f ); - if( !f ) { - // try with *.cfg extension - COM_DefaultExtension( buffer, ".cfg", sizeof( buffer ) ); - len = FS_LoadFile( buffer, ( void ** )&f ); - if( !f ) { - Com_Printf( "Couldn't exec %s: %s\n", buffer, Q_ErrorString( len ) ); - return; + ret = Cmd_ExecuteFile( buffer, 0 ); + if( ret == Q_ERR_NOENT && FS_strcmp( COM_FileExtension( buffer ), ".cfg" ) ) { + // try with .cfg extension + len = COM_DefaultExtension( buffer, ".cfg", sizeof( buffer ) ); + if( len < sizeof( buffer ) ) { + ret = Cmd_ExecuteFile( buffer, 0 ); } } - if( memchr( f, 0, len ) ) { - Com_Printf( "Refusing to exec binary file %s\n", buffer ); - goto finish; + if( ret ) { +fail: + Com_Printf( "Couldn't exec %s: %s\n", buffer, Q_ErrorString( ret ) ); } - - Com_Printf( "Execing %s\n", buffer ); - - // FIXME: bad thing to do in place - COM_Compress( f ); - - // FIXME: always insert into generic command buffer - Cbuf_InsertText( &cmd_buffer, f ); - -finish: - FS_FreeFile( f ); } void Cmd_Config_g( genctx_t *ctx ) { diff --git a/src/com_local.h b/src/com_local.h index 6938041..f4d03d3 100644 --- a/src/com_local.h +++ b/src/com_local.h @@ -176,6 +176,9 @@ void Cmd_ExecuteString( cmdbuf_t *buf, const char *text ); // Parses a single line of text into arguments and tries to execute it // as if it was typed at the console +qerror_t Cmd_ExecuteFile( const char *path, unsigned flags ); +// execute a config file + char *Cmd_MacroExpandString( const char *text, qboolean aliasHack ); void Cmd_Register( const cmdreg_t *reg ); diff --git a/src/common.c b/src/common.c index caee295..5096733 100644 --- a/src/common.c +++ b/src/common.c @@ -1729,6 +1729,16 @@ static qboolean Com_AddLateCommands( void ) { return ret; } +static void Com_AddConfigFile( const char *name, unsigned flags ) { + qerror_t ret; + + ret = Cmd_ExecuteFile( name, flags ); + if( ret == Q_ERR_SUCCESS ) { + Cbuf_Execute( &cmd_buffer ); + } else if( ret != Q_ERR_NOENT ) { + Com_WPrintf( "Couldn't exec %s: %s\n", name, Q_ErrorString( ret ) ); + } +} /* ================= @@ -1819,8 +1829,7 @@ void Qcommon_Init( int argc, char **argv ) { // add any system-wide configuration files Sys_AddDefaultConfig(); - Cbuf_Execute( &cmd_buffer ); - + // we need to add the early commands twice, because // a basedir or cddir needs to be set before execing // config files, but we want other parms to override @@ -1851,14 +1860,11 @@ void Qcommon_Init( int argc, char **argv ) { logfile_name->changed = logfile_param_changed; logfile_enable_changed( logfile_enable ); - Cbuf_AddText( &cmd_buffer, "exec "COM_DEFAULTCFG_NAME"\n" ); - Cbuf_Execute( &cmd_buffer ); - - Cbuf_AddText( &cmd_buffer, "exec "COM_CONFIG_NAME"\n" ); - Cbuf_Execute( &cmd_buffer ); - - Cbuf_AddText( &cmd_buffer, "exec "COM_AUTOEXECCFG_NAME"\n" ); - Cbuf_Execute( &cmd_buffer ); + // execute configs: default.cfg may come from the packfile, but config.cfg + // and autoexec.cfg must be real files within the game directory + Com_AddConfigFile( COM_DEFAULTCFG_NAME, 0 ); + Com_AddConfigFile( COM_CONFIG_NAME, FS_TYPE_REAL|FS_PATH_GAME ); + Com_AddConfigFile( COM_AUTOEXECCFG_NAME, FS_TYPE_REAL|FS_PATH_GAME ); Com_AddEarlyCommands( qtrue ); diff --git a/src/files.c b/src/files.c index 0b3de80..d39d595 100644 --- a/src/files.c +++ b/src/files.c @@ -2952,6 +2952,7 @@ void FS_Shutdown( void ) { // disconnected static void fs_game_changed( cvar_t *self ) { char *s = self->string; + qerror_t ret; // validate it if( *s ) { @@ -2981,6 +2982,12 @@ static void fs_game_changed( cvar_t *self ) { #else FS_Restart( qfalse ); #endif + + // exec autoexec.cfg (must be a real file within the game directory) + ret = Cmd_ExecuteFile( COM_AUTOEXECCFG_NAME, FS_TYPE_REAL|FS_PATH_GAME ); + if( ret && ret != Q_ERR_NOENT ) { + Com_WPrintf( "Couldn't exec %s: %s\n", COM_AUTOEXECCFG_NAME, Q_ErrorString( ret ) ); + } } /* diff --git a/src/sys_unix.c b/src/sys_unix.c index 769bebd..99354b2 100644 --- a/src/sys_unix.c +++ b/src/sys_unix.c @@ -570,8 +570,6 @@ void Sys_AddDefaultConfig( void ) { } if( fstat( fileno( fp ), &st ) == 0 ) { - Com_Printf( "Execing " SYS_SITECFG_NAME "\n" ); - len = st.st_size; if( len >= cmd_buffer.maxsize ) { len = cmd_buffer.maxsize - 1; @@ -584,6 +582,11 @@ void Sys_AddDefaultConfig( void ) { } fclose( fp ); + + if( cmd_buffer.cursize ) { + Com_Printf( "Execing %s\n", SYS_SITECFG_NAME ); + Cbuf_Execute( &cmd_buffer ); + } } void Sys_Sleep( int msec ) { |