diff --git a/src/sbbs3/userdat.c b/src/sbbs3/userdat.c
index b2ff17570c53ec1c02d26c7d5eef6407c9c655f8..3f5e8e88580fca81501b410bc0b25b508022c5a9 100644
--- a/src/sbbs3/userdat.c
+++ b/src/sbbs3/userdat.c
@@ -1002,6 +1002,88 @@ int DLLCALL putsmsg(scfg_t* cfg, int usernumber, char *strin)
 	return(0);
 }
 
+/****************************************************************************/
+/* Returns any short messages waiting for user number, buffer must be freed */
+/****************************************************************************/
+char* DLLCALL getsmsg(scfg_t* cfg, int usernumber)
+{
+	char	str[MAX_PATH+1], HUGE16 *buf;
+	int		i;
+    int		file;
+    long	length;
+	node_t	node;
+
+	sprintf(str,"%smsgs/%4.4u.msg",cfg->data_dir,usernumber);
+	if(flength(str)<1L)
+		return(NULL);
+	if((file=nopen(str,O_RDWR))==-1)
+		return(NULL);
+	length=filelength(file);
+	if((buf=(char *)malloc(length+1))==NULL) {
+		close(file);
+		return(NULL);
+	}
+	if(read(file,buf,length)!=length) {
+		close(file);
+		free(buf);
+		return(NULL);
+	}
+	chsize(file,0L);
+	close(file);
+	buf[length]=0;
+
+	for(i=1;i<=cfg->sys_nodes;i++) {	/* clear msg waiting flag */
+		getnodedat(cfg,i,&node,NULL);
+		if(node.useron==usernumber
+			&& (node.status==NODE_INUSE || node.status==NODE_QUIET)
+			&& node.misc&NODE_MSGW) {
+			getnodedat(cfg,i,&node,&file);
+			node.misc&=~NODE_MSGW;
+			putnodedat(cfg,i,&node,file); 
+		} 
+	}
+
+	return(buf);	/* caller must free */
+}
+
+char* DLLCALL getnmsg(scfg_t* cfg, int node_num)
+{
+	char	str[MAX_PATH+1];
+	char*	buf;
+	int		file;
+	long	length;
+	node_t	node;
+
+	getnodedat(cfg,node_num,&node,&file);
+	node.misc&=~NODE_NMSG;          /* clear the NMSG flag */
+	putnodedat(cfg,node_num,&node,file);
+
+	sprintf(str,"%smsgs/n%3.3u.msg",cfg->data_dir,node_num);
+	if(flength(str)<1L)
+		return(NULL);
+	if((file=nopen(str,O_RDWR))==-1)
+		return(NULL); 
+	length=filelength(file);
+	if(!length) {
+		close(file);
+		return(NULL); 
+	}
+	if((buf=(char *)malloc(length+1))==NULL) {
+		close(file);
+		return(NULL); 
+	}
+	if(read(file,buf,length)!=length) {
+		close(file);
+		free(buf);
+		return(NULL);
+	}
+	chsize(file,0L);
+	close(file);
+	buf[length]=0;
+
+	return(buf);	/* caller must free */
+}
+
 /****************************************************************************/
 /* Creates a short message for node 'num' that contains 'strin'             */
 /****************************************************************************/
diff --git a/src/sbbs3/userdat.h b/src/sbbs3/userdat.h
index df42e1afb95515fcebc1d66ba4532b977261876d..a846814858cb4846d1b0ba29564866829804be89 100644
--- a/src/sbbs3/userdat.h
+++ b/src/sbbs3/userdat.h
@@ -88,7 +88,9 @@ DLLEXPORT void	DLLCALL printnodedat(scfg_t* cfg, uint number, node_t* node);
 DLLEXPORT void	DLLCALL packchatpass(char *pass, node_t* node);
 DLLEXPORT char* DLLCALL unpackchatpass(char *pass, node_t* node);
 
+DLLEXPORT char* DLLCALL getsmsg(scfg_t* cfg, int usernumber);
 DLLEXPORT int	DLLCALL putsmsg(scfg_t* cfg, int usernumber, char *strin);
+DLLEXPORT char* DLLCALL getnmsg(scfg_t* cfg, int node_num);
 DLLEXPORT int	DLLCALL putnmsg(scfg_t* cfg, int num, char *strin);
 
 DLLEXPORT uint	DLLCALL userdatdupe(scfg_t* cfg, uint usernumber, uint offset, uint datlen, char *dat