diff --git a/src/sbbs3/data_ovl.cpp b/src/sbbs3/data_ovl.cpp
index 039c632dcc5ff96a7bb06c368b6685354065cc62..6fd173ac2abb69d5f8294e278230bc62597bdc1c 100644
--- a/src/sbbs3/data_ovl.cpp
+++ b/src/sbbs3/data_ovl.cpp
@@ -43,8 +43,19 @@ void sbbs_t::getmsgptrs()
 
 void sbbs_t::putmsgptrs()
 {
-	if(!::putmsgptrs(&cfg,&useron,subscan))
-		errormsg(WHERE, ERR_WRITE, "message pointers", 0);
+	if(useron.number == 0 || useron.rest&FLAG('G'))
+		return;
+	char path[MAX_PATH + 1];
+	msgptrs_filename(&cfg, useron.number, path, sizeof path);
+	const uint access = O_RDWR | O_CREAT | O_TEXT;
+	FILE* fp = fnopen(NULL, path, access);
+	if (fp == NULL) {
+		errormsg(WHERE, ERR_OPEN, path, access);
+	} else {
+		if(!putmsgptrs_fp(&cfg,&useron,subscan, fp))
+			errormsg(WHERE, ERR_WRITE, "message pointers", 0);
+		fclose(fp);
+	}
 }
 
 void sbbs_t::reinit_msg_ptrs()
diff --git a/src/sbbs3/userdat.c b/src/sbbs3/userdat.c
index f62cc873bc0adbf24df438ad8af958ac3aaf9bc3..9c7c2188c5f8862d5876fd62d1a75e0aca60208a 100644
--- a/src/sbbs3/userdat.c
+++ b/src/sbbs3/userdat.c
@@ -56,6 +56,12 @@ char* userdat_filename(scfg_t* cfg, char* path, size_t size)
 	return path;
 }
 
+char* msgptrs_filename(scfg_t* cfg, unsigned user_number, char* path, size_t size)
+{
+	safe_snprintf(path, size, "%suser/%4.4u.subs", cfg->data_dir, user_number);
+	return path;
+}
+
 /****************************************************************************/
 /****************************************************************************/
 void split_userdat(char *userdat, char* field[])
@@ -3973,7 +3979,7 @@ bool getmsgptrs(scfg_t* cfg, user_t* user, subscan_t* subscan, void (*progress)(
 		return initmsgptrs(cfg, subscan, cfg->guest_msgscan_init, progress, cbdata);
 
 	/* New way: */
-	SAFEPRINTF2(path,"%suser/%4.4u.subs", cfg->data_dir, user->number);
+	msgptrs_filename(cfg, user->number, path, sizeof path);
 	FILE* fp = fnopen(NULL, path, O_RDONLY|O_TEXT);
 	if (fp != NULL) {
 		str_list_t ini = iniReadFile(fp);
@@ -4032,12 +4038,30 @@ bool getmsgptrs(scfg_t* cfg, user_t* user, subscan_t* subscan, void (*progress)(
 }
 
 /****************************************************************************/
-/* Writes to data/user/####.subs the msgptr array for the current user		*/
-/* Pass usernumber value of 0 to indicate "Guest" login						*/
+/* Writes to data/user/####.subs the msgptr array for the specified user	*/
 /****************************************************************************/
 bool putmsgptrs(scfg_t* cfg, user_t* user, subscan_t* subscan)
 {
 	char		path[MAX_PATH+1];
+
+	if (user->number==0 || (user->rest&FLAG('G')))	/* Guest */
+		return true;
+
+	msgptrs_filename(cfg, user->number, path, sizeof path);
+	FILE* fp = fnopen(NULL, path, O_RDWR|O_CREAT|O_TEXT);
+	if (fp == NULL)
+		return false;
+	bool result = putmsgptrs_fp(cfg, user, subscan, fp);
+	fclose(fp);
+
+	return result;
+}
+
+/****************************************************************************/
+/* Writes to FILE* the msgptr array for the specified user					*/
+/****************************************************************************/
+bool putmsgptrs_fp(scfg_t* cfg, user_t* user, subscan_t* subscan, FILE* fp)
+{
 	int			i;
 	time_t		now = time(NULL);
 	bool		result = true;
@@ -4046,10 +4070,6 @@ bool putmsgptrs(scfg_t* cfg, user_t* user, subscan_t* subscan)
 		return(true);
 
 	fixmsgptrs(cfg, subscan);
-	SAFEPRINTF2(path,"%suser/%4.4u.subs", cfg->data_dir, user->number);
-	FILE* fp = fnopen(NULL, path, O_RDWR|O_CREAT|O_TEXT);
-	if (fp == NULL)
-		return false;
 	str_list_t new = strListInit();
 	str_list_t ini = iniReadFile(fp);
 	ini_style_t ini_style = { .key_prefix = "\t", .section_separator = "" };
@@ -4077,7 +4097,6 @@ bool putmsgptrs(scfg_t* cfg, user_t* user, subscan_t* subscan)
 		result = iniWriteFile(fp, new);
 	strListFree(&new);
 	iniFreeStringList(ini);
-	fclose(fp);
 
 	return result;
 }
diff --git a/src/sbbs3/userdat.h b/src/sbbs3/userdat.h
index bad512ecfd725fb6d0318810040d426a2a247947..137b3bf14cf25881aa2bf7b5c378f4546bf9868d 100644
--- a/src/sbbs3/userdat.h
+++ b/src/sbbs3/userdat.h
@@ -22,6 +22,8 @@
 #ifndef _USERDAT_H
 #define _USERDAT_H
 
+#include <stdio.h>		// FILE
+
 #include "scfgdefs.h"   /* scfg_t */
 #include "client.h"		/* client_t */
 #include "link_list.h"
@@ -38,6 +40,7 @@ extern "C" {
 #endif
 
 DLLEXPORT char*	userdat_filename(scfg_t*, char*, size_t);
+DLLEXPORT char*	msgptrs_filename(scfg_t*, unsigned user_number, char*, size_t);
 DLLEXPORT int	openuserdat(scfg_t*, bool for_modify);
 DLLEXPORT bool	seekuserdat(int file, unsigned user_number);
 DLLEXPORT int	closeuserdat(int file);
@@ -164,6 +167,7 @@ DLLEXPORT bool	user_set_time_property(scfg_t*, unsigned user_number, const char*
 DLLEXPORT bool	newmsgs(smb_t*, time_t);
 DLLEXPORT bool	getmsgptrs(scfg_t*, user_t*, subscan_t*, void (*progress)(void*, int, int), void* cbdata);
 DLLEXPORT bool	putmsgptrs(scfg_t*, user_t*, subscan_t*);
+DLLEXPORT bool	putmsgptrs_fp(scfg_t*, user_t*, subscan_t*, FILE*);
 DLLEXPORT bool	fixmsgptrs(scfg_t*, subscan_t*);
 DLLEXPORT bool	initmsgptrs(scfg_t*, subscan_t*, unsigned days, void (*progress)(void*, int, int), void* cbdata);