diff --git a/exec/default.src b/exec/default.src
index 455c9f08b9faccdab978939e20cc6cbdaa1d1540..9ec5c74d68dc5bcb0307e6657ef12b8438b935dd 100644
--- a/exec/default.src
+++ b/exec/default.src
@@ -233,7 +233,7 @@ cmdkey B
 	end_cmd
 
 cmdkey C
-	exec_bin chat_sec
+	chat_section
 	end_cmd
 
 cmdkey D
@@ -700,7 +700,7 @@ cmdkey B
 	end_cmd
 
 cmdkey C
-	exec_bin chat_sec
+	chat_section
 	end_cmd
 
 cmdkey D
diff --git a/exec/feedback.src b/exec/feedback.src
new file mode 100644
index 0000000000000000000000000000000000000000..cc06f101c2c98451f65750c0c1cb1090c90b9f28
--- /dev/null
+++ b/exec/feedback.src
@@ -0,0 +1 @@
+yes_no "Are you sure"
diff --git a/exec/major.src b/exec/major.src
index 1e56d75383610b57aa995eb26761a4e451a57620..84b980aeb52b5bd7c093aa5288a0e6fddbc04752 100644
--- a/exec/major.src
+++ b/exec/major.src
@@ -1,9 +1,5 @@
-# major.src
-
 # MajorBBS Clone Command Shell for Synchronet
 
-# $Id: major.src,v 1.13 2020/09/12 02:46:08 rswindell Exp $
-
 # @format.tab-size 8, @format.use-tabs true
 
 !include sbbsdefs.inc
@@ -25,7 +21,7 @@ cmdkey ?
 	end_cmd
 
 cmdkey T
-	exec_bin chat_sec
+	chat_section
 	end_cmd
 
 cmdkey I
@@ -273,7 +269,7 @@ cmdkey Q
         end_cmd
 
 cmdkey T
-	exec_bin chat_sec
+	chat_section
 	end_cmd
 
 cmdkey S
diff --git a/exec/pcboard.src b/exec/pcboard.src
index 5bcc3448c93278e262ca378ac9964d17708c67aa..1ffffdcf70f6eda472131a5e455cfe0aadbf6367 100644
--- a/exec/pcboard.src
+++ b/exec/pcboard.src
@@ -1,9 +1,5 @@
-# pcboard.src
-
 # PCBoard v15.1 menu/command emulation
 
-# $Id: pcboard.src,v 1.14 2020/09/12 02:46:09 rswindell Exp $
-
 # @format.tab-size 8, @format.use-tabs true
 
 !include sbbsdefs.inc
@@ -244,7 +240,7 @@ cmdstr WHO
 	end_cmd
 
 cmdstr CHAT
-	exec_bin chat_sec
+	chat_section
 	end_cmd
 
 cmdstr NEWS
diff --git a/exec/renegade.src b/exec/renegade.src
index a16b089afb268e0a7fa644b78c2c46200252fe3b..99cb064a3d8f1385a0e9884f8c2a09f6c6435dcf 100644
--- a/exec/renegade.src
+++ b/exec/renegade.src
@@ -1,7 +1,3 @@
-# renegade.src
-
-# $Id: renegade.src,v 1.16 2020/09/12 02:46:09 rswindell Exp $
-
 # @format.tab-size 8, @format.use-tabs true
 
 !include sbbsdefs.inc
@@ -95,7 +91,7 @@ cmdkey A
 	end_cmd
 
 cmdkey C
-	exec_bin chat_sec
+	chat_section
 	end_cmd
 
 cmdkey E
@@ -483,7 +479,7 @@ cmdkey E
 	end_cmd
 
 cmdkey C
-	exec_bin chat_sec
+	chat_section
 	end_cmd
 
 cmdkey D
@@ -746,7 +742,7 @@ cmdkey /A
 	end_cmd
 
 cmdkey C
-	exec_bin chat_sec
+	chat_section
 	end_cmd
 
 cmdkey /L
diff --git a/exec/sdos.src b/exec/sdos.src
index bee7966242217cd3b90c35aab5b0c42c77f603ef..35db2e32cca46eae0b3c6df4901d3212d35265bb 100644
--- a/exec/sdos.src
+++ b/exec/sdos.src
@@ -1,9 +1,5 @@
-# sdos.src
-
 # DOS shell for Synchronet version 2 systems
 
-# $Id: sdos.src,v 1.15 2020/09/12 02:46:09 rswindell Exp $
-
 # @format.tab-size 8, @format.use-tabs true
 
 # Thanks to Yojimbo for the BDOS shell that inspired this one
@@ -111,7 +107,7 @@ if_true
 # Global BBS commands
 compare_str "chat"
 if_true
-	exec_bin chat_sec
+	chat_section
 	return
 	end_if
 
diff --git a/exec/simple.src b/exec/simple.src
index a3f7edbe38660dd54b73cefa9e05796098a0c67f..3b97fccf4c76ddc391b4b05e43bd878efa825ac8 100644
--- a/exec/simple.src
+++ b/exec/simple.src
@@ -1,9 +1,5 @@
-# simple.src
-
 # Simple Synchronet Command Shell - for beginner/first-time users
 
-# $Id: simple.src,v 1.13 2020/09/12 02:46:09 rswindell Exp $
-
 # @format.tab-size 8, @format.use-tabs true
 
 !include sbbsdefs.inc
@@ -31,11 +27,11 @@ logstr
 # Commands
 
 cmdstr C
-	exec_bin chat_sec
+	chat_section
 	end_cmd
 
 cmdstr CHAT
-	exec_bin chat_sec
+	chat_section
 	end_cmd
 
 cmdstr Q
diff --git a/exec/wildcat.src b/exec/wildcat.src
index 80d1c0bc1732ec8caeb177d89da5f5f6f7ca78ee..5d1479d2da03052915b780cbe48bf4a573e0b16a 100644
--- a/exec/wildcat.src
+++ b/exec/wildcat.src
@@ -1,7 +1,3 @@
-# wildcat.src
-
-# $Id: wildcat.src,v 1.17 2020/09/12 02:46:09 rswindell Exp $
-
 # @format.tab-size 8, @format.use-tabs true
 
 !include sbbsdefs.inc
@@ -65,7 +61,7 @@ cmdkey F
 	goto transfers
 	end_cmd
 cmdkey T
-	exec_bin chat_sec
+	chat_section
 	end_cmd
 cmdkey J
 	msg_select_area
diff --git a/exec/wwiv.src b/exec/wwiv.src
index 230ebc7996bd4610f9b9a77045aa710e79d382af..9845796a089532f8f36252f83a35c18748fce640 100644
--- a/exec/wwiv.src
+++ b/exec/wwiv.src
@@ -130,7 +130,7 @@ cmdkey A
 	end_cmd
 
 cmdkey C
-	exec_bin chat_sec
+	chat_section
 	end_cmd
 
 cmdkey D
@@ -514,7 +514,7 @@ cmdkey B
 	end_cmd
 
 cmdkey C
-	exec_bin chat_sec
+	chat_section
 	end_cmd
 
 cmdkey D
diff --git a/src/sbbs3/chat.cpp b/src/sbbs3/chat.cpp
index 41e7286ec5cb7a41780ae24a76a16eb9eb283996..0eb9bfa0ad4cff89e8b63b92bc8329b3ce279512 100644
--- a/src/sbbs3/chat.cpp
+++ b/src/sbbs3/chat.cpp
@@ -586,94 +586,7 @@ bool sbbs_t::guru_page(void)
 /****************************************************************************/
 void sbbs_t::chatsection()
 {
-	char	str[256],ch,no_rip_menu;
-
-	if(useron.rest&FLAG('C')) {
-		bputs(text[R_Chat]);
-		return;
-	}
-
-	action=NODE_CHAT;
-	if(useron.misc&(RIP|WIP|HTML) || !(useron.misc&EXPERT))
-		menu("chat");
-	ASYNC;
-	bputs(text[ChatPrompt]);
-	while(online) {
-		no_rip_menu=0;
-		ch=(char)getkeys("ACDJPQST?\r",0);
-		if(ch>' ')
-			logch(ch,0);
-		switch(ch) {
-			case 'S':
-				useron.chat^=CHAT_SPLITP;
-				putuserchat(useron.number, useron.chat);
-				bprintf("\r\nPrivate split-screen chat is now: %s\r\n"
-					,useron.chat&CHAT_SPLITP ? text[ON]:text[OFF]);
-				break;
-			case 'A':
-				CRLF;
-				useron.chat^=CHAT_NOACT;
-				putuserchat(useron.number, useron.chat);
-				if(getnodedat(cfg.node_num,&thisnode,true)==0) {
-					thisnode.misc^=NODE_AOFF;
-					printnodedat(cfg.node_num,&thisnode);
-				}
-				putnodedat(cfg.node_num,&thisnode);
-				no_rip_menu=true;
-				break;
-			case 'D':
-				CRLF;
-				useron.chat^=CHAT_NOPAGE;
-				putuserchat(useron.number, useron.chat);
-				if(getnodedat(cfg.node_num,&thisnode,true)==0) {
-					thisnode.misc^=NODE_POFF;
-					printnodedat(cfg.node_num,&thisnode);
-				}
-				putnodedat(cfg.node_num,&thisnode);
-				no_rip_menu=true;
-				break;
-			case 'J':
-				multinodechat();
-				break;
-			case 'P':   /* private node-to-node chat */
-				privchat();
-				break;
-			case 'C':
-				no_rip_menu=1;
-				if(sysop_page())
-					break;
-				if(cfg.total_gurus && chk_ar(cfg.guru[0]->ar,&useron,&client) && text[ChatWithGuruInsteadQ][0]) {
-					SAFEPRINTF(str,text[ChatWithGuruInsteadQ],cfg.guru[0]->name);
-					if(!yesno(str))
-						break; 
-				}
-				else
-					break;
-				/* FALL-THROUGH */
-			case 'T':
-				guru_page();
-				no_rip_menu=1;
-				break;
-			case '?':
-				if(useron.misc&EXPERT)
-					menu("chat");
-				break;
-			default:	/* 'Q' or <CR> */
-				lncntr=0;
-//				if(gurubuf)
-//					free(gurubuf);
-				return; 
-		}
-		action=NODE_CHAT;
-		if(!(useron.misc&EXPERT) || useron.misc&(WIP|HTML)
-			|| (useron.misc&RIP && !no_rip_menu)) {
-			menu("chat"); 
-		}
-		ASYNC;
-		bputs(text[ChatPrompt]); 
-	}
-//	if(gurubuf)
-//		free(gurubuf);
+	exec_bin(cfg.chatsec_mod, &main_csi);
 }
 
 /****************************************************************************/
diff --git a/src/sbbs3/js_bbs.cpp b/src/sbbs3/js_bbs.cpp
index 75cf3b78dba44d74d01eb148745fb35c5fe53a76..fff3813ded0d41c134171bc97af255c96779bb24 100644
--- a/src/sbbs3/js_bbs.cpp
+++ b/src/sbbs3/js_bbs.cpp
@@ -2054,6 +2054,24 @@ js_text_sec(JSContext *cx, uintN argc, jsval *arglist)
 	return(JS_TRUE);
 }
 
+static JSBool
+js_chat_sec(JSContext *cx, uintN argc, jsval *arglist)
+{
+	sbbs_t*		sbbs;
+	jsrefcount	rc;
+
+	if((sbbs=js_GetPrivate(cx, JS_THIS_OBJECT(cx, arglist)))==NULL)
+		return(JS_FALSE);
+
+	JS_SET_RVAL(cx, arglist, JSVAL_VOID);
+
+	rc=JS_SUSPENDREQUEST(cx);
+	sbbs->chatsection();
+	JS_RESUMEREQUEST(cx, rc);
+
+	return(JS_TRUE);
+}
+
 static JSBool
 js_qwk_sec(JSContext *cx, uintN argc, jsval *arglist)
 {
@@ -4438,6 +4456,10 @@ static jsSyncMethodSpec js_bbs_functions[] = {
 	,JSDOCSTR("enter the external programs section (or go directly to the specified <i>section</i>)")
 	,310
 	},
+	{"chat_sec",		js_chat_sec,		0,	JSTYPE_VOID,	JSDOCSTR("")
+	,JSDOCSTR("enter the chat section/menu")
+	,320
+	},
 	{"xfer_policy",		js_xfer_policy,		0,	JSTYPE_VOID,	JSDOCSTR("")
 	,JSDOCSTR("display the file transfer policy")
 	,310
diff --git a/src/sbbs3/scfg/scfgsys.c b/src/sbbs3/scfg/scfgsys.c
index 983026c86ba9c7cd370ec71d906ec50812274d04..931abd575465439340fe14a2bcc90dde4db81416 100644
--- a/src/sbbs3/scfg/scfgsys.c
+++ b/src/sbbs3/scfg/scfgsys.c
@@ -2603,6 +2603,7 @@ void sys_cfg(void)
 					sprintf(opt[i++],"%-16.16s%s","Expired User",cfg.expire_mod);
 					sprintf(opt[i++],"%-16.16s%s","Auto Message",cfg.automsg_mod);
 					sprintf(opt[i++],"%-16.16s%s","Send Feedback",cfg.feedback_mod);
+					sprintf(opt[i++],"%-16.16s%s","Chat Section",cfg.chatsec_mod);
 					sprintf(opt[i++],"%-16.16s%s","Text Section",cfg.textsec_mod);
 					sprintf(opt[i++],"%-16.16s%s","Xtrn Section",cfg.xtrnsec_mod);
 					sprintf(opt[i++],"%-16.16s%s","Pre Xtrn",cfg.prextrn_mod);
@@ -2638,6 +2639,7 @@ void sys_cfg(void)
 						"`Expired User`   User account expires (offline)\n"
 						"`Auto Message`   User chooses to re-read or edit the auto-message\n"
 						"`Send Feedback`  User sending email to a sysop (return error to cancel)\n"
+						"`Chat Section`   User enters chat section/menu\n"
 						"`Text Section`   Handle general text file (viewing) section\n"
 						"`Xtrn Section`   Handle external programs (doors) section\n"
 						"`Pre Xtrn`       Executed before external programs (doors) run\n"
@@ -2704,74 +2706,78 @@ void sys_cfg(void)
 								,cfg.feedback_mod,sizeof(cfg.feedback_mod)-1,K_EDIT);
 							break;
 						case 9:
+							uifc.input(WIN_MID|WIN_SAV,0,0,"Chat Section Module"
+								,cfg.chatsec_mod,sizeof(cfg.chatsec_mod)-1,K_EDIT);
+							break;
+						case 10:
 							uifc.input(WIN_MID|WIN_SAV,0,0,"Text File Section Module"
 								,cfg.textsec_mod,sizeof(cfg.textsec_mod)-1,K_EDIT);
 							break;
-						case 10:
+						case 11:
 							uifc.input(WIN_MID|WIN_SAV,0,0,"External Program Section Module"
 								,cfg.xtrnsec_mod,sizeof(cfg.xtrnsec_mod)-1,K_EDIT);
 							break;
-						case 11:
+						case 12:
 							uifc.input(WIN_MID|WIN_SAV,0,0,"Pre External Program Module"
 								,cfg.prextrn_mod,sizeof(cfg.prextrn_mod)-1,K_EDIT);
 							break;
-						case 12:
+						case 13:
 							uifc.input(WIN_MID|WIN_SAV,0,0,"Post External Program Module"
 								,cfg.postxtrn_mod,sizeof(cfg.postxtrn_mod)-1,K_EDIT);
 							break;
-						case 13:
+						case 14:
 							uifc.input(WIN_MID|WIN_SAV,0,0,"Read Mail Module"
 								,cfg.readmail_mod,sizeof(cfg.readmail_mod)-1,K_EDIT);
 							break;
-						case 14:
+						case 15:
 							uifc.input(WIN_MID|WIN_SAV,0,0,"Scan Msgs Module"
 								,cfg.scanposts_mod,sizeof(cfg.scanposts_mod)-1,K_EDIT);
 							break;
-						case 15:
+						case 16:
 							uifc.input(WIN_MID|WIN_SAV,0,0,"Scan Subs Module"
 								,cfg.scansubs_mod,sizeof(cfg.scansubs_mod)-1,K_EDIT);
 							break;
-						case 16:
+						case 17:
 							uifc.input(WIN_MID|WIN_SAV,0,0,"List Msgs Module"
 								,cfg.listmsgs_mod,sizeof(cfg.listmsgs_mod)-1,K_EDIT);
 							break;
-						case 17:
+						case 18:
 							uifc.input(WIN_MID|WIN_SAV,0,0,"List Logons Module"
 								,cfg.logonlist_mod,sizeof(cfg.logonlist_mod)-1,K_EDIT);
 							break;
-						case 18:
+						case 19:
 							uifc.input(WIN_MID|WIN_SAV,0,0,"List Users"
 								,cfg.userlist_mod,sizeof(cfg.userlist_mod)-1,K_EDIT);
 							break;
-						case 19:
+						case 20:
 							uifc.input(WIN_MID|WIN_SAV,0,0,"List Nodes Module"
 								,cfg.nodelist_mod,sizeof(cfg.nodelist_mod)-1,K_EDIT);
 							break;
-						case 20:
+						case 21:
 							uifc.input(WIN_MID|WIN_SAV,0,0,"Who's Online Module"
 								,cfg.whosonline_mod,sizeof(cfg.whosonline_mod)-1,K_EDIT);
 							break;
-						case 21:
+						case 22:
 							uifc.input(WIN_MID|WIN_SAV,0,0,"Private Message Module"
 								,cfg.privatemsg_mod,sizeof(cfg.privatemsg_mod)-1,K_EDIT);
 							break;
-						case 22:
+						case 23:
 							uifc.input(WIN_MID|WIN_SAV,0,0,"Scan Dirs Module"
 								,cfg.scandirs_mod,sizeof(cfg.scandirs_mod)-1,K_EDIT);
 							break;
-						case 23:
+						case 24:
 							uifc.input(WIN_MID|WIN_SAV,0,0,"List Files Module"
 								,cfg.listfiles_mod,sizeof(cfg.listfiles_mod)-1,K_EDIT);
 							break;
-						case 24:
+						case 25:
 							uifc.input(WIN_MID|WIN_SAV,0,0,"View File Information Module"
 								,cfg.fileinfo_mod,sizeof(cfg.fileinfo_mod)-1,K_EDIT);
 							break;
-						case 25:
+						case 26:
 							uifc.input(WIN_MID|WIN_SAV,0,0,"Batch File Transfer Module"
 								,cfg.batxfer_mod, sizeof(cfg.batxfer_mod)-1, K_EDIT);
 							break;
-						case 26:
+						case 27:
 							uifc.input(WIN_MID|WIN_SAV,0,0,"Temporary File Transfer Module"
 								,cfg.tempxfer_mod, sizeof(cfg.tempxfer_mod)-1, K_EDIT);
 							break;
diff --git a/src/sbbs3/scfgdefs.h b/src/sbbs3/scfgdefs.h
index 3d90c3797fdbd96688dda5265f81cf16635edddc..28ffeeaf1af20c800ed78e7c72cd36996d1325df 100644
--- a/src/sbbs3/scfgdefs.h
+++ b/src/sbbs3/scfgdefs.h
@@ -603,6 +603,7 @@ typedef struct
 	char			expire_mod[LEN_CMD+1];			/* User expiration module */
 	char			textsec_mod[LEN_CMD+1];			/* Text section module */
 	char			xtrnsec_mod[LEN_CMD+1];			/* External Program section module */
+	char			chatsec_mod[LEN_CMD+1];			/* Chat section module */
 	char			automsg_mod[LEN_CMD+1];			/* Auto-message module */
 	char			feedback_mod[LEN_CMD+1];		/* Send feedback to sysop module */
 	char			readmail_mod[LEN_CMD+1];	/* Reading mail module */
diff --git a/src/sbbs3/scfglib1.c b/src/sbbs3/scfglib1.c
index 95ac3e1e0bc154d17012f9ba3d4db780c986ea79..02d01ae0105cfe9a74a4cceb7aba290c8eceb000 100644
--- a/src/sbbs3/scfglib1.c
+++ b/src/sbbs3/scfglib1.c
@@ -240,6 +240,7 @@ BOOL read_main_cfg(scfg_t* cfg, char* error, size_t maxerrlen)
 	SAFECOPY(cfg->scansubs_mod, iniGetString(section, NULL, "scansubs", "", value));
 	SAFECOPY(cfg->listmsgs_mod, iniGetString(section, NULL, "listmsgs", "", value));
 	SAFECOPY(cfg->textsec_mod, iniGetString(section, NULL, "textsec", "text_sec", value));
+	SAFECOPY(cfg->chatsec_mod, iniGetString(section, NULL, "chatsec", "chat_sec", value));
 	SAFECOPY(cfg->automsg_mod, iniGetString(section, NULL, "automsg", "automsg", value));
 	SAFECOPY(cfg->feedback_mod, iniGetString(section, NULL, "feedback", "", value));
 	SAFECOPY(cfg->xtrnsec_mod, iniGetString(section, NULL, "xtrnsec", "xtrn_sec", value));
diff --git a/src/sbbs3/scfgsave.c b/src/sbbs3/scfgsave.c
index 9ce7fd3c34e49fb42041d1148577cacc6f13235c..710a5e3498e190ac92ec647cef18731156409572 100644
--- a/src/sbbs3/scfgsave.c
+++ b/src/sbbs3/scfgsave.c
@@ -246,6 +246,7 @@ BOOL write_main_cfg(scfg_t* cfg, int backup_level)
 		iniSetString(&ini, name, "scansubs", cfg->scansubs_mod, NULL);
 		iniSetString(&ini, name, "listmsgs", cfg->listmsgs_mod, NULL);
 		iniSetString(&ini, name, "textsec", cfg->textsec_mod, NULL);
+		iniSetString(&ini, name, "chatsec", cfg->chatsec_mod, NULL);
 		iniSetString(&ini, name, "automsg", cfg->automsg_mod, NULL);
 		iniSetString(&ini, name, "feedback", cfg->feedback_mod, NULL);
 		iniSetString(&ini, name, "userlist", cfg->userlist_mod, NULL);