Exemplo n.º 1
0
/*
=====================
SV_WipeSavegame

Delete save/<XXX>/
=====================
*/
static void SV_WipeSavegame (const char *savename)
{
	char	name[MAX_OSPATH];
	char	*s;

	Com_DPrintf("SV_WipeSaveGame(%s)\n", savename);

	Com_sprintf (name, sizeof(name), "%s/save/%s/server.ssv", FS_Gamedir (), savename);
	FS_RemoveFile(name);
	Com_sprintf (name, sizeof(name), "%s/save/%s/game.ssv", FS_Gamedir (), savename);
	FS_RemoveFile(name);

	Com_sprintf (name, sizeof(name), "%s/save/%s/*.sav", FS_Gamedir (), savename);
	s = Sys_FindFirst( name, 0, 0 );
	while (s)
	{
		FS_RemoveFile(s);
		s = Sys_FindNext( 0, 0 );
	}
	Sys_FindClose ();
	Com_sprintf (name, sizeof(name), "%s/save/%s/*.sv2", FS_Gamedir (), savename);
	s = Sys_FindFirst(name, 0, 0 );
	while (s)
	{
		FS_RemoveFile(s);
		s = Sys_FindNext( 0, 0 );
	}
	Sys_FindClose ();
}
Exemplo n.º 2
0
void Sys_Mkfifo (const char *ospath, qFILE *f)
{
    FILE *fifo;
    int result;
    struct stat buf;

    /* if file already exists AND is a pipefile, remove it */
    if (!stat(ospath, &buf) && S_ISFIFO(buf.st_mode))
        FS_RemoveFile(ospath);

    result = mkfifo(ospath, 0600);
    if (result != 0)
        return;

    fifo = fopen(ospath, "w+");
    if (fifo) {
        const int fn = fileno(fifo);
        fcntl(fn, F_SETFL, O_NONBLOCK);
    }

    if (fifo) {
        f->f = fifo;
    } else {
        Com_Printf("WARNING: Could not create fifo pipe at %s.\n", ospath);
        f->f = NULL;
    }
}
Exemplo n.º 3
0
/*
* SV_Demo_Stop
*/
static void SV_Demo_Stop( bool cancel, bool silent )
{
	if( !svs.demo.file )
	{
		if( !silent ) {
			Com_Printf( "No server demo recording in progress\n" );
		}
		return;
	}

	if( cancel )
	{
		Com_Printf( "Canceled server demo recording: %s\n", svs.demo.filename );
	}
	else
	{
		SNAP_StopDemoRecording( svs.demo.file );

		Com_Printf( "Stopped server demo recording: %s\n", svs.demo.filename );
	}

	FS_FCloseFile( svs.demo.file );
	svs.demo.file = 0;

	if( cancel )
	{
		if( !FS_RemoveFile( svs.demo.tempname ) )
			Com_Printf( "Error: Failed to delete the temporary server demo file\n" );
	}
	else
	{
		// write some meta information about the match/demo
		SV_SetDemoMetaKeyValue( "hostname", sv.configstrings[CS_HOSTNAME] );
		SV_SetDemoMetaKeyValue( "localtime", va( "%u", svs.demo.localtime ) );
		SV_SetDemoMetaKeyValue( "multipov", "1" );
		SV_SetDemoMetaKeyValue( "duration", va( "%u", (int)ceil( svs.demo.duration/1000.0f ) ) );
		SV_SetDemoMetaKeyValue( "mapname", sv.configstrings[CS_MAPNAME] );
		SV_SetDemoMetaKeyValue( "gametype", sv.configstrings[CS_GAMETYPENAME] );
		SV_SetDemoMetaKeyValue( "levelname", sv.configstrings[CS_MESSAGE] );
		SV_SetDemoMetaKeyValue( "matchname", sv.configstrings[CS_MATCHNAME] );
		SV_SetDemoMetaKeyValue( "matchscore", sv.configstrings[CS_MATCHSCORE] );
		SV_SetDemoMetaKeyValue( "matchuuid", sv.configstrings[CS_MATCHUUID] );

		SNAP_WriteDemoMetaData( svs.demo.tempname, svs.demo.meta_data, svs.demo.meta_data_realsize );

		if( !FS_MoveFile( svs.demo.tempname, svs.demo.filename ) )
			Com_Printf( "Error: Failed to rename the server demo file\n" );
	}

	svs.demo.localtime = 0;
	svs.demo.basetime = svs.demo.duration = 0;

	SNAP_FreeClientFrames( &svs.demo.client );

	Mem_ZoneFree( svs.demo.filename );
	svs.demo.filename = NULL;
	Mem_ZoneFree( svs.demo.tempname );
	svs.demo.tempname = NULL;
}
Exemplo n.º 4
0
/*
* ML_Restart
* Restart map list stuff
*/
void ML_Restart( qboolean forcemaps )
{
    ML_Shutdown();
    if( forcemaps )
        FS_RemoveFile( MLIST_CACHE );
    FS_Rescan();
    ML_Init();
}
Exemplo n.º 5
0
/*
* TV_Upstream_StopDemoRecord
*/
void TV_Upstream_StopDemoRecord( upstream_t *upstream, qboolean silent, qboolean cancel )
{
	assert( upstream );

	if( !upstream->demo.recording )
	{
		if( !silent )
			Com_Printf( "Not recording a demo.\n" );
		return;
	}

	// finish up
	SNAP_StopDemoRecording( upstream->demo.filehandle );

	FS_FCloseFile( upstream->demo.filehandle );

	// cancel the demos
	if( cancel )
	{
		// remove the file that correspond to cls.demo.file
		if( !silent )
			Com_Printf( "Canceling demo: %s\n", upstream->demo.filename );
		if( !FS_RemoveFile( upstream->demo.tempname ) && !silent )
			Com_Printf( "Error canceling demo." );
	}
	else
	{
		// write some meta information about the match/demo
		TV_Upstream_SetDemoMetaKeyValue( upstream, "hostname", upstream->configstrings[CS_HOSTNAME] );
		TV_Upstream_SetDemoMetaKeyValue( upstream, "localtime", va( "%u", upstream->demo.localtime ) );
		TV_Upstream_SetDemoMetaKeyValue( upstream, "multipov", "1" );
		TV_Upstream_SetDemoMetaKeyValue( upstream, "duration", va( "%u", (int)ceil( upstream->demo.duration/1000.0f ) ) );
		TV_Upstream_SetDemoMetaKeyValue( upstream, "mapname", upstream->configstrings[CS_MAPNAME] );
		TV_Upstream_SetDemoMetaKeyValue( upstream, "gametype", upstream->configstrings[CS_GAMETYPENAME] );
		TV_Upstream_SetDemoMetaKeyValue( upstream, "levelname", upstream->configstrings[CS_MESSAGE] );
		TV_Upstream_SetDemoMetaKeyValue( upstream, "matchname", upstream->configstrings[CS_MATCHNAME] );
		TV_Upstream_SetDemoMetaKeyValue( upstream, "matchscore", upstream->configstrings[CS_MATCHSCORE] );
		TV_Upstream_SetDemoMetaKeyValue( upstream, "matchuuid", upstream->configstrings[CS_MATCHUUID] );

		SNAP_WriteDemoMetaData( upstream->demo.tempname, upstream->demo.meta_data, upstream->demo.meta_data_realsize );

		if( !FS_MoveFile( upstream->demo.tempname, upstream->demo.filename ) )
			Com_Printf( "Error: Failed to rename the demo file\n" );
	}

	if( !silent )
		Com_Printf( "Stopped demo: %s\n", upstream->demo.filename );

	upstream->demo.filehandle = 0; // file id

	Mem_ZoneFree( upstream->demo.filename );
	upstream->demo.filename = NULL;
	Mem_ZoneFree( upstream->demo.tempname );
	upstream->demo.tempname = NULL;

	upstream->demo.recording = qfalse;
	upstream->demo.autorecording = qfalse;
}
Exemplo n.º 6
0
/**
 * @brief Removes a user created team
 */
void GAME_TeamDelete_f (void)
{
	if (Cmd_Argc() != 2) {
		Com_Printf("Usage: %s <filename>\n", Cmd_Argv(0));
		return;
	}

	const char* team = Cmd_Argv(1);
	char buf[MAX_OSPATH];
	GAME_GetAbsoluteSavePath(buf, sizeof(buf));
	Q_strcat(buf, sizeof(buf), "%s", team);
	FS_RemoveFile(buf);
}
Exemplo n.º 7
0
/**
 * @note Both client and server can use this, and it will
 * do the appropriate things.
 */
void Com_Error (int code, const char* fmt, ...)
{
	va_list argptr;
	static char msg[MAXPRINTMSG];
	static bool recursive = false;

	if (recursive)
		Sys_Error("recursive error after: %s", msg);
	recursive = true;

	va_start(argptr, fmt);
	Q_vsnprintf(msg, sizeof(msg), fmt, argptr);
	va_end(argptr);

	switch (code) {
	case ERR_DISCONNECT:
		Com_Printf("%s\n", msg);
		CL_Drop();
		recursive = false;
		Com_Drop();
	case ERR_DROP:
		Com_Printf("********************\n");
		Com_Printf("ERROR: %s\n", msg);
		Com_Printf("********************\n");
		Sys_Backtrace();
		SV_Shutdown("Server crashed.", false);
		CL_Drop();
		recursive = false;
		Com_Drop();
	default:
		Com_Printf("%s\n", msg);
		SV_Shutdown("Server fatal crashed", false);

		/* send an receive net messages a last time */
		NET_Wait(0);

		FS_CloseFile(&logfile);
		if (pipefile.f != nullptr) {
			FS_CloseFile(&pipefile);
			FS_RemoveFile(va("%s/%s", FS_Gamedir(), pipefile.name));
		}

		CL_Shutdown();
		Qcommon_Shutdown();
		Sys_Error("Shutdown");
	}
}
Exemplo n.º 8
0
/*
* SNAP_WriteDemoMetaData
*/
void SNAP_WriteDemoMetaData( const char *filename, const char *meta_data, size_t meta_data_realsize )
{
	unsigned i;
	unsigned v;
	char tmpn[256];
	int filenum, filelen;
	msg_t msg;
	uint8_t msg_buffer[MAX_MSGLEN];
	void *compressed_msg;

	MSG_Init( &msg, msg_buffer, sizeof( msg_buffer ) );

	// write to a temp file
	v = 0;
	for( i = 0; filename[i]; i++ ) {
		v = ( v + i ) * 37 + tolower( filename[i] ); // case insensitivity
	}
	Q_snprintfz( tmpn, sizeof( tmpn ), "%u.tmp", v );

	if( FS_FOpenFile( tmpn, &filenum, FS_WRITE|SNAP_DEMO_GZ ) == -1 ) {
		return;
	}

	SNAP_DemoMetaDataMessage( &msg, meta_data, meta_data_realsize );
	SNAP_RecordDemoMetaDataMessage( filenum, &msg );

	// now open the original file in update mode and overwrite metadata

	// important note: we need to the load the temp file before closing it
	// because in the case of gz compression, closing the file may actually
	// write some data we don't want to copy
	filelen = FS_LoadFile( tmpn, &compressed_msg, NULL, 0 );

	if( compressed_msg ) {
		int origfile;

		if( FS_FOpenFile( filename, &origfile, FS_READ|FS_UPDATE ) != -1 ) {
			FS_Write( compressed_msg, filelen, origfile );
			FS_FCloseFile( origfile );
		}
		FS_FreeFile( compressed_msg );
	}

	FS_FCloseFile( filenum );

	FS_RemoveFile( tmpn );
}
Exemplo n.º 9
0
/* <2af4b> ../engine/hashpak.c:1678 */
void HPAK_CheckSize(char *pakname)
{
	char fullname[MAX_PATH];
	float maxSize;
	float actualSize;
	FileHandle_t hfile;

	maxSize = hpk_maxsize.value;
	if (!maxSize || pakname == NULL)
		return;

	if (maxSize < 0.0f)
	{
		Con_Printf("hpk_maxsize < 0, setting to 0\n");
		Cvar_DirectSet(&hpk_maxsize, "0");
		return;
	}

	Q_snprintf(fullname, ARRAYSIZE(fullname), "%s", pakname);
#ifdef REHLDS_FIXES
	fullname[ARRAYSIZE(fullname) - 1] = 0;
#endif // REHLDS_FIXES

	COM_DefaultExtension(fullname, HASHPAK_EXTENSION);
	COM_FixSlashes(fullname);

	actualSize = 0.0f;
	maxSize *= 1000000.0f;

	hfile = FS_Open(fullname, "rb");
	if (hfile)
	{
		actualSize = (float)FS_Size(hfile);
		FS_Close(hfile);
	}
	if (actualSize >= maxSize)
	{
		Con_Printf("Server: Size of %s > %f MB, deleting.\n", fullname, hpk_maxsize.value);
		Log_Printf("Server: Size of %s > %f MB, deleting.\n", fullname, hpk_maxsize.value);
		FS_RemoveFile(fullname, 0);
	}
}
Exemplo n.º 10
0
/**
 * Both client and server can use this, and it will
 * do the appropriate things.
 */
void Com_Quit (void)
{
#ifdef DEDICATED_ONLY
	Com_WriteConfigToFile("dedconfig.cfg");
#else
	Com_WriteConfigToFile("config.cfg");
#endif

	SV_Shutdown("Server quit.", false);
	SV_Clear();
	CL_Shutdown();

	/* send an receive net messages a last time */
	NET_Wait(0);
	FS_CloseFile(&logfile);
	if (pipefile.f != nullptr) {
		FS_CloseFile(&pipefile);
		FS_RemoveFile(va("%s/%s", FS_Gamedir(), pipefile.name));
	}
	Sys_Quit();
}
Exemplo n.º 11
0
/* <2afb5> ../engine/hashpak.c:1728 */
void HPAK_ValidatePak(char *fullpakname)
{
	hash_pack_header_t header;
	hash_pack_directory_t directory;
	hash_pack_entry_t *entry;
	char szFileName[MAX_PATH];
	FileHandle_t fp;

	byte *pData;
	byte md5[16];

	MD5Context_t ctx;

	HPAK_FlushHostQueue();
	fp = FS_Open(fullpakname, "rb");

	if (!fp)
		return;

	FS_Read(&header, sizeof(hash_pack_header_t), 1, fp);

	if (header.version != HASHPAK_VERSION || Q_strncmp(header.szFileStamp, "HPAK", sizeof(header.szFileStamp)) != 0)
	{
		Con_Printf("%s is not a PAK file, deleting\n", fullpakname);
		FS_Close(fp);
		FS_RemoveFile(fullpakname, 0);
		return;
	}

	FS_Seek(fp, header.nDirectoryOffset, FILESYSTEM_SEEK_HEAD);
	FS_Read(&directory, 4, 1, fp);

	if (directory.nEntries < 1 || (unsigned int)directory.nEntries > MAX_FILE_ENTRIES)
	{
		Con_Printf("ERROR: HPAK %s had bogus # of directory entries:  %i, deleting\n", fullpakname, directory.nEntries);
		FS_Close(fp);
		FS_RemoveFile(fullpakname, 0);
		return;
	}

	directory.p_rgEntries = (hash_pack_entry_t *)Mem_Malloc(sizeof(hash_pack_entry_t) * directory.nEntries);
	FS_Read(directory.p_rgEntries, sizeof(hash_pack_entry_t) * directory.nEntries, 1, fp);
	for (int nCurrent = 0; nCurrent < directory.nEntries; nCurrent++)
	{
		entry = &directory.p_rgEntries[nCurrent];
		COM_FileBase(entry->resource.szFileName, szFileName);

		if ((unsigned int)entry->nFileLength >= MAX_FILE_SIZE)
		{
			Con_Printf("Mismatched data in HPAK file %s, deleting\n", fullpakname);
			Con_Printf("Unable to MD5 hash data lump %i, size invalid:  %i\n", nCurrent + 1, entry->nFileLength);

			FS_Close(fp);
			FS_RemoveFile(fullpakname, 0);
			Mem_Free(directory.p_rgEntries);
			return;
		}

		pData = (byte *)Mem_Malloc(entry->nFileLength + 1);

		Q_memset(pData, 0, entry->nFileLength);
		FS_Seek(fp, entry->nOffset, FILESYSTEM_SEEK_HEAD);
		FS_Read(pData, entry->nFileLength, 1, fp);
		Q_memset(&ctx, 0, sizeof(MD5Context_t));

		MD5Init(&ctx);
		MD5Update(&ctx, pData, entry->nFileLength);
		MD5Final(md5, &ctx);

		if (pData)
			Mem_Free(pData);

		if (Q_memcmp(entry->resource.rgucMD5_hash, md5, sizeof(md5)) != 0)
		{
			Con_Printf("Mismatched data in HPAK file %s, deleting\n", fullpakname);
			FS_Close(fp);
			FS_RemoveFile(fullpakname, 0);
			Mem_Free(directory.p_rgEntries);
			return;
		}
	}
	FS_Close(fp);
	Mem_Free(directory.p_rgEntries);
}
Exemplo n.º 12
0
/**
 * @brief A download finished, find out what it was, whether there were any errors and
 * if so, how severe. If none, rename file and other such stuff.
 */
static void CL_FinishHTTPDownload (void)
{
	int messagesInQueue, i;
	CURLcode result;
	CURL *curl;
	long responseCode;
	double timeTaken, fileSize;
	char tempName[MAX_OSPATH];
	bool isFile;

	do {
		CURLMsg *msg = curl_multi_info_read(multi, &messagesInQueue);
		dlhandle_t *dl = NULL;

		if (!msg) {
			Com_Printf("CL_FinishHTTPDownload: Odd, no message for us...\n");
			return;
		}

		if (msg->msg != CURLMSG_DONE) {
			Com_Printf("CL_FinishHTTPDownload: Got some weird message...\n");
			continue;
		}

		curl = msg->easy_handle;

		/* curl doesn't provide reverse-lookup of the void * ptr, so search for it */
		for (i = 0; i < 4; i++) {
			if (cls.HTTPHandles[i].curl == curl) {
				dl = &cls.HTTPHandles[i];
				break;
			}
		}

		if (!dl)
			Com_Error(ERR_DROP, "CL_FinishHTTPDownload: Handle not found");

		/* we mark everything as done even if it errored to prevent multiple attempts. */
		dl->queueEntry->state = DLQ_STATE_DONE;

		/* filelist processing is done on read */
		if (dl->file)
			isFile = true;
		else
			isFile = false;

		if (isFile) {
			fclose(dl->file);
			dl->file = NULL;
		}

		/* might be aborted */
		if (pendingCount)
			pendingCount--;
		handleCount--;
		/* Com_Printf("finished dl: hc = %d\n", handleCount); */
		cls.downloadName[0] = 0;
		cls.downloadPosition = 0;

		result = msg->data.result;

		switch (result) {
		/* for some reason curl returns CURLE_OK for a 404... */
		case CURLE_HTTP_RETURNED_ERROR:
		case CURLE_OK:
			curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &responseCode);
			if (responseCode == 404) {
				const char *extension = Com_GetExtension(dl->queueEntry->ufoPath);
				if (extension != NULL && Q_streq(extension, "pk3"))
					downloadingPK3 = false;

				if (isFile)
					FS_RemoveFile(dl->filePath);
				Com_Printf("HTTP(%s): 404 File Not Found [%d remaining files]\n", dl->queueEntry->ufoPath, pendingCount);
				curl_easy_getinfo(curl, CURLINFO_SIZE_DOWNLOAD, &fileSize);
				if (fileSize > 512) {
					/* ick */
					isFile = false;
					result = CURLE_FILESIZE_EXCEEDED;
					Com_Printf("Oversized 404 body received (%d bytes), aborting HTTP downloading.\n", (int)fileSize);
				} else {
					curl_multi_remove_handle(multi, dl->curl);
					continue;
				}
			} else if (responseCode == 200) {
				if (!isFile && !abortDownloads)
					CL_ParseFileList(dl);
				break;
			}

			/* every other code is treated as fatal, fallthrough here */

		/* fatal error, disable http */
		case CURLE_COULDNT_RESOLVE_HOST:
		case CURLE_COULDNT_CONNECT:
		case CURLE_COULDNT_RESOLVE_PROXY:
			if (isFile)
				FS_RemoveFile(dl->filePath);
			Com_Printf("Fatal HTTP error: %s\n", curl_easy_strerror(result));
			curl_multi_remove_handle(multi, dl->curl);
			if (abortDownloads)
				continue;
			CL_CancelHTTPDownloads(true);
			continue;
		default:
			i = strlen(dl->queueEntry->ufoPath);
			if (Q_streq(dl->queueEntry->ufoPath + i - 4, ".pk3"))
				downloadingPK3 = false;
			if (isFile)
				FS_RemoveFile(dl->filePath);
			Com_Printf("HTTP download failed: %s\n", curl_easy_strerror(result));
			curl_multi_remove_handle(multi, dl->curl);
			continue;
		}

		if (isFile) {
			/* rename the temp file */
			Com_sprintf(tempName, sizeof(tempName), "%s/%s", FS_Gamedir(), dl->queueEntry->ufoPath);

			if (!FS_RenameFile(dl->filePath, tempName, false))
				Com_Printf("Failed to rename %s for some odd reason...", dl->filePath);

			/* a pk3 file is very special... */
			i = strlen(tempName);
			if (Q_streq(tempName + i - 4, ".pk3")) {
				FS_RestartFilesystem(NULL);
				CL_ReVerifyHTTPQueue();
				downloadingPK3 = false;
			}
		}

		/* show some stats */
		curl_easy_getinfo(curl, CURLINFO_TOTAL_TIME, &timeTaken);
		curl_easy_getinfo(curl, CURLINFO_SIZE_DOWNLOAD, &fileSize);

		/** @todo
		 * technically i shouldn't need to do this as curl will auto reuse the
		 * existing handle when you change the URL. however, the handleCount goes
		 * all weird when reusing a download slot in this way. if you can figure
		 * out why, please let me know. */
		curl_multi_remove_handle(multi, dl->curl);

		Com_Printf("HTTP(%s): %.f bytes, %.2fkB/sec [%d remaining files]\n",
			dl->queueEntry->ufoPath, fileSize, (fileSize / 1024.0) / timeTaken, pendingCount);
	} while (messagesInQueue > 0);

	if (handleCount == 0) {
		if (abortDownloads == HTTPDL_ABORT_SOFT)
			abortDownloads = HTTPDL_ABORT_NONE;
		else if (abortDownloads == HTTPDL_ABORT_HARD)
			cls.downloadServer[0] = 0;
	}

	/* done current batch, see if we have more to dl - maybe a .bsp needs downloaded */
	if (cls.state == ca_connected && !CL_PendingHTTPDownloads())
		CL_RequestNextDownload();
}
Exemplo n.º 13
0
/**
 * @brief Writes lines containing "bind key value"
 * @param[in] filename Path to print the keybinding too
 * @sa Com_WriteConfigToFile
 */
void Key_WriteBindings (const char* filename)
{
	int i;
	/* this gets true in case of an error */
	qboolean deleteFile = qfalse;
	qFILE f;
	int cnt = 0;

	OBJZERO(f);
	FS_OpenFile(filename, &f, FILE_WRITE);
	if (!f.f) {
		Com_Printf("Couldn't write %s.\n", filename);
		return;
	}

	FS_Printf(&f, "// generated by ufo, do not modify\n");
	FS_Printf(&f, "// If you want to know the keyname of a specific key - set in_debug cvar to 1 and press the key\n");
	FS_Printf(&f, "unbindallmenu\n");
	FS_Printf(&f, "unbindall\n");
	FS_Printf(&f, "unbindallbattle\n");
	/* failfast, stops loop for first occurred error in fprintf */
	for (i = 0; i < K_LAST_KEY && !deleteFile; i++)
		if (menuKeyBindings[i] && menuKeyBindings[i][0]) {
			if (FS_Printf(&f, "bindmenu %s \"%s\"\n", Key_KeynumToString(i), menuKeyBindings[i]) < 0)
				deleteFile = qtrue;
			cnt++;
		}
	for (i = 0; i < K_LAST_KEY && !deleteFile; i++)
		if (keyBindings[i] && keyBindings[i][0]) {
			if (FS_Printf(&f, "bind %s \"%s\"\n", Key_KeynumToString(i), keyBindings[i]) < 0)
				deleteFile = qtrue;
			cnt++;
		}
	for (i = 0; i < K_LAST_KEY && !deleteFile; i++)
		if (battleKeyBindings[i] && battleKeyBindings[i][0]) {
			if (FS_Printf(&f, "bindbattle %s \"%s\"\n", Key_KeynumToString(i), battleKeyBindings[i]) < 0)
				deleteFile = qtrue;
			cnt++;
		}

	for (i = 0; i < UI_GetKeyBindingCount(); i++) {
		const char *path;
		uiKeyBinding_t*binding = UI_GetKeyBindingByIndex (i);
		if (binding->node == NULL)
			continue;
		if (binding->property == NULL)
			path = va("%s", UI_GetPath(binding->node));
		else
			path = va("%s@%s", UI_GetPath(binding->node), binding->property->string);

		if (FS_Printf(&f, "bindui %s \"%s\"\n", Key_KeynumToString(binding->key), path) < 0)
			deleteFile = qtrue;
	}

	FS_CloseFile(&f);
	if (!deleteFile && cnt)
		Com_Printf("Wrote %s\n", filename);
	else
		/* error in writing the keys.cfg - remove the file again */
		FS_RemoveFile(va("%s/%s", FS_Gamedir(), filename));
}
Exemplo n.º 14
0
/*
* SV_Demo_Purge_f
* 
* Removes the server demo files
*/
void SV_Demo_Purge_f( void )
{
	char *buffer;
	char *p, *s, num[8];
	char path[256];
	size_t extlen, length, bufSize;
	unsigned int i, numdemos, numautodemos, maxautodemos;

	if( Cmd_Argc() > 2 )
	{
		Com_Printf( "Usage: serverrecordpurge [maxautodemos]\n" );
		return;
	}

	maxautodemos = 0;
	if( Cmd_Argc() == 2 )
		maxautodemos = atoi( Cmd_Argv( 1 ) );

	numdemos = FS_GetFileListExt( SV_DEMO_DIR, APP_DEMO_EXTENSION_STR, NULL, &bufSize, 0, 0 );
	if( !numdemos )
		return;

	extlen = strlen( APP_DEMO_EXTENSION_STR );
	buffer = Mem_TempMalloc( bufSize );
	FS_GetFileList( SV_DEMO_DIR, APP_DEMO_EXTENSION_STR, buffer, bufSize, 0, 0 );

	numautodemos = 0;
	s = buffer;
	for( i = 0; i < numdemos; i++, s += length + 1 )
	{
		length = strlen( s );
		if( length < strlen( "_auto9999" ) + extlen )
			continue;

		p = s + length - strlen( "_auto9999" ) - extlen;
		if( strncmp( p, "_auto", strlen( "_auto" ) ) )
			continue;

		p += strlen( "_auto" );
		Q_snprintfz( num, sizeof( num ), "%04i", atoi( p ) );
		if( strncmp( p, num, 4 ) )
			continue;

		numautodemos++;
	}

	if( numautodemos <= maxautodemos )
	{
		Mem_TempFree( buffer );
		return;
	}

	s = buffer;
	for( i = 0; i < numdemos; i++, s += length + 1 )
	{
		length = strlen( s );
		if( length < strlen( "_auto9999" ) + extlen )
			continue;

		p = s + length - strlen( "_auto9999" ) - extlen;
		if( strncmp( p, "_auto", strlen( "_auto" ) ) )
			continue;

		p += strlen( "_auto" );
		Q_snprintfz( num, sizeof( num ), "%04i", atoi( p ) );
		if( strncmp( p, num, 4 ) )
			continue;

		Q_snprintfz( path, sizeof( path ), "%s/%s", SV_DEMO_DIR, s );
		Com_Printf( "Removing old autorecord demo: %s\n", path );
		if( !FS_RemoveFile( path ) )
		{
			Com_Printf( "Error, couldn't remove file: %s\n", path );
			continue;
		}

		if( --numautodemos == maxautodemos )
			break;
	}

	Mem_TempFree( buffer );
}