From 16ab96939c851c590bfba3a034c27935f266cb6b Mon Sep 17 00:00:00 2001
From: "Rob Swindell (on Windows 11)" <rob@synchro.net>
Date: Tue, 12 Nov 2024 19:04:41 -0800
Subject: [PATCH] Use (new) make_newsgroup_name() function

... to be sure configured newsgroup name is RFC compliant.
---
 src/sbbs3/scfg/scfgsub.c | 18 ++++++++++++------
 src/sbbs3/scfglib1.c     | 35 +++++------------------------------
 2 files changed, 17 insertions(+), 36 deletions(-)

diff --git a/src/sbbs3/scfg/scfgsub.c b/src/sbbs3/scfg/scfgsub.c
index 9659d7e065..9508c901ac 100644
--- a/src/sbbs3/scfg/scfgsub.c
+++ b/src/sbbs3/scfg/scfgsub.c
@@ -292,8 +292,10 @@ void sub_cfg(int grpnum)
 			SAFECOPY(cfg.sub[subnum[i]]->lname,str);
 			SAFECOPY(cfg.sub[subnum[i]]->sname,str2);
 			SAFECOPY(cfg.sub[subnum[i]]->qwkname,code);
-			if(strchr(str,'.') && strchr(str,' ')==NULL)
+			if(strchr(str,'.') && strchr(str,' ')==NULL) {
 				SAFECOPY(cfg.sub[subnum[i]]->newsgroup,str);
+				make_newsgroup_name(cfg.sub[subnum[i]]->newsgroup);
+			}
 			uifc.changes = TRUE;
 			continue;
 		}
@@ -353,9 +355,10 @@ void sub_cfg(int grpnum)
 			else
 				SAFEPRINTF(area_tag, "[%s]", sub_area_tag(&cfg, cfg.sub[i], tmp, sizeof(tmp)));
 			char newsgroup_name[sizeof(cfg.sub[i]->newsgroup) + 2];
-			if(cfg.sub[i]->newsgroup[0])
+			if(cfg.sub[i]->newsgroup[0]) {
 				SAFECOPY(newsgroup_name, cfg.sub[i]->newsgroup);
-			else
+				make_newsgroup_name(newsgroup_name);
+			} else
 				SAFEPRINTF(newsgroup_name, "[%s]", sub_newsgroup_name(&cfg, cfg.sub[i], tmp, sizeof(tmp)));
 			snprintf(opt[n++], MAX_OPLN, "%-27.27s%s","Long Name",cfg.sub[i]->lname);
 			snprintf(opt[n++], MAX_OPLN, "%-27.27s%s","Short Name",cfg.sub[i]->sname);
@@ -476,10 +479,13 @@ void sub_cfg(int grpnum)
 						"is configured here, a name will be automatically generated from the\n"
 						"Sub-board's Short Name and message group's Short Name.\n"
 						"\n"
-						"This name should ~ not ~ contain spaces."
+						"A newsgroup name (per RFC 5536) may ~ only ~ contain the characters:\n"
+						"    [`a-z`], [`A-Z`], [`0-9`], '`+`', '`_`', '`-`', and '`.`'.\n"
+						"A newsgroup name may not begin or end with a '`.`'.\n"
 					;
-					uifc.input(WIN_MID|WIN_SAV,0,17,""
-						,cfg.sub[i]->newsgroup,sizeof(cfg.sub[i]->newsgroup)-1,K_EDIT);
+					if(uifc.input(WIN_MID|WIN_SAV,0,17,""
+						,cfg.sub[i]->newsgroup,sizeof(cfg.sub[i]->newsgroup)-1,K_EDIT) > 0)
+						make_newsgroup_name(cfg.sub[i]->newsgroup);
 					break;
 				case 5:
 					uifc.helpbuf=
diff --git a/src/sbbs3/scfglib1.c b/src/sbbs3/scfglib1.c
index 740603d9db..03453d7763 100644
--- a/src/sbbs3/scfglib1.c
+++ b/src/sbbs3/scfglib1.c
@@ -26,6 +26,7 @@
 #include "findstr.h"
 #include "ini_file.h"
 #include "sockwrap.h"	 // IPPORT_MQTT
+#include "str_util.h"
 
 bool allocerr(char* error, size_t maxerrlen, const char* fname, const char *item, size_t size)
 {
@@ -934,37 +935,11 @@ faddr_t* nearest_sysfaddr(scfg_t* cfg, faddr_t* addr)
 
 char* sub_newsgroup_name(scfg_t* cfg, sub_t* sub, char* str, size_t size)
 {
-	memset(str, 0, size);
 	if(sub->newsgroup[0])
-		strncpy(str, sub->newsgroup, size - 1);
-	else {
-		snprintf(str, size - 1, "%s.%s", cfg->grp[sub->grp]->sname, sub->sname);
-		/*
-		 * From RFC5536:
-		 * newsgroup-name  =  component *( "." component )
-		 * component       =  1*component-char
-		 * component-char  =  ALPHA / DIGIT / "+" / "-" / "_"
-		 */
-		if (str[0] == '.')
-			str[0] = '_';
-		size_t c;
-		for(c = 0; str[c] != 0; c++) {
-			/* Legal characters */
-			if ((str[c] >= 'A' && str[c] <= 'Z')
-					|| (str[c] >= 'a' && str[c] <= 'z')
-					|| (str[c] >= '0' && str[c] <= '9')
-					|| str[c] == '+'
-					|| str[c] == '-'
-					|| str[c] == '_'
-					|| str[c] == '.')
-				continue;
-			str[c] = '_';
-		}
-		c--;
-		if (str[c] == '.')
-			str[c] = '_';
-	}
-	return str;
+		strlcpy(str, sub->newsgroup, size);
+	else
+		snprintf(str, size, "%s.%s", cfg->grp[sub->grp]->sname, sub->sname);
+	return make_newsgroup_name(str);
 }
 
 char* sub_area_tag(scfg_t* cfg, sub_t* sub, char* str, size_t size)
-- 
GitLab