From 512fae4c255de2428bfa96a26ca88acfd896d29a Mon Sep 17 00:00:00 2001
From: Nicholas Hastings <nshastings@gmail.com>
Date: Wed, 8 Oct 2014 14:50:55 -0700
Subject: [PATCH] Fix crash on Windows when dumping admin cache to file.

---
 core/logic/AdminCache.cpp   | 12 +++++++++++-
 core/logic/AdminCache.h     |  2 +-
 core/logic/common_logic.cpp |  4 ++--
 core/logic/intercom.h       |  2 +-
 core/sm_srvcmds.cpp         |  8 +-------
 5 files changed, 16 insertions(+), 12 deletions(-)

diff --git a/core/logic/AdminCache.cpp b/core/logic/AdminCache.cpp
index eaf6ab43..e88a722a 100644
--- a/core/logic/AdminCache.cpp
+++ b/core/logic/AdminCache.cpp
@@ -1762,7 +1762,7 @@ void iterator_group_grp_override(FILE *fp, const char *key, OverrideRule rule)
 	fprintf(fp, "\t\t\t\"@%s\"\t\t\"%s\"\n", key, str);
 }
 
-void AdminCache::DumpCache(FILE *fp)
+bool AdminCache::DumpCache(const char *filename)
 {
 	int *itable;
 	AdminId aid;
@@ -1771,6 +1771,12 @@ void AdminCache::DumpCache(FILE *fp)
 	unsigned int num;
 	AdminUser *pAdmin;
 	AdminGroup *pGroup;
+	
+	FILE *fp;
+	if ((fp = fopen(filename, "wt")) == NULL)
+	{
+		return false;
+	}
 
 	fprintf(fp, "\"Groups\"\n{\n");
 	
@@ -1901,6 +1907,10 @@ void AdminCache::DumpCache(FILE *fp)
 	for (FlagMap::iterator iter = m_CmdOverrides.iter(); !iter.empty(); iter.next())
 		iterator_glob_basic_override(fp, iter->key.chars(), iter->value);
 	fprintf(fp, "}\n");
+	
+	fclose(fp);
+	
+	return true;
 }
 
 AdminGroup *AdminCache::GetGroup(GroupId gid)
diff --git a/core/logic/AdminCache.h b/core/logic/AdminCache.h
index 0254cb85..0cdd5859 100644
--- a/core/logic/AdminCache.h
+++ b/core/logic/AdminCache.h
@@ -183,7 +183,7 @@ public: //IAdminSystem
 	bool IsValidAdmin(AdminId id);
 	bool CheckClientCommandAccess(int client, const char *cmd, FlagBits cmdflags);
 public:
-	void DumpCache(FILE *fp);
+	bool DumpCache(const char *filename);
 	AdminGroup *GetGroup(GroupId gid);
 	AdminUser *GetUser(AdminId id);
 	const char *GetString(int idx);
diff --git a/core/logic/common_logic.cpp b/core/logic/common_logic.cpp
index 438e9097..d58864ee 100644
--- a/core/logic/common_logic.cpp
+++ b/core/logic/common_logic.cpp
@@ -108,9 +108,9 @@ static void DumpHandles(void (*dumpfn)(const char *fmt, ...))
 	g_HandleSys.Dump(dumpfn);
 }
 
-static void DumpAdminCache(FILE *f)
+static bool DumpAdminCache(const char *filename)
 {
-	g_Admins.DumpCache(f);
+	return g_Admins.DumpCache(filename);
 }
 
 static void RegisterProfiler(IProfilingTool *tool)
diff --git a/core/logic/intercom.h b/core/logic/intercom.h
index ec6223e8..94c1bc22 100644
--- a/core/logic/intercom.h
+++ b/core/logic/intercom.h
@@ -350,7 +350,7 @@ struct sm_logic_t
 	void			(*GenerateError)(IPluginContext *, cell_t, int, const char *, ...);
 	void			(*AddNatives)(sp_nativeinfo_t *natives);
 	void			(*DumpHandles)(void (*dumpfn)(const char *fmt, ...));
-	void			(*DumpAdminCache)(FILE *);
+	bool			(*DumpAdminCache)(const char *filename);
 	void            (*RegisterProfiler)(IProfilingTool *tool);
 	IScriptManager	*scripts;
 	IShareSys		*sharesys;
diff --git a/core/sm_srvcmds.cpp b/core/sm_srvcmds.cpp
index e1dd46b1..cf9355e2 100644
--- a/core/sm_srvcmds.cpp
+++ b/core/sm_srvcmds.cpp
@@ -424,21 +424,15 @@ CON_COMMAND(sm_reload_translations, "Reparses all loaded translation files")
 
 CON_COMMAND(sm_dump_admcache, "Dumps the admin cache for debugging")
 {
-	FILE *fp;
 	char buffer[PLATFORM_MAX_PATH];
-
 	g_SourceMod.BuildPath(Path_SM, buffer, sizeof(buffer), "data/admin_cache_dump.txt");
 
-	if ((fp = fopen(buffer, "wt")) == NULL)
+	if (!logicore.DumpAdminCache(buffer))
 	{
 		g_RootMenu.ConsolePrint("Could not open file for writing: %s", buffer);
 		return;
 	}
 
-	logicore.DumpAdminCache(fp);
-
 	g_RootMenu.ConsolePrint("Admin cache dumped to: %s", buffer);
-
-	fclose(fp);
 }