diff --git a/src/sbbs3/getmsg.cpp b/src/sbbs3/getmsg.cpp
index 6562e7335a4b88483fab8e251efc83805f7477fb..6f58f39e4d8ab9edca786a2621effe087550f7bd 100644
--- a/src/sbbs3/getmsg.cpp
+++ b/src/sbbs3/getmsg.cpp
@@ -119,7 +119,7 @@ void sbbs_t::show_msgattr(smbmsg_t* msg)
 /****************************************************************************/
 /* Displays a message header to the screen                                  */
 /****************************************************************************/
-void sbbs_t::show_msghdr(smb_t* smb, smbmsg_t* msg)
+void sbbs_t::show_msghdr(smb_t* smb, smbmsg_t* msg, const char* subject, const char* from, const char* to)
 {
 	char	str[MAX_PATH+1];
 	char	age[64];
@@ -127,8 +127,10 @@ void sbbs_t::show_msghdr(smb_t* smb, smbmsg_t* msg)
 	int 	i;
 	smb_t	saved_smb = this->smb;
 
-	this->smb = *smb;	// Needed for @-codes and JS bbs.smb_* properties
-	current_msg = msg;	// Needed for @-codes and JS bbs.msg_* properties
+	if(smb != NULL)
+		this->smb = *smb;	// Needed for @-codes and JS bbs.smb_* properties
+	if(msg != NULL)
+		current_msg = msg;		// Needed for @-codes and JS bbs.msg_* properties
 
 	attr(LIGHTGRAY);
 	if(!tos) {
@@ -139,23 +141,23 @@ void sbbs_t::show_msghdr(smb_t* smb, smbmsg_t* msg)
 	}
 	msghdr_tos = tos;
 	if(!menu("msghdr", P_NOERROR)) {
-		bprintf(text[MsgSubj],msg->subj);
+		bprintf(text[MsgSubj], subject == NULL ? msg->subj : subject);
 		if(msg->tags && *msg->tags)
 			bprintf(text[MsgTags], msg->tags);
 		if(msg->hdr.attr)
 			show_msgattr(msg);
-		if(msg->to && *msg->to) {
-			bprintf(text[MsgTo],msg->to);
+		if(to != NULL ||msg->to_list != NULL || (msg->to && *msg->to)) {
+			bprintf(text[MsgTo], to == NULL ? (msg->to_list == NULL ? msg->to : msg->to_list) : to);
 			if(msg->to_net.addr!=NULL)
 				bprintf(text[MsgToNet],smb_netaddrstr(&msg->to_net,str));
 			if(msg->to_ext)
 				bprintf(text[MsgToExt],msg->to_ext);
 		}
-		if(!(msg->hdr.attr&MSG_ANONYMOUS) || SYSOP) {
-			bprintf(text[MsgFrom],msg->from);
+		if(from != NULL || msg->from != NULL && (!(msg->hdr.attr&MSG_ANONYMOUS) || SYSOP)) {
+			bprintf(text[MsgFrom], from == NULL ? msg->from : from);
 			if(msg->from_ext)
 				bprintf(text[MsgFromExt],msg->from_ext);
-			if(msg->from_net.addr!=NULL && strchr(msg->from,'@')==NULL)
+			if(msg->from_net.addr!=NULL && (msg->from == NULL || (msg->from,'@')==NULL))
 				bprintf(text[MsgFromNet],smb_netaddrstr(&msg->from_net,str));
 		}
 		if(!(msg->hdr.attr&MSG_POLL) && (msg->upvotes || msg->downvotes))
diff --git a/src/sbbs3/js_bbs.cpp b/src/sbbs3/js_bbs.cpp
index d7bbe2410f79d32462b3d23c97471682b22564b3..5867bb579eed7aa8d2e4c6f53575d23dad1a9ec9 100644
--- a/src/sbbs3/js_bbs.cpp
+++ b/src/sbbs3/js_bbs.cpp
@@ -3606,6 +3606,9 @@ js_show_msg_header(JSContext *cx, uintN argc, jsval *arglist)
 	sbbs_t*		sbbs;
 	smb_t*		smb = NULL;
 	smbmsg_t*	msg = NULL;
+	char*		subject = NULL;
+	char*		from = NULL;
+	char*		to = NULL;
 	jsrefcount	rc;
 
 	JS_SET_RVAL(cx, arglist, JSVAL_VOID);
@@ -3620,14 +3623,26 @@ js_show_msg_header(JSContext *cx, uintN argc, jsval *arglist)
 			if(!js_GetMsgHeaderObjectPrivates(cx, hdrobj, &smb, &msg, NULL)) {
 				return JS_FALSE;
 			}
+		} else if(JSVAL_IS_STRING(argv[n])) {
+			JSString* str = JS_ValueToString(cx, argv[n]);
+			if(subject == NULL) {
+				JSSTRING_TO_MSTRING(cx, str, subject, NULL);
+			} else if(from == NULL) {
+				JSSTRING_TO_MSTRING(cx, str, from, NULL);
+			} else if(to == NULL) {
+				JSSTRING_TO_MSTRING(cx, str, to, NULL);
+			}
 		}
 	}
 	if(smb == NULL || msg == NULL)
 		return JS_TRUE;
 
 	rc=JS_SUSPENDREQUEST(cx);
-	sbbs->show_msghdr(smb, msg);
+	sbbs->show_msghdr(smb, msg, subject, from, to);
 	JS_RESUMEREQUEST(cx, rc);
+	FREE_AND_NULL(subject);
+	FREE_AND_NULL(from);
+	FREE_AND_NULL(to);
 
 	return(JS_TRUE);
 }
@@ -4259,7 +4274,7 @@ static jsSyncMethodSpec js_bbs_functions[] = {
 		"<i>header</i> must be a header object returned from <i>MsgBase.get_msg_header()</i>)")
 	,31702
 	},
-	{"show_msg_header",	js_show_msg_header,	1,	JSTYPE_VOID,	JSDOCSTR("[object header]")
+	{"show_msg_header",	js_show_msg_header,	1,	JSTYPE_VOID,	JSDOCSTR("[object header] [,subject] [,from] [,to]")
 	,JSDOCSTR("show a message's header (only)<br>"
 		"<i>header</i> must be a header object returned from <i>MsgBase.get_msg_header()</i>)")
 	,31702
diff --git a/src/sbbs3/sbbs.h b/src/sbbs3/sbbs.h
index 4245a362ac1d7d211db41c91e029c60f5103e845..21968808af0a2998b7d9d65d3f71edd512d1507f 100644
--- a/src/sbbs3/sbbs.h
+++ b/src/sbbs3/sbbs.h
@@ -681,7 +681,7 @@ public:
 	/* getmsg.cpp */
 	int		loadmsg(smbmsg_t *msg, ulong number);
 	void	show_msgattr(smbmsg_t*);
-	void	show_msghdr(smb_t*, smbmsg_t*);
+	void	show_msghdr(smb_t*, smbmsg_t*, const char *subj = NULL, const char* from = NULL, const char* to = NULL);
 	bool	show_msg(smb_t*, smbmsg_t*, long p_mode = 0, post_t* post = NULL);
 	bool	msgtotxt(smb_t*, smbmsg_t*, const char *fname, bool header = true, ulong gettxt_mode = GETMSGTXT_ALL);
 	ulong	getlastmsg(uint subnum, uint32_t *ptr, time_t *t);