From bcc17e369e8bc13ea6cd64433293f6fe864483fe Mon Sep 17 00:00:00 2001
From: "Rob Swindell (on Windows 11)" <rob@synchro.net>
Date: Fri, 20 Sep 2024 00:01:22 -0700
Subject: [PATCH] Store debug information in dsts.ini to help solve cause of
 issue #791

This should help identify the function(s) used when the corruption occurs.
---
 src/sbbs3/getstats.c | 29 +++++++++++++++++++++++------
 src/sbbs3/getstats.h |  2 +-
 src/sbbs3/logon.cpp  |  4 ++--
 src/sbbs3/main.cpp   |  2 +-
 src/sbbs3/userdat.c  |  2 +-
 5 files changed, 28 insertions(+), 11 deletions(-)

diff --git a/src/sbbs3/getstats.c b/src/sbbs3/getstats.c
index 21bce3932a..f4db8a751c 100644
--- a/src/sbbs3/getstats.c
+++ b/src/sbbs3/getstats.c
@@ -23,6 +23,7 @@
 #include "nopen.h"
 #include "smblib.h"
 #include "ini_file.h"
+#include "datewrap.h"
 #include "xpendian.h"
 #include "xpdatetime.h"
 #include "scfglib.h"
@@ -210,7 +211,23 @@ static void settotals(str_list_t* ini, const char* section, const totals_t* stat
 
 /****************************************************************************/
 /****************************************************************************/
-bool fwrite_dstats(FILE* fp, const stats_t* stats)
+static bool write_dstats(FILE* fp, str_list_t* ini, const char* function)
+{
+	time_t now = time(NULL);
+	char tstr[32];
+	char value[INI_MAX_VALUE_LEN + 1];
+	const char* key = "LastWrite";
+	char* last = iniGetString(*ini, ROOT_SECTION, key, NULL, value);
+	if(last != NULL)
+		iniSetString(ini, ROOT_SECTION, "PrevLastWrite", last, NULL);
+	safe_snprintf(value, sizeof value, "%.24s by %s", ctime_r(&now, tstr), function);
+	iniSetString(ini, ROOT_SECTION, key, value, NULL);
+	return iniWriteFile(fp, *ini);
+}
+
+/****************************************************************************/
+/****************************************************************************/
+bool fwrite_dstats(FILE* fp, const stats_t* stats, const char* function)
 {
 	bool result;
 	str_list_t ini;
@@ -222,7 +239,7 @@ bool fwrite_dstats(FILE* fp, const stats_t* stats)
 	iniSetDateTime(&ini, NULL, strStatsDate, /* include_time: */false, stats->date, /* style: */NULL);
 	settotals(&ini, strStatsToday, &stats->today);
 	settotals(&ini, strStatsTotal, &stats->total);
-	result = iniWriteFile(fp, ini);
+	result = write_dstats(fp, &ini, function);
 	iniFreeStringList(ini);
 
 	return result;
@@ -238,7 +255,7 @@ bool putstats(scfg_t* cfg, uint node, const stats_t* stats)
 	FILE* fp = fopen_dstats(cfg, node, /* for_write: */true);
 	if(fp == NULL)
 		return false;
-	result = fwrite_dstats(fp, stats);
+	result = fwrite_dstats(fp, stats, __FUNCTION__);
 	iniCloseFile(fp);
 	return result;
 }
@@ -376,7 +393,7 @@ static bool inc_xfer_stats(scfg_t* cfg, uint node, uint files, uint64_t bytes, c
 	ini = iniReadFile(fp);
 	inc_xfer_stat_keys(&ini, strStatsTotal, files, bytes, files_key, bytes_key);
 	inc_xfer_stat_keys(&ini, strStatsToday, files, bytes, files_key, bytes_key);
-	result = iniWriteFile(fp, ini);
+	result = write_dstats(fp, &ini, __FUNCTION__);
 	fclose_dstats(fp);
 	iniFreeStringList(ini);
 
@@ -413,7 +430,7 @@ static bool inc_post_stat(scfg_t* cfg, uint node, uint count)
 	ini = iniReadFile(fp);
 	iniSetUInteger(&ini, strStatsToday, strStatsPosts, iniGetUInteger(ini, strStatsToday, strStatsPosts, 0) + count, /* style: */NULL);
 	iniSetUInteger(&ini, strStatsTotal, strStatsPosts, iniGetUInteger(ini, strStatsTotal, strStatsPosts, 0) + count, /* style: */NULL);
-	result = iniWriteFile(fp, ini);
+	result = write_dstats(fp, &ini, __FUNCTION__);
 	fclose_dstats(fp);
 	iniFreeStringList(ini);
 
@@ -441,7 +458,7 @@ static bool inc_email_stat(scfg_t* cfg, uint node, uint count, bool feedback)
 	ini = iniReadFile(fp);
 	iniSetUInteger(&ini, strStatsToday, key, iniGetUInteger(ini, strStatsToday, key, 0) + count, /* style: */NULL);
 	iniSetUInteger(&ini, strStatsTotal, key, iniGetUInteger(ini, strStatsTotal, key, 0) + count, /* style: */NULL);
-	result = iniWriteFile(fp, ini);
+	result = write_dstats(fp, &ini, __FUNCTION__);
 	fclose_dstats(fp);
 	iniFreeStringList(ini);
 
diff --git a/src/sbbs3/getstats.h b/src/sbbs3/getstats.h
index 79a0a4ab50..8390caeca6 100644
--- a/src/sbbs3/getstats.h
+++ b/src/sbbs3/getstats.h
@@ -35,7 +35,7 @@ DLLEXPORT FILE*		fopen_cstats(scfg_t*, uint node, bool for_write);
 DLLEXPORT bool		fclose_cstats(FILE*);
 DLLEXPORT bool		fclose_dstats(FILE*);
 DLLEXPORT bool		fread_dstats(FILE*, stats_t*);
-DLLEXPORT bool		fwrite_dstats(FILE*, const stats_t*);
+DLLEXPORT bool		fwrite_dstats(FILE*, const stats_t*, const char* function);
 DLLEXPORT bool		fwrite_cstats(FILE*, const stats_t*);
 DLLEXPORT void		parse_cstats(str_list_t, stats_t*);
 DLLEXPORT bool		getstats(scfg_t*, uint node, stats_t*);
diff --git a/src/sbbs3/logon.cpp b/src/sbbs3/logon.cpp
index e6a8f09e43..78358189f0 100644
--- a/src/sbbs3/logon.cpp
+++ b/src/sbbs3/logon.cpp
@@ -657,7 +657,7 @@ uint sbbs_t::logonstats()
 			fwrite_cstats(csts, &stats);
 			fclose_cstats(csts);
 			rolloverstats(&stats);
-			fwrite_dstats(dsts, &stats);
+			fwrite_dstats(dsts, &stats, __FUNCTION__);
 			fclose_dstats(dsts);
 		} 
 	}
@@ -680,7 +680,7 @@ uint sbbs_t::logonstats()
 		fread_dstats(fp, &stats);
 		stats.today.logons++;
 		stats.total.logons++;
-		fwrite_dstats(fp, &stats);
+		fwrite_dstats(fp, &stats, __FUNCTION__);
 		fclose_dstats(fp);
 	}
 
diff --git a/src/sbbs3/main.cpp b/src/sbbs3/main.cpp
index 6cb7daac40..34b3f110e4 100644
--- a/src/sbbs3/main.cpp
+++ b/src/sbbs3/main.cpp
@@ -4382,7 +4382,7 @@ void sbbs_t::logoffstats()
 		if(fread_dstats(fp, &stats)) {
 			stats.total.timeon += minutes_used;
 			stats.today.timeon += minutes_used;
-			fwrite_dstats(fp, &stats);
+			fwrite_dstats(fp, &stats, __FUNCTION__);
 		}
 		fclose_dstats(fp);
 	}
diff --git a/src/sbbs3/userdat.c b/src/sbbs3/userdat.c
index 37b126f6cd..c5a7f27504 100644
--- a/src/sbbs3/userdat.c
+++ b/src/sbbs3/userdat.c
@@ -3303,7 +3303,7 @@ int newuserdat(scfg_t* cfg, user_t* user)
 		if(fread_dstats(fp, &stats)) {
 			stats.today.nusers++;
 			stats.total.nusers++;
-			fwrite_dstats(fp, &stats);
+			fwrite_dstats(fp, &stats, __FUNCTION__);
 		}
 		fclose_dstats(fp);
 	}
-- 
GitLab