From e7dc69a1549f699d180b37d7775f68aac9c17d1e Mon Sep 17 00:00:00 2001
From: Rob Swindell <rob@synchro.net>
Date: Thu, 3 Feb 2022 22:52:26 -0800
Subject: [PATCH] Better detection/rejection of duplicate sub and dir internal
 codes

When manually adding a message/file area or modifying an internal code value, reject the code if it's a duplicate.

This required that getsubnum() and getdirnum() support non-prepped configurations (where the full internal code has already been constructed from the prefix and suffix).
---
 src/sbbs3/scfg/scfg.c     |  8 +++---
 src/sbbs3/scfg/scfg.h     |  3 +++
 src/sbbs3/scfg/scfgchat.c |  8 +++---
 src/sbbs3/scfg/scfgsub.c  | 16 ++++++++---
 src/sbbs3/scfg/scfgxfr2.c | 16 ++++++++---
 src/sbbs3/scfg/scfgxtrn.c | 14 +++++-----
 src/sbbs3/scfglib1.c      | 56 ++++++++++++++++++++++-----------------
 7 files changed, 76 insertions(+), 45 deletions(-)

diff --git a/src/sbbs3/scfg/scfg.c b/src/sbbs3/scfg/scfg.c
index 0ee5b9cdec..c6f615a6f2 100644
--- a/src/sbbs3/scfg/scfg.c
+++ b/src/sbbs3/scfg/scfg.c
@@ -876,7 +876,7 @@ void txt_cfg()
 				continue;
 			if(!code_ok(code)) {
 				uifc.helpbuf=invalid_code;
-				uifc.msg("Invalid Code");
+				uifc.msg(strInvalidCode);
 				uifc.helpbuf=0;
 				continue; 
 			}
@@ -964,7 +964,7 @@ void txt_cfg()
 						SAFECOPY(cfg.txtsec[i]->code,str);
 					else {
 						uifc.helpbuf=invalid_code;
-						uifc.msg("Invalid Code");
+						uifc.msg(strInvalidCode);
 						uifc.helpbuf=0; 
 					}
 					break; 
@@ -1050,7 +1050,7 @@ void shell_cfg()
 				continue;
 			if(!code_ok(code)) {
 				uifc.helpbuf=invalid_code;
-				uifc.msg("Invalid Code");
+				uifc.msg(strInvalidCode);
 				uifc.helpbuf=0;
 				continue; 
 			}
@@ -1156,7 +1156,7 @@ void shell_cfg()
 						SAFECOPY(cfg.shell[i]->code,str);
 					else {
 						uifc.helpbuf=invalid_code;
-						uifc.msg("Invalid Code");
+						uifc.msg(strInvalidCode);
 						uifc.helpbuf=0; 
 					}
 					break;
diff --git a/src/sbbs3/scfg/scfg.h b/src/sbbs3/scfg/scfg.h
index 032e154cbb..eb933a83d0 100644
--- a/src/sbbs3/scfg/scfg.h
+++ b/src/sbbs3/scfg/scfg.h
@@ -68,6 +68,9 @@
 								"For a complete list of the supported command-line specifiers, see:\n"				\
 								"`http://wiki.synchro.net/config:cmdline`\n"
 
+#define strInvalidCode		"Invalid Internal Code Rejected!"
+#define strDuplicateCode	"Duplicate Internal Code Rejected!"
+
 /*************/
 /* Constants */
 /*************/
diff --git a/src/sbbs3/scfg/scfgchat.c b/src/sbbs3/scfg/scfgchat.c
index 902ca35411..72ab557a19 100644
--- a/src/sbbs3/scfg/scfgchat.c
+++ b/src/sbbs3/scfg/scfgchat.c
@@ -248,7 +248,7 @@ void chan_cfg()
 				continue;
 			if(!code_ok(code)) {
 				uifc.helpbuf=invalid_code;
-				uifc.msg("Invalid Code");
+				uifc.msg(strInvalidCode);
 				uifc.helpbuf=0;
 				continue; 
 			}
@@ -349,7 +349,7 @@ void chan_cfg()
 						SAFECOPY(cfg.chan[i]->code,str);
 					else {
 						uifc.helpbuf=invalid_code;
-						uifc.msg("Invalid Code");
+						uifc.msg(strInvalidCode);
 						uifc.helpbuf=0; 
 					}
 					break;
@@ -640,7 +640,7 @@ void guru_cfg()
 				continue;
 			if(!code_ok(code)) {
 				uifc.helpbuf=invalid_code;
-				uifc.msg("Invalid Code");
+				uifc.msg(strInvalidCode);
 				uifc.helpbuf=0;
 				continue; 
 			}
@@ -730,7 +730,7 @@ void guru_cfg()
 						SAFECOPY(cfg.guru[i]->code,str);
 					else {
 						uifc.helpbuf=invalid_code;
-						uifc.msg("Invalid Code");
+						uifc.msg(strInvalidCode);
 						uifc.helpbuf=0; 
 					}
 					break;
diff --git a/src/sbbs3/scfg/scfgsub.c b/src/sbbs3/scfg/scfgsub.c
index a68a5dd842..6adee146fe 100644
--- a/src/sbbs3/scfg/scfgsub.c
+++ b/src/sbbs3/scfg/scfgsub.c
@@ -253,9 +253,14 @@ void sub_cfg(uint grpnum)
 			if(uifc.input(WIN_MID|WIN_SAV,0,0,"Sub-board Internal Code Suffix",code,LEN_CODE
 				,K_EDIT|K_UPPER)<1)
 				continue;
+			SAFEPRINTF2(tmp, "%s%s", cfg.grp[grpnum]->code_prefix, code);
+			if(getsubnum(&cfg, tmp) >= 0) {
+				uifc.msg(strDuplicateCode);
+				continue;
+			}
 			if(!code_ok(code)) {
 				uifc.helpbuf=invalid_code;
-				uifc.msg("Invalid Code");
+				uifc.msg(strInvalidCode);
 				uifc.helpbuf=0;
 				continue; 
 			}
@@ -406,11 +411,16 @@ void sub_cfg(uint grpnum)
 					SAFECOPY(str,cfg.sub[i]->code_suffix);
 					uifc.input(WIN_MID|WIN_SAV,0,17,"Internal Code Suffix (unique)"
 						,str,LEN_CODE,K_EDIT|K_UPPER);
-					if(code_ok(str))
+					if(strcmp(str,cfg.sub[i]->code_suffix) == 0)
+						break;
+					SAFEPRINTF2(tmp, "%s%s", cfg.grp[cfg.sub[i]->grp]->code_prefix, str);
+					if(getsubnum(&cfg, tmp) >= 0)
+						uifc.msg(strDuplicateCode);
+					else if(code_ok(str))
 						SAFECOPY(cfg.sub[i]->code_suffix,str);
 					else {
 						uifc.helpbuf=invalid_code;
-						uifc.msg("Invalid Code");
+						uifc.msg(strInvalidCode);
 						uifc.helpbuf=0; 
 					}
 					break;
diff --git a/src/sbbs3/scfg/scfgxfr2.c b/src/sbbs3/scfg/scfgxfr2.c
index 372ba61a7e..823a6bda59 100644
--- a/src/sbbs3/scfg/scfgxfr2.c
+++ b/src/sbbs3/scfg/scfgxfr2.c
@@ -1077,9 +1077,14 @@ void dir_cfg(uint libnum)
 			if(uifc.input(WIN_MID|WIN_SAV,0,0,"Directory Internal Code Suffix",code,LEN_CODE
 				,K_EDIT|K_UPPER)<1)
 				continue;
+			SAFEPRINTF2(tmp, "%s%s", cfg.lib[libnum]->code_prefix, code);
+			if(getdirnum(&cfg, tmp) >= 0) {
+				uifc.msg(strDuplicateCode);
+				continue;
+			}
 			if(!code_ok(code)) {
 				uifc.helpbuf=invalid_code;
-				uifc.msg("Invalid Code");
+				uifc.msg(strInvalidCode);
 				uifc.helpbuf=0;
 				continue;
 			}
@@ -1238,11 +1243,16 @@ void dir_cfg(uint libnum)
 					SAFECOPY(str,cfg.dir[i]->code_suffix);
 					uifc.input(WIN_L2R|WIN_SAV,0,17,"Internal Code Suffix (unique)"
 						,str,LEN_CODE,K_EDIT|K_UPPER);
-					if(code_ok(str))
+					if(strcmp(str,cfg.dir[i]->code_suffix) == 0)
+						break;
+					SAFEPRINTF2(tmp, "%s%s", cfg.lib[cfg.dir[i]->lib]->code_prefix, str);
+					if(getdirnum(&cfg, tmp) >= 0)
+						uifc.msg(strDuplicateCode);
+					else if(code_ok(str))
 						SAFECOPY(cfg.dir[i]->code_suffix,str);
 					else {
 						uifc.helpbuf=invalid_code;
-						uifc.msg("Invalid Code");
+						uifc.msg(strInvalidCode);
 						uifc.helpbuf=0; 
 					}
 					break;
diff --git a/src/sbbs3/scfg/scfgxtrn.c b/src/sbbs3/scfg/scfgxtrn.c
index dc189928b7..06cf1c3d39 100644
--- a/src/sbbs3/scfg/scfgxtrn.c
+++ b/src/sbbs3/scfg/scfgxtrn.c
@@ -556,7 +556,7 @@ void tevents_cfg()
 						SAFECOPY(cfg.event[i]->code,str);
 					else {
 						uifc.helpbuf=invalid_code;
-						uifc.msg("Invalid Code");
+						uifc.msg(strInvalidCode);
 						uifc.helpbuf=0; 
 					}
 					break;
@@ -1093,7 +1093,7 @@ void xtrn_cfg(uint section)
 				continue;
 			if(!code_ok(code)) {
 				uifc.helpbuf=invalid_code;
-				uifc.msg("Invalid Code");
+				uifc.msg(strInvalidCode);
 				uifc.helpbuf=0;
 				continue; 
 			}
@@ -1234,7 +1234,7 @@ void xtrn_cfg(uint section)
 						SAFECOPY(cfg.xtrn[i]->code,str);
 					else {
 						uifc.helpbuf=invalid_code;
-						uifc.msg("Invalid Code");
+						uifc.msg(strInvalidCode);
 						uifc.helpbuf=0; 
 					}
 					break;
@@ -1699,7 +1699,7 @@ void xedit_cfg()
 				continue;
 			if(!code_ok(code)) {
 				uifc.helpbuf=invalid_code;
-				uifc.msg("Invalid Code");
+				uifc.msg(strInvalidCode);
 				uifc.helpbuf=0;
 				continue; 
 			}
@@ -1831,7 +1831,7 @@ void xedit_cfg()
 						SAFECOPY(cfg.xedit[i]->code,str);
 					else {
 						uifc.helpbuf=invalid_code;
-						uifc.msg("Invalid Code");
+						uifc.msg(strInvalidCode);
 						uifc.helpbuf=0; 
 					}
 					break;
@@ -2309,7 +2309,7 @@ void xtrnsec_cfg()
 				continue;
 			if(!code_ok(code)) {
 				uifc.helpbuf=invalid_code;
-				uifc.msg("Invalid Code");
+				uifc.msg(strInvalidCode);
 				uifc.helpbuf=0;
 				continue; 
 			}
@@ -2414,7 +2414,7 @@ void xtrnsec_cfg()
 						SAFECOPY(cfg.xtrnsec[i]->code,str);
 					else {
 						uifc.helpbuf=invalid_code;
-						uifc.msg("Invalid Code");
+						uifc.msg(strInvalidCode);
 						uifc.helpbuf=0; 
 					}
 					break;
diff --git a/src/sbbs3/scfglib1.c b/src/sbbs3/scfglib1.c
index 31f00fbf5d..5b55b7ea1a 100644
--- a/src/sbbs3/scfglib1.c
+++ b/src/sbbs3/scfglib1.c
@@ -764,52 +764,60 @@ void make_data_dirs(scfg_t* cfg)
 
 int getdirnum(scfg_t* cfg, const char* code)
 {
+	char fullcode[LEN_EXTCODE + 1];
 	size_t i;
 
 	if(code == NULL || *code == '\0')
 		return -1;
 
-	for(i=0;i<cfg->total_dirs;i++)
-		if(stricmp(cfg->dir[i]->code,code)==0)
-			return(i);
-	return(-1);
+	for(i=0;i<cfg->total_dirs;i++) {
+		if(cfg->dir[i]->code[0] == '\0' && cfg->dir[i]->lib < cfg->total_libs ) {
+			SAFEPRINTF2(fullcode, "%s%s", cfg->lib[cfg->dir[i]->lib]->code_prefix, cfg->dir[i]->code_suffix);
+			if(stricmp(fullcode, code) == 0)
+				return i;
+		} else {
+			if(stricmp(cfg->dir[i]->code, code)==0)
+				return i;
+		}
+	}
+	return -1;
 }
 
 int getlibnum(scfg_t* cfg, const char* code)
 {
-	size_t i;
+	int i = getdirnum(cfg, code);
 
-	if(code == NULL || *code == '\0')
-		return -1;
-
-	for(i=0;i<cfg->total_dirs;i++)
-		if(stricmp(cfg->dir[i]->code,code)==0)
-			return(cfg->dir[i]->lib);
-	return(-1);
+	if(i >= 0)
+		return cfg->dir[i]->lib;
+	return i;
 }
 
 int getsubnum(scfg_t* cfg, const char* code)
 {
+	char fullcode[LEN_EXTCODE + 1];
 	size_t i;
 
 	if(code == NULL || *code == '\0')
 		return -1;
 
-	for(i=0;i<cfg->total_subs;i++)
-		if(stricmp(cfg->sub[i]->code,code)==0)
-			return(i);
-	return(-1);
+	for(i=0;i<cfg->total_subs;i++) {
+		if(cfg->sub[i]->code[0] == '\0' && cfg->sub[i]->grp < cfg->total_grps ) {
+			SAFEPRINTF2(fullcode, "%s%s", cfg->grp[cfg->sub[i]->grp]->code_prefix, cfg->sub[i]->code_suffix);
+			if(stricmp(fullcode, code) == 0)
+				return i;
+		} else {
+			if(stricmp(cfg->sub[i]->code,code) == 0)
+				return i;
+		}
+	}
+	return -1;
 }
 
 int getgrpnum(scfg_t* cfg, const char* code)
 {
-	size_t i;
-
-	if(code == NULL || *code == '\0')
-		return -1;
+	int i = getdirnum(cfg, code);
 
-	for(i=0;i<cfg->total_subs;i++)
-		if(stricmp(cfg->sub[i]->code,code)==0)
-			return(cfg->sub[i]->grp);
-	return(-1);
+	if(i >= 0)
+			return cfg->sub[i]->grp;
+	return i;
 }
-- 
GitLab