From 25d190c9cd2b3be4f281f49bdfb9b7707d854800 Mon Sep 17 00:00:00 2001
From: rswindell <>
Date: Wed, 22 May 2019 09:53:40 +0000
Subject: [PATCH] Fix issue reported by Va7aqd: when sub-boards were cut to the
 clipboard (or deleted) or a group of sub-boards was deleted, and any of the
 deleted/cut sub-boards belonged to a configured QWKnet hub, that QWKnet
 sub-board would end-up pointing to the next sub-board in the configuration
 (possibly in another message group, possibly not part of the QWKnet in
 question). Now, if a QWKnet sub is deleted/cut, remove it (correctly) from
 any QWKnet hubs using a common (new) function: remove_sub(). The bug was: the
 remaining sub-board pointers were moved *before* the remove-sub pointer was
 compared against the list of QWKnet hub subs (and NULLed), so while the
 effort *was* made to address this problem, it didn't actually work in
 practice. Thanks for the bug report.

---
 src/sbbs3/scfg/scfg.h    |  1 +
 src/sbbs3/scfg/scfgmsg.c | 12 +-----------
 src/sbbs3/scfg/scfgsub.c | 28 ++++++++++++++++++----------
 3 files changed, 20 insertions(+), 21 deletions(-)

diff --git a/src/sbbs3/scfg/scfg.h b/src/sbbs3/scfg/scfg.h
index f439876350..4b34ed455f 100644
--- a/src/sbbs3/scfg/scfg.h
+++ b/src/sbbs3/scfg/scfg.h
@@ -144,6 +144,7 @@ int  bits(long l);
 void getar(char *desc, char *ar);
 bool new_sub(unsigned new_subnum, unsigned group_num);
 bool new_qhub_sub(qhub_t*, unsigned qsubnum, sub_t*, unsigned confnum);
+void remove_sub(scfg_t*, unsigned subnum);
 void sort_subs(int grpnum);
 void sort_dirs(int libnum);
 unsigned subs_in_group(unsigned grpnum);
diff --git a/src/sbbs3/scfg/scfgmsg.c b/src/sbbs3/scfg/scfgmsg.c
index da726b7ddd..f409fc5365 100644
--- a/src/sbbs3/scfg/scfgmsg.c
+++ b/src/sbbs3/scfg/scfgmsg.c
@@ -526,17 +526,7 @@ void msgs_cfg()
 			if (msk == MSK_DEL) {
 				for (j = 0; j < cfg.total_subs;) {
 					if (cfg.sub[j]->grp == grpnum) {	/* delete subs of this group */
-						free(cfg.sub[j]);
-						cfg.total_subs--;
-						k = j;
-						while (k < cfg.total_subs) {	/* move all subs down */
-							cfg.sub[k] = cfg.sub[k + 1];
-							for (q = 0; q < cfg.total_qhubs; q++)
-								for (s = 0; s < cfg.qhub[q]->subs; s++)
-									if (cfg.qhub[q]->sub[s] == cfg.sub[j])
-										cfg.qhub[q]->sub[s] = NULL;
-							k++;
-						}
+						remove_sub(&cfg, j);
 					}
 					else j++;
 				}
diff --git a/src/sbbs3/scfg/scfgsub.c b/src/sbbs3/scfg/scfgsub.c
index 47d7bc64dd..22708d7de8 100644
--- a/src/sbbs3/scfg/scfgsub.c
+++ b/src/sbbs3/scfg/scfgsub.c
@@ -95,13 +95,29 @@ bool new_sub(unsigned new_subnum, unsigned group_num)
 	return true;
 }
 
+void remove_sub(scfg_t* cfg, unsigned subnum)
+{
+	sub_t* sub = cfg->sub[subnum];
+	// Remove the sub-board from any QWKnet hub sub-boards
+	for (unsigned q = 0; q < cfg->total_qhubs; q++) {
+		for (unsigned s = 0; s < cfg->qhub[q]->subs; s++) {
+			if (cfg->qhub[q]->sub[s] == sub)
+				cfg->qhub[q]->sub[s] = NULL;
+		}
+	}
+	FREE_AND_NULL(cfg->sub[subnum]);
+	--cfg->total_subs;
+	for (unsigned i = subnum; i < cfg->total_subs; i++)
+		cfg->sub[i] = cfg->sub[i + 1];
+}
+
 void sub_cfg(uint grpnum)
 {
 	static int dflt,tog_dflt,opt_dflt,net_dflt,adv_dflt,bar;
 	char str[128],str2[128],done=0,code[128];
 	char path[MAX_PATH+1];
 	char data_dir[MAX_PATH+1];
-	int j,m,n,ptridx,q,s;
+	int j,m,n,ptridx;
 	uint i,subnum[MAX_OPTS+1];
 	static sub_t savsub;
 
@@ -291,15 +307,7 @@ void sub_cfg(uint grpnum)
 			}
 			if(msk == MSK_CUT)
 				savsub = *cfg.sub[subnum[i]];
-			free(cfg.sub[subnum[i]]);
-			cfg.total_subs--;
-			for(j=subnum[i];j<cfg.total_subs;j++)
-				cfg.sub[j]=cfg.sub[j+1];
-			for(q=0;q<cfg.total_qhubs;q++)
-				for(s=0;s<cfg.qhub[q]->subs;s++) {
-					if(cfg.qhub[q]->sub[s] == cfg.sub[subnum[i]])
-						cfg.qhub[q]->sub[s] = NULL;
-				}
+			remove_sub(&cfg, subnum[i]);
 			uifc.changes = TRUE;
 			continue; 
 		}
-- 
GitLab