/* * @brief A client issued an rcon command. Shift down the remaining args and * redirect all output to the invoking client. */ static void Svc_RemoteCommand(void) { const _Bool auth = Sv_RconAuthenticate(); const char *addr = Net_NetaddrToString(&net_from); // first print to the server console if (auth) Com_Print("Rcon from %s:\n%s\n", addr, net_message.data + 4); else Com_Print("Bad rcon from %s:\n%s\n", addr, net_message.data + 4); // then redirect the remaining output back to the client Com_BeginRedirect(RD_PACKET, sv_outputbuf, SV_OUTPUTBUF_LENGTH, Sv_FlushRedirect); if (auth) { char remaining[MAX_STRING_CHARS]; int32_t i; remaining[0] = 0; for (i = 2; i < Cmd_Argc(); i++) { strcat(remaining, Cmd_Argv(i)); strcat(remaining, " "); } Cmd_ExecuteString(remaining); } else { Com_Print("Bad rcon_password\n"); } Com_EndRedirect(); }
/* * @brief A client issued an rcon command. Shift down the remaining args and * redirect all output to the invoking client. */ static void Sv_Rcon_f(void) { const _Bool auth = Sv_RconAuthenticate(); const char *addr = Net_NetaddrToString(&net_from); // first print to the server console if (auth) Com_Print("Rcon from %s:\n%s\n", addr, net_message.data + 4); else Com_Print("Bad rcon from %s:\n%s\n", addr, net_message.data + 4); // then redirect the remaining output back to the client console_t rcon = { .Append = Sv_Rcon_Print }; sv_rcon_buffer[0] = '\0'; Con_AddConsole(&rcon); if (auth) { char cmd[MAX_STRING_CHARS]; cmd[0] = '\0'; for (int32_t i = 2; i < Cmd_Argc(); i++) { g_strlcat(cmd, Cmd_Argv(i), sizeof(cmd)); g_strlcat(cmd, " ", sizeof(cmd)); } Cmd_ExecuteString(cmd); } else { Com_Print("Bad rcon_password\n"); } Netchan_OutOfBandPrint(NS_UDP_SERVER, &net_from, "print\n%s", sv_rcon_buffer); Con_RemoveConsole(&rcon); }