diff --git a/src/sbbs3/getnode.cpp b/src/sbbs3/getnode.cpp
index 8f65c874d790c6c960652b7635894c1190751cee..cfb28ba38b0efc8109aefe3ebd4ff6f8ae8c76ae 100644
--- a/src/sbbs3/getnode.cpp
+++ b/src/sbbs3/getnode.cpp
@@ -342,9 +342,7 @@ int sbbs_t::getnodeext(uint number, char *ext)
 /****************************************************************************/
 int sbbs_t::getsmsg(int usernumber, bool clearline)
 {
-	char	str[MAX_PATH+1], *buf;
-    int		file;
-    long	length;
+	char	*buf;
 	node_t	node;
 	int		i;
 
@@ -360,35 +358,14 @@ int sbbs_t::getsmsg(int usernumber, bool clearline)
 		} 
 	}
 
-	SAFEPRINTF2(str,"%smsgs/%4.4u.msg",cfg.data_dir,usernumber);
-	if(flength(str)<1L)
-		return(0);
-	if((file=nopen(str,O_RDWR))==-1) {
-		errormsg(WHERE,ERR_OPEN,str,O_RDWR);
-		return(errno); 
-	}
-	length=(long)filelength(file);
-	if((buf=(char *)malloc(length+1))==NULL) {
-		close(file);
-		errormsg(WHERE,ERR_ALLOC,str,length+1);
-		return(-1); 
-	}
-	if(lread(file,buf,length)!=length) {
-		close(file);
-		free(buf);
-		errormsg(WHERE,ERR_READ,str,length);
-		return(errno); 
-	}
-	chsize(file,0L);
-	close(file);
-	buf[length]=0;
+	if((buf = readsmsg(&cfg, usernumber)) == NULL)
+		return -1;
 	getnodedat(cfg.node_num,&thisnode,0);
 	if(clearline)
 		this->clearline();
 	else
 		if(column)
 			CRLF;
-	strip_invalid_attr(buf);
 	putmsg(buf,P_NOATCODES);
 	free(buf);
 
diff --git a/src/sbbs3/userdat.c b/src/sbbs3/userdat.c
index 23ea41c2fd11ffee47c06d52d861013e9dad0a37..b24030f99c503685cc9ae40a94fcde42b6ec3f70 100644
--- a/src/sbbs3/userdat.c
+++ b/src/sbbs3/userdat.c
@@ -1416,10 +1416,8 @@ int putsmsg(scfg_t* cfg, int usernumber, char *strin)
 /****************************************************************************/
 char* getsmsg(scfg_t* cfg, int usernumber)
 {
-	char	str[MAX_PATH+1], *buf;
 	int		i;
     int		file = -1;
-    long	length;
 	node_t	node;
 
 	if(!VALID_CFG(cfg) || usernumber<1)
@@ -1438,6 +1436,21 @@ char* getsmsg(scfg_t* cfg, int usernumber)
 	}
 	CLOSE_OPEN_FILE(file);
 
+	return readsmsg(cfg, usernumber);
+}
+
+/****************************************************************************/
+/* Returns any short messages waiting for user number, buffer must be freed */
+/****************************************************************************/
+char* readsmsg(scfg_t* cfg, int usernumber)
+{
+	char	str[MAX_PATH+1], *buf;
+    int		file;
+    long	length;
+
+	if(!VALID_CFG(cfg) || usernumber<1)
+		return(NULL);
+
 	SAFEPRINTF2(str,"%smsgs/%4.4u.msg",cfg->data_dir,usernumber);
 	if(flength(str)<1L)
 		return(NULL);
@@ -1458,6 +1471,13 @@ char* getsmsg(scfg_t* cfg, int usernumber)
 	buf[length]=0;
 	strip_invalid_attr(buf);
 
+	SAFEPRINTF2(str, "%smsgs/%4.4u.last.msg", cfg->data_dir, usernumber);
+	backup(str, 19, /* rename: */true);
+	if((file = nopen(str, O_WRONLY|O_CREAT|O_APPEND)) != -1) {
+		(void)write(file, buf, length);
+		close(file);
+	}
+
 	return(buf);	/* caller must free */
 }
 
@@ -2803,14 +2823,14 @@ int newuserdat(scfg_t* cfg, user_t* user)
 	delfiles(str,tmp, /* keep: */0);
 	SAFEPRINTF(str,"%suser",cfg->data_dir);
 	delfiles(str,tmp, /* keep: */0);
+	SAFEPRINTF(str,"%smsgs",cfg->data_dir);
+	delfiles(str,tmp, /* keep: */0);
 	SAFEPRINTF2(str,"%suser/%04u",cfg->data_dir,user->number);
 	delfiles(str,ALLFILES, /* keep: */0);
 	rmdir(str);
 
 	SAFEPRINTF2(str,"%suser/ptrs/%04u.ixb",cfg->data_dir,user->number); /* msg ptrs */
 	remove(str);
-	SAFEPRINTF2(str,"%smsgs/%04u.msg",cfg->data_dir,user->number); /* delete short msg */
-	remove(str);
 
 	/* Update daily statistics database (for system and node) */
 
diff --git a/src/sbbs3/userdat.h b/src/sbbs3/userdat.h
index b3aaed0fe17aaedcce04b65247d95d8781145ffb..0537f3e97de96ce0cae26ac0f300733eef0b4733 100644
--- a/src/sbbs3/userdat.h
+++ b/src/sbbs3/userdat.h
@@ -69,6 +69,7 @@ DLLEXPORT void	printnodedat(scfg_t*, uint number, node_t* node);
 DLLEXPORT int	is_user_online(scfg_t*, uint usernumber);
 DLLEXPORT void	packchatpass(char *pass, node_t* node);
 DLLEXPORT char* unpackchatpass(char *pass, node_t* node);
+DLLEXPORT char* readsmsg(scfg_t*, int usernumber);
 DLLEXPORT char* getsmsg(scfg_t*, int usernumber);
 DLLEXPORT int	putsmsg(scfg_t*, int usernumber, char *strin);
 DLLEXPORT char* getnmsg(scfg_t*, int node_num);