From b353ec463ad3b7c0ce7ce870746e1a4b245ff3eb Mon Sep 17 00:00:00 2001 From: Alibek Omarov Date: Thu, 5 Mar 2026 04:44:19 +0500 Subject: [PATCH] engine: host: move exec, userconfigd and memstats to it's respective files --- engine/common/cmd.c | 122 +++++++++++++++++++++++++++++++++++-- engine/common/host.c | 141 ++----------------------------------------- engine/common/zone.c | 25 +++++++- 3 files changed, 146 insertions(+), 142 deletions(-) diff --git a/engine/common/cmd.c b/engine/common/cmd.c index 50c335e2..d93439e2 100644 --- a/engine/common/cmd.c +++ b/engine/common/cmd.c @@ -1243,6 +1243,118 @@ static void Cmd_MakePrivileged_f( void ) } } +/* +=============== +Cmd_Exec_f +=============== +*/ +static void Cmd_Exec_f( void ) +{ + string cfgpath; + byte *f; + fs_offset_t len; + + if( Cmd_Argc() != 2 ) + { + Con_Printf( S_USAGE "exec \n" ); + return; + } + + Q_strncpy( cfgpath, Cmd_Argv( 1 ), sizeof( cfgpath )); + COM_DefaultExtension( cfgpath, ".cfg", sizeof( cfgpath )); // append as default + +#ifndef XASH_DEDICATED + if( !Cmd_CurrentCommandIsPrivileged() && !Q_stricmp( GI->gamefolder, "tfc" )) + { + const char *const unprivileged_whitelist[] = + { + "civilian.cfg", "demoman.cfg", "engineer.cfg", + "hwguy.cfg", "mapdefault.cfg", "medic.cfg", "pyro.cfg", + "scout.cfg", "sniper.cfg", "soldier.cfg", "spy.cfg", + }; + char mapcfg[MAX_VA_STRING]; + qboolean allow = false; + + Q_snprintf( mapcfg, sizeof( mapcfg ), "%s.cfg", clgame.mapname ); + + if( !Q_stricmp( mapcfg, cfgpath )) + { + allow = true; + } + else for( int i = 0; i < ARRAYSIZE( unprivileged_whitelist ); i++ ) + { + if( !Q_strcmp( cfgpath, unprivileged_whitelist[i] )) + { + allow = true; + break; + } + } + + if( !allow ) + { + Con_Printf( "exec %s: not privileged or in whitelist\n", cfgpath ); + return; + } + } +#endif // XASH_DEDICATED + + // don't execute game.cfg in singleplayer + if( SV_GetMaxClients() == 1 && !Q_stricmp( "game.cfg", cfgpath )) + return; + + f = FS_LoadFile( cfgpath, &len, false ); + if( !f ) + { + Con_Reportf( "couldn't exec %s\n", Cmd_Argv( 1 )); + return; + } + + // len is fs_offset_t, which can be larger than size_t + if( len >= SIZE_MAX ) + { + Con_Reportf( "%s: %s is too long\n", __func__, Cmd_Argv( 1 )); + return; + } + + if( !Q_stricmp( "config.cfg", cfgpath )) + host.config_executed = true; + + Con_Printf( "execing " S_GREEN "%s" S_DEFAULT "\n", Cmd_Argv( 1 )); + + // adds \n at end of the file + // FS_LoadFile always null terminates + if( f[len - 1] != '\n' ) + { + Cbuf_InsertTextLen( f, len, len + 1 ); + Cbuf_InsertTextLen( "\n", 1, 1 ); + } + else Cbuf_InsertTextLen( f, len, len ); + + Mem_Free( f ); +} + +/* +================= +Cmd_Userconfigd_f +================= +*/ +static void Cmd_Userconfigd_f( void ) +{ + search_t *t; + int i; + + t = FS_Search( "userconfig.d/*.cfg", true, false ); + if( !t ) + return; + + for( i = 0; i < t->numfilenames; i++ ) + { + Cbuf_AddTextf( "exec %s\n", t->filenames[i] ); + } + + Mem_Free( t ); +} + /* ========== Cmd_Escape @@ -1294,9 +1406,9 @@ void Cmd_Init( void ) // register our commands Cmd_AddCommand( "echo", Cmd_Echo_f, "print a message to the console (useful in scripts)" ); Cmd_AddCommand( "wait", Cmd_Wait_f, "make script execution wait for some rendered frames" ); - Cmd_AddCommand( "cmdlist", Cmd_List_f, "display all console commands beginning with the specified prefix" ); + Cmd_AddRestrictedCommand( "cmdlist", Cmd_List_f, "display all console commands beginning with the specified prefix" ); Cmd_AddRestrictedCommand( "stuffcmds", Cmd_StuffCmds_f, "execute commandline parameters (must be present in .rc script)" ); - Cmd_AddCommand( "apropos", Cmd_Apropos_f, "lists all console variables/commands/aliases containing the specified string in the name or description" ); + Cmd_AddRestrictedCommand( "apropos", Cmd_Apropos_f, "lists all console variables/commands/aliases containing the specified string in the name or description" ); #if !XASH_DEDICATED Cmd_AddCommand( "cmd", Cmd_ForwardToServer, "send a console commandline to the server" ); #endif // XASH_DEDICATED @@ -1307,8 +1419,10 @@ void Cmd_Init( void ) Cmd_AddRestrictedCommand( "make_privileged", Cmd_MakePrivileged_f, "makes command or variable privileged (protected from access attempts from server)" ); - Cmd_AddCommand( "basecmd_stats", BaseCmd_Stats_f, "print info about basecmd usage" ); - Cmd_AddCommand( "basecmd_test", BaseCmd_Test_f, "test basecmd" ); + Cmd_AddRestrictedCommand( "basecmd_stats", BaseCmd_Stats_f, "print info about basecmd usage" ); + Cmd_AddRestrictedCommand( "basecmd_test", BaseCmd_Test_f, "test basecmd" ); + Cmd_AddCommand( "exec", Cmd_Exec_f, "execute a script file" ); + Cmd_AddRestrictedCommand( "userconfigd", Cmd_Userconfigd_f, "execute all scripts from userconfig.d" ); } void Cmd_Shutdown( void ) diff --git a/engine/common/host.c b/engine/common/host.c index 9f81b23b..c4b91a45 100644 --- a/engine/common/host.c +++ b/engine/common/host.c @@ -435,118 +435,6 @@ static void Host_ChangeGame_f( void ) } } -/* -=============== -Host_Exec_f -=============== -*/ -static void Host_Exec_f( void ) -{ - string cfgpath; - byte *f; - fs_offset_t len; - - if( Cmd_Argc() != 2 ) - { - Con_Printf( S_USAGE "exec \n" ); - return; - } - - Q_strncpy( cfgpath, Cmd_Argv( 1 ), sizeof( cfgpath )); - COM_DefaultExtension( cfgpath, ".cfg", sizeof( cfgpath )); // append as default - -#ifndef XASH_DEDICATED - if( !Cmd_CurrentCommandIsPrivileged() ) - { - const char *unprivilegedWhitelist[] = - { - NULL, "mapdefault.cfg", "scout.cfg", "sniper.cfg", - "soldier.cfg", "demoman.cfg", "medic.cfg", "hwguy.cfg", - "pyro.cfg", "spy.cfg", "engineer.cfg", "civilian.cfg" - }; - int i; - char temp[MAX_VA_STRING]; - qboolean allow = false; - - Q_snprintf( temp, sizeof( temp ), "%s.cfg", clgame.mapname ); - unprivilegedWhitelist[0] = temp; - - for( i = 0; i < ARRAYSIZE( unprivilegedWhitelist ); i++ ) - { - if( !Q_strcmp( cfgpath, unprivilegedWhitelist[i] )) - { - allow = true; - break; - } - } - - if( !allow ) - { - Con_Printf( "exec %s: not privileged or in whitelist\n", cfgpath ); - return; - } - } -#endif // XASH_DEDICATED - - // don't execute game.cfg in singleplayer - if( SV_GetMaxClients() == 1 && !Q_stricmp( "game.cfg", cfgpath )) - return; - - f = FS_LoadFile( cfgpath, &len, false ); - if( !f ) - { - Con_Reportf( "couldn't exec %s\n", Cmd_Argv( 1 )); - return; - } - - // len is fs_offset_t, which can be larger than size_t - if( len >= SIZE_MAX ) - { - Con_Reportf( "%s: %s is too long\n", __func__, Cmd_Argv( 1 )); - return; - } - - if( !Q_stricmp( "config.cfg", cfgpath )) - host.config_executed = true; - - if( !host.apply_game_config ) - Con_Printf( "execing %s\n", Cmd_Argv( 1 )); - - // adds \n at end of the file - // FS_LoadFile always null terminates - if( f[len - 1] != '\n' ) - { - Cbuf_InsertTextLen( f, len, len + 1 ); - Cbuf_InsertTextLen( "\n", 1, 1 ); - } - else Cbuf_InsertTextLen( f, len, len ); - - Mem_Free( f ); -} - -/* -=============== -Host_MemStats_f -=============== -*/ -static void Host_MemStats_f( void ) -{ - switch( Cmd_Argc( )) - { - case 1: - Mem_PrintList( 1<<30 ); - Mem_PrintStats(); - break; - case 2: - Mem_PrintList( Q_atoi( Cmd_Argv( 1 )) * 1024 ); - Mem_PrintStats(); - break; - default: - Con_Printf( S_USAGE "memlist \n" ); - break; - } -} - /* ================= Host_RegisterDecal @@ -902,27 +790,6 @@ static void Host_Crash_f( void ) *(volatile int *)0 = 0xffffffff; } -/* -================= -Host_Userconfigd_f -================= -*/ -static void Host_Userconfigd_f( void ) -{ - search_t *t; - int i; - - t = FS_Search( "userconfig.d/*.cfg", true, false ); - if( !t ) return; - - for( i = 0; i < t->numfilenames; i++ ) - { - Cbuf_AddTextf( "exec %s\n", t->filenames[i] ); - } - - Mem_Free( t ); -} - #if XASH_ENGINE_TESTS static void Host_RunTests( int stage ) { @@ -1136,9 +1003,7 @@ static void Host_InitCommon( int argc, char **argv, const char *progname, qboole host.bugcomp = Host_CheckBugcomp(); - Cmd_AddCommand( "exec", Host_Exec_f, "execute a script file" ); - Cmd_AddCommand( "memlist", Host_MemStats_f, "prints memory pool information" ); - Cmd_AddRestrictedCommand( "userconfigd", Host_Userconfigd_f, "execute all scripts from userconfig.d" ); + Cmd_AddCommand( "memlist", Mem_Stats_f, "prints memory pool information" ); #if !XASH_DEDICATED Cmd_AddRestrictedCommand( "host_writeconfig", Host_WriteConfig, "save current configuration" ); @@ -1301,8 +1166,10 @@ int EXPORT Host_Main( int argc, char **argv, const char *progname, int bChangeGa Cbuf_AddText( "exec config.cfg\n" ); Cbuf_Execute(); } + // exec all files from userconfig.d - Host_Userconfigd_f(); + Cbuf_AddText( "userconfigd\n" ); + Cbuf_Execute(); break; case HOST_DEDICATED: // allways parse commandline in dedicated-mode diff --git a/engine/common/zone.c b/engine/common/zone.c index 32778708..3127ac79 100644 --- a/engine/common/zone.c +++ b/engine/common/zone.c @@ -471,7 +471,7 @@ void Mem_PrintStats( void ) Con_Printf( "total allocated size: ^1%s\n", Q_memprint( realsize )); } -void Mem_PrintList( size_t minallocationsize ) +static void Mem_PrintList( size_t minallocationsize ) { mempool_t *pool; memheader_t *mem; @@ -510,6 +510,29 @@ void Mem_PrintList( size_t minallocationsize ) } } +/* +=============== +Mem_Stats_f +=============== +*/ +void Mem_Stats_f( void ) +{ + switch( Cmd_Argc( )) + { + case 1: + Mem_PrintList( 1<<30 ); + Mem_PrintStats(); + break; + case 2: + Mem_PrintList( Q_atoi( Cmd_Argv( 1 )) * 1024 ); + Mem_PrintStats(); + break; + default: + Con_Printf( S_USAGE "memlist \n" ); + break; + } +} + /* ======================== Memory_Init