int FS_Game_FOpenFileByMode(const char* path, fileHandle_t* handle, fsMode_t mode) { switch (mode) { case fsMode_t::FS_READ: if (FS::PakPath::FileExists(path)) return FS_FOpenFileRead(path, handle, false); else { int size = FS_SV_FOpenFileRead(FS::Path::Build("game", path).c_str(), handle); return (!handle || *handle) ? size : -1; } case fsMode_t::FS_WRITE: case fsMode_t::FS_WRITE_VIA_TEMPORARY: *handle = FS_FOpenFileWrite_internal(FS::Path::Build("game", path).c_str(), mode == fsMode_t::FS_WRITE_VIA_TEMPORARY); return *handle == 0 ? -1 : 0; case fsMode_t::FS_APPEND: case fsMode_t::FS_APPEND_SYNC: *handle = FS_FOpenFileAppend(FS::Path::Build("game", path).c_str()); handleTable[*handle].forceFlush = mode == fsMode_t::FS_APPEND_SYNC; return *handle == 0 ? -1 : 0; default: Com_Error(errorParm_t::ERR_DROP, "FS_Game_FOpenFileByMode: bad mode %s", Util::enum_str(mode)); } }
/* ================== CL_OpenClientLog ================== */ void CL_OpenClientLog(void) { if( cl_logs && cl_logs->integer ) { if( FS_Initialized() && LogFileOpened == qfalse ) { char FileLocation[ 255 ]; char *nowString; //get current time/date info qtime_t now; Com_RealTime( &now ); nowString = va( "%04d-%02d-%02d", 1900 + now.tm_year, 1 + now.tm_mon, now.tm_mday ); sprintf(FileLocation,"logs/%s.log", nowString ); LogFileHandle = FS_FOpenFileAppend( FileLocation ); //open file with filename as date LogFileOpened = qtrue; //var to tell if files open } } }
void QDECL SV_EnterLeaveLog( const char *fmt, ... ) { Sys_EnterCriticalSection(5); va_list argptr; char msg[MAXPRINTMSG]; char inputmsg[MAXPRINTMSG]; struct tm *newtime; char* ltime; time_t realtime; // logfile if ( com_logfile && com_logfile->integer ) { // TTimo: only open the qconsole.log if the filesystem is in an initialized state // also, avoid recursing in the qconsole.log opening (i.e. if fs_debug is on) va_start (argptr,fmt); Q_vsnprintf (inputmsg, sizeof(inputmsg), fmt, argptr); va_end (argptr); Com_UpdateRealtime(); realtime = Com_GetRealtime(); newtime = localtime( &realtime ); ltime = asctime( newtime ); ltime[strlen(ltime)-1] = 0; if ( !enterleavelogfile && FS_Initialized()) { enterleavelogfile = FS_FOpenFileAppend( "enterleave.log" ); // force it to not buffer so we get valid if ( enterleavelogfile ){ FS_ForceFlush(enterleavelogfile); FS_Write(va("\nLogfile opened on %s\n\n", ltime), strlen(va("\nLogfile opened on %s\n\n", ltime)), enterleavelogfile); } } if ( enterleavelogfile && FS_Initialized()) { Com_sprintf(msg, sizeof(msg), "%s: %s\n", ltime, inputmsg); FS_Write(msg, strlen(msg), enterleavelogfile); } } Sys_LeaveCriticalSection(5); }
void QDECL Com_PrintAdministrativeLog( const char *msg ) { Sys_EnterCriticalSection(5); struct tm *newtime; char* ltime; time_t realtime; // logfile if ( com_logfile && com_logfile->integer ) { // TTimo: only open the qconsole.log if the filesystem is in an initialized state // also, avoid recursing in the qconsole.log opening (i.e. if fs_debug is on) if ( !adminlogfile && FS_Initialized()) { Com_UpdateRealtime(); realtime = Com_GetRealtime(); newtime = localtime( &realtime ); ltime = asctime( newtime ); ltime[strlen(ltime)-1] = 0; adminlogfile = FS_FOpenFileAppend( "adminactions.log" ); // force it to not buffer so we get valid if ( adminlogfile ){ FS_ForceFlush(adminlogfile); FS_Write(va("\nLogfile opened on %s\n\n", ltime), strlen(va("\nLogfile opened on %s\n\n", ltime)), adminlogfile); } } if ( adminlogfile && FS_Initialized()) { FS_Write(msg, strlen(msg), adminlogfile); } } Sys_LeaveCriticalSection(5); }
/* * Finds the file in the search path. Returns filesize and an open FILE *. Used * for streaming data out of either a pak file or a seperate file. */ int FS_FOpenFile(const char *name, fileHandle_t *f, fsMode_t mode) { int size = 0; fsHandle_t *handle; handle = FS_HandleForFile(name, f); Q_strlcpy(handle->name, name, sizeof(handle->name)); handle->mode = mode; switch (mode) { case FS_READ: size = FS_FOpenFileRead(handle); break; case FS_WRITE: size = FS_FOpenFileWrite(handle); break; case FS_APPEND: size = FS_FOpenFileAppend(handle); break; default: Com_Error(ERR_FATAL, "FS_FOpenFile: bad mode (%i)", mode); break; } if (size != -1) { return size; } /* Couldn't open, so free the handle. */ memset(handle, 0, sizeof(*handle)); *f = 0; return -1; }
static void SV_AddBanToList(qboolean isexception) { char *banstring, *suffix; netadr_t ip; int argc, mask; fileHandle_t writeto; argc = Cmd_Argc(); if(argc < 2 || argc > 3) { Com_Printf ("Usage: %s (ip[/subnet] | clientnum [subnet])\n", Cmd_Argv(0)); return; } if(serverBansCount > sizeof(serverBans) / sizeof(*serverBans)) { Com_Printf ("Error: Maximum number of bans/exceptions exceeded.\n"); return; } banstring = Cmd_Argv(1); if(strchr(banstring, '.') || strchr(banstring, ':')) { // This is an ip address, not a client num. // Look for a CIDR-Notation suffix suffix = strchr(banstring, '/'); if(suffix) { *suffix = '\0'; suffix++; } if(!NET_StringToAdr(banstring, &ip, NA_UNSPEC)) { Com_Printf("Error: Invalid address %s\n", banstring); return; } } else { client_t *cl; // client num. if(!com_sv_running->integer) { Com_Printf("Server is not running.\n"); return; } cl = SV_GetPlayerByNum(); if(!cl) { Com_Printf("Error: Playernum %s does not exist.\n", Cmd_Argv(1)); return; } ip = cl->netchan.remoteAddress; if(argc == 3) suffix = Cmd_Argv(2); else suffix = NULL; } if(ip.type != NA_IP && ip.type != NA_IP6) { Com_Printf("Error: Can ban players connected via the internet only.\n"); return; } if(suffix) { mask = atoi(suffix); if(ip.type == NA_IP) { if(mask < 0 || mask > 32) mask = 32; } else { if(mask < 0 || mask > 128) mask = 128; } } else if(ip.type == NA_IP) mask = 32; else mask = 128; serverBans[serverBansCount].ip = ip; serverBans[serverBansCount].subnet = mask; serverBans[serverBansCount].isexception = isexception; Com_Printf("Added %s: %s/%d\n", isexception ? "ban exception" : "ban", NET_AdrToString(ip), mask); // Write out the ban information. if((writeto = FS_FOpenFileAppend(SERVER_BANFILE))) { char writebuf[128]; Com_sprintf(writebuf, sizeof(writebuf), "%d %s %d\n", isexception, NET_AdrToString(ip), mask); FS_Write(writebuf, strlen(writebuf), writeto); FS_FCloseFile(writeto); } serverBansCount++; }
/* =============== SVC_RemoteCommand An rcon packet arrived from the network. Shift down the remaining args Redirect all printfs =============== */ void SVC_RemoteCommand( netadr_t from, msg_t *msg ) { qboolean valid; unsigned int time; char remaining[1024]; // TTimo - scaled down to accumulate, but not overflow anything network wise, print wise etc. // (OOB messages are the bottleneck here) #define SV_OUTPUTBUF_LENGTH (1024 - 16) char sv_outputbuf[SV_OUTPUTBUF_LENGTH]; static unsigned int lasttime = 0; char *cmd_aux; fileHandle_t rconLog = 0; // TTimo - https://zerowing.idsoftware.com/bugzilla/show_bug.cgi?id=534 time = Com_Milliseconds(); if ( (unsigned)( time - lasttime ) < 500u ) { return; } lasttime = time; if(strlen(sv_rconLog->string)) { rconLog = FS_FOpenFileAppend(sv_rconLog->string); if (!rconLog) { Com_Printf("Warning: Unable to open sv_rconLog: \"%s\"", sv_rconLog->string); Cvar_Set ("sv_rconLog", ""); } } const char *message = ""; if ( !strlen( sv_rconPassword->string ) || strcmp (Cmd_Argv(1), sv_rconPassword->string) ) { valid = qfalse; message = va("Bad rcon from %s: %s\n", NET_AdrToString (from), Cmd_ArgsFrom(2)); } else { valid = qtrue; message = va("Rcon from %s: %s\n", NET_AdrToString (from), Cmd_ArgsFrom(2)); } Com_Printf (message); if (rconLog) { qtime_t qt; Com_RealTime(&qt); char *timestamp = va( "%02i/%02i/%02i %02i:%02i:%02i ", qt.tm_mday, qt.tm_mon, qt.tm_year-100, qt.tm_hour, qt.tm_min, qt.tm_sec ); FS_Write(timestamp, strlen(timestamp), rconLog); FS_Write(message, strlen(message), rconLog); FS_FCloseFile(rconLog); } // start redirecting all print outputs to the packet svs.redirectAddress = from; Com_BeginRedirect (sv_outputbuf, SV_OUTPUTBUF_LENGTH, SV_FlushRedirect); if ( !strlen( sv_rconPassword->string ) ) { Com_Printf ("No rconpassword set on the server.\n"); } else if ( !valid ) { Com_Printf ("Bad rconpassword.\n"); } else { remaining[0] = 0; // https://zerowing.idsoftware.com/bugzilla/show_bug.cgi?id=543 // get the command directly, "rcon <pass> <command>" to avoid quoting issues // extract the command by walking // since the cmd formatting can fuckup (amount of spaces), using a dumb step by step parsing cmd_aux = Cmd_Cmd(); cmd_aux+=4; while(cmd_aux[0]==' ') cmd_aux++; while(cmd_aux[0] && cmd_aux[0]!=' ') // password cmd_aux++; while(cmd_aux[0]==' ') cmd_aux++; Q_strcat( remaining, sizeof(remaining), cmd_aux); Cmd_ExecuteString (remaining); } Com_EndRedirect (); }