From d214b9ec3efe2ce4b59e73d501f069b10bc82581 Mon Sep 17 00:00:00 2001
From: rswindell <>
Date: Wed, 6 Dec 2017 04:51:26 +0000
Subject: [PATCH] Use an external semfile (ctrl/sysavail.chat) to signal sysop
 availability for chat, rather than the old startup options flag
 ([BBS]->SYSOP_AVAILABLE). This will be much easier for other
 processes/programs to query and control.

---
 src/sbbs3/chat.cpp              | 21 ++++++++++++++++++++-
 src/sbbs3/ctrl/MainFormUnit.cpp | 22 ++++++++++------------
 src/sbbs3/logon.cpp             |  3 +--
 src/sbbs3/sbbs.h                |  4 ++++
 4 files changed, 35 insertions(+), 15 deletions(-)

diff --git a/src/sbbs3/chat.cpp b/src/sbbs3/chat.cpp
index 9c6969d78d..218c349606 100644
--- a/src/sbbs3/chat.cpp
+++ b/src/sbbs3/chat.cpp
@@ -695,6 +695,25 @@ void sbbs_t::chatsection()
 //		free(gurubuf);
 }
 
+static char* sysop_available_semfile(scfg_t* scfg)
+{
+	static char semfile[MAX_PATH+1];
+	SAFEPRINTF(semfile, "%ssysavail.chat", scfg->ctrl_dir);
+	return semfile;
+}
+
+extern "C" BOOL DLLCALL sysop_available(scfg_t* scfg)
+{
+	return fexist(sysop_available_semfile(scfg));
+}
+
+extern "C" BOOL DLLCALL set_sysop_availability(scfg_t* scfg, BOOL available)
+{
+	if(available)
+		return ftouch(sysop_available_semfile(scfg));
+	return remove(sysop_available_semfile(scfg)) == 0;
+}
+
 /****************************************************************************/
 /****************************************************************************/
 bool sbbs_t::sysop_page(void)
@@ -707,7 +726,7 @@ bool sbbs_t::sysop_page(void)
 		return(false); 
 	}
 
-	if(startup->options&BBS_OPT_SYSOP_AVAILABLE 
+	if(sysop_available(&cfg)
 		|| (cfg.sys_chat_ar[0] && chk_ar(cfg.sys_chat_ar,&useron,&client))
 		|| useron.exempt&FLAG('C')) {
 
diff --git a/src/sbbs3/ctrl/MainFormUnit.cpp b/src/sbbs3/ctrl/MainFormUnit.cpp
index 1c923841ad..e646cfe38c 100644
--- a/src/sbbs3/ctrl/MainFormUnit.cpp
+++ b/src/sbbs3/ctrl/MainFormUnit.cpp
@@ -843,7 +843,7 @@ __fastcall TMainForm::TMainForm(TComponent* Owner)
     bbs_startup.event_cbdata=&event_log_list;    
     bbs_startup.first_node=1;
     bbs_startup.last_node=4;
-	bbs_startup.options=BBS_OPT_XTRN_MINIMIZED|BBS_OPT_SYSOP_AVAILABLE;
+	bbs_startup.options=BBS_OPT_XTRN_MINIMIZED;
 	bbs_startup.telnet_port=IPPORT_TELNET;
     bbs_startup.rlogin_port=513;
 	bbs_startup.lputs=lputs;
@@ -2248,7 +2248,7 @@ void __fastcall TMainForm::StartupTimerTick(TObject *Sender)
     else
     	SoundToggle->Checked=true;
 
-    if(bbs_startup.options&BBS_OPT_SYSOP_AVAILABLE)
+    if(sysop_available(&cfg))
     	ChatToggle->Checked=true;
     else
     	ChatToggle->Checked=false;
@@ -2959,6 +2959,12 @@ void __fastcall TMainForm::UpTimerTick(TObject *Sender)
     char    days[64];
     static  time_t start;
     ulong   up;
+    static  bool sysop_available;
+
+    if(ChatToggle->Checked != sysop_available) {
+        sysop_available = ChatToggle->Checked;
+        set_sysop_availability(&cfg, sysop_available);
+    }
 
     if(!start)
         start=time(NULL);
@@ -3032,16 +3038,8 @@ void __fastcall TMainForm::UpTimerTick(TObject *Sender)
 void __fastcall TMainForm::ChatToggleExecute(TObject *Sender)
 {
     ChatToggle->Checked=!ChatToggle->Checked;
-    if(ChatToggle->Checked)
-	    bbs_startup.options|=BBS_OPT_SYSOP_AVAILABLE;
-    else
-        bbs_startup.options&=~BBS_OPT_SYSOP_AVAILABLE;
-
-	if(bbs_svc!=NULL && controlService!=NULL)
-        controlService(bbs_svc
-            ,ChatToggle->Checked ? SERVICE_CONTROL_SYSOP_AVAILABLE : SERVICE_CONTROL_SYSOP_UNAVAILABLE
-            ,&bbs_svc_status);
 }
+
 //---------------------------------------------------------------------------
 void __fastcall TMainForm::UserEditExecute(TObject *Sender)
 {
@@ -3374,7 +3372,7 @@ void __fastcall TMainForm::reload_config(void)
    	StatusBar->Panels->Items[STATUSBAR_LAST_PANEL]->Text="Configuration reloaded";
    	semfile_list_check(&initialized,recycle_semfiles);
 
-    if(bbs_startup.options&BBS_OPT_SYSOP_AVAILABLE)
+    if(sysop_available(&cfg))
     	ChatToggle->Checked=true;
     else
     	ChatToggle->Checked=false;
diff --git a/src/sbbs3/logon.cpp b/src/sbbs3/logon.cpp
index 2a5f6baa56..6071015997 100644
--- a/src/sbbs3/logon.cpp
+++ b/src/sbbs3/logon.cpp
@@ -454,8 +454,7 @@ bool sbbs_t::logon()
 			,cfg.level_timeperday[useron.level]+useron.min);
 		bprintf(text[LiMailWaiting],mailw);
 		strcpy(str,text[LiSysopIs]);
-		if(startup->options&BBS_OPT_SYSOP_AVAILABLE 
-			|| (cfg.sys_chat_ar[0] && chk_ar(cfg.sys_chat_ar,&useron,&client)))
+		if(sysop_available(&cfg))
 			strcat(str,text[LiSysopAvailable]);
 		else
 			strcat(str,text[LiSysopNotAvailable]);
diff --git a/src/sbbs3/sbbs.h b/src/sbbs3/sbbs.h
index df055f6a8d..16520f327c 100644
--- a/src/sbbs3/sbbs.h
+++ b/src/sbbs3/sbbs.h
@@ -1012,6 +1012,10 @@ extern "C" {
 	DLLEXPORT int		DLLCALL sbbs_random(int);
 	DLLEXPORT void		DLLCALL sbbs_srand(void);
 
+	/* chat.cpp */
+	DLLEXPORT BOOL		DLLCALL sysop_available(scfg_t*);
+	DLLEXPORT BOOL		DLLCALL set_sysop_availability(scfg_t*, BOOL available);
+
 	/* getstats.c */
 	DLLEXPORT BOOL		DLLCALL getstats(scfg_t* cfg, char node, stats_t* stats);
 	DLLEXPORT ulong		DLLCALL	getposts(scfg_t* cfg, uint subnum);
-- 
GitLab