diff --git a/src/sbbs3/scfg/scfgsub.c b/src/sbbs3/scfg/scfgsub.c
index 70499bf342872a6433d73fe97ec58fb7c7f30705..79730b37b556bd151dccfa1818a82b5de6e71a31 100644
--- a/src/sbbs3/scfg/scfgsub.c
+++ b/src/sbbs3/scfg/scfgsub.c
@@ -32,6 +32,56 @@
  ****************************************************************************/
 
 #include "scfg.h"
+#include <stdbool.h>
+
+static bool new_sub(unsigned new_subnum, unsigned group_num)
+{
+	sub_t* new_subboard;
+	if ((new_subboard = (sub_t *)malloc(sizeof(*new_subboard))) == NULL) {
+		errormsg(WHERE, ERR_ALLOC, "sub-board", sizeof(*new_subboard));
+		return false;
+	}
+	memset(new_subboard, 0, sizeof(*new_subboard));
+	new_subboard->grp = group_num;
+	if (cfg.total_faddrs)
+		new_subboard->faddr = cfg.faddr[0];
+	/* ToDo: Define these defaults somewhere else: */
+	new_subboard->misc = (SUB_NSDEF | SUB_SSDEF | SUB_QUOTE | SUB_TOUSER | SUB_HDRMOD | SUB_FAST);
+	new_subboard->maxmsgs = 500;
+
+	/* Allocate a new (unused) pointer index */
+	for (; new_subboard->ptridx < USHRT_MAX; new_subboard->ptridx++) {
+		int n;
+		for (n = 0; n < cfg.total_subs; n++)
+			if (cfg.sub[n]->ptridx == new_subboard->ptridx)
+				break;
+		if (n == cfg.total_subs)
+			break;
+	}
+
+	sub_t **new_sub_list;
+	if ((new_sub_list = (sub_t **)realloc(cfg.sub, sizeof(sub_t *)*(cfg.total_subs + 1))) == NULL) {
+		errormsg(WHERE, ERR_ALLOC, "sub list", cfg.total_subs + 1);
+		free(new_subboard);
+		return false;
+	}
+	cfg.sub = new_sub_list;
+
+	/* Move higher numbered subs (for inserting) */
+	for (unsigned u = cfg.total_subs; u > new_subnum; u--)
+		cfg.sub[u] = cfg.sub[u - 1];
+
+	/* Subs are re-numbered, so adjust QWKnet hub sub lists */
+	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] >= new_subnum)
+				cfg.qhub[q]->sub[s]++;
+
+	cfg.sub[new_subnum] = new_subboard;
+	cfg.total_subs++;
+	return true;
+}
+
 
 void sub_cfg(uint grpnum)
 {
@@ -40,7 +90,7 @@ void sub_cfg(uint grpnum)
 	char path[MAX_PATH+1];
 	char data_dir[MAX_PATH+1];
 	int j,m,n,ptridx,q,s;
-	uint i,u,subnum[MAX_OPTS+1];
+	uint i,subnum[MAX_OPTS+1];
 	static sub_t savsub;
 
 while(1) {
@@ -62,7 +112,7 @@ while(1) {
 	if(j)
 		i|=WIN_DEL|WIN_GET|WIN_DELACT;
 	if(j<MAX_OPTS)
-		i|=WIN_INS|WIN_XTR|WIN_INSACT;
+		i|=WIN_INS|WIN_XTR|WIN_PUTXTR|WIN_INSACT;
 	if(savsub.sname[0])
 		i|=WIN_PUT;
 	uifc.helpbuf=
@@ -121,7 +171,7 @@ while(1) {
 			"\n"
 			"Every sub-board must have its own unique code for Synchronet to refer to\n"
 			"it internally. This code should be descriptive of the sub-board's topic,\n"
-			"usually an abreviation of the sub-board's name.\n"
+			"usually an abbreviation of the sub-board's name.\n"
 			"\n"
 			"`Note:` The internal code is constructed from the message group's code\n"
 			"prefix (if present) and the sub-board's code suffix.\n"
@@ -136,55 +186,20 @@ while(1) {
 			continue; 
 		}
 
-		if((cfg.sub=(sub_t **)realloc(cfg.sub,sizeof(sub_t *)*(cfg.total_subs+1)))==NULL) {
-            errormsg(WHERE,ERR_ALLOC,nulstr,cfg.total_subs+1);
-			cfg.total_subs=0;
-			bail(1);
-            continue; 
-		}
-
-		for(ptridx=0;ptridx<USHRT_MAX;ptridx++) { /* Search for unused pointer indx */
-            for(n=0;n<cfg.total_subs;n++)
-				if(cfg.sub[n]->ptridx==ptridx)
-                    break;
-            if(n==cfg.total_subs)
-                break; 
-		}
-
-		if(j) {
-			for(u=cfg.total_subs;u>subnum[i];u--)
-                cfg.sub[u]=cfg.sub[u-1];
-			for(q=0;q<cfg.total_qhubs;q++)
-				for(s=0;s<cfg.qhub[q]->subs;s++)
-					if(cfg.qhub[q]->sub[s]>=subnum[i])
-						cfg.qhub[q]->sub[s]++; 
-		}
+		if (!new_sub(subnum[i], grpnum))
+			continue;
 
-		if((cfg.sub[subnum[i]]=(sub_t *)malloc(sizeof(sub_t)))==NULL) {
-			errormsg(WHERE,ERR_ALLOC,nulstr,sizeof(sub_t));
-			continue; 
-		}
-		memset((sub_t *)cfg.sub[subnum[i]],0,sizeof(sub_t));
-		cfg.sub[subnum[i]]->grp=grpnum;
-		if(cfg.total_faddrs)
-			cfg.sub[subnum[i]]->faddr=cfg.faddr[0];
-		else
-			memset(&cfg.sub[subnum[i]]->faddr,0,sizeof(faddr_t));
-		cfg.sub[subnum[i]]->maxmsgs=500;
 		strcpy(cfg.sub[subnum[i]]->code_suffix,code);
 		strcpy(cfg.sub[subnum[i]]->lname,str);
 		strcpy(cfg.sub[subnum[i]]->sname,str2);
 		strcpy(cfg.sub[subnum[i]]->qwkname,code);
 		if(strchr(str,'.') && strchr(str,' ')==NULL)
 			strcpy(cfg.sub[subnum[i]]->newsgroup,str);
-		cfg.sub[subnum[i]]->misc=(SUB_NSDEF|SUB_SSDEF|SUB_QUOTE|SUB_TOUSER
-			|SUB_HDRMOD|SUB_FAST);
-		cfg.sub[subnum[i]]->ptridx=ptridx;
-		cfg.total_subs++;
 		uifc.changes=1;
 		continue; 
-}
-	if((i&MSK_ON)==MSK_DEL) {
+	}
+	if((i&MSK_ON) == MSK_DEL || (i&MSK_ON) == MSK_CUT) {
+		int msk = (i&MSK_ON);
 		i&=MSK_OFF;
 		uifc.helpbuf=
 			"`Delete Data in Sub-board:`\n"
@@ -213,6 +228,8 @@ while(1) {
 					clearptrs(subnum[i]); 
 			}
 		}
+		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++)
@@ -234,6 +251,10 @@ while(1) {
 	}
 	if((i&MSK_ON)==MSK_PUT) {
 		i&=MSK_OFF;
+		if (opt[i][0] == 0) {	/* Paste-over extra/blank item */
+			if (!new_sub(subnum[i], grpnum))
+				continue;
+		}
 		ptridx=cfg.sub[subnum[i]]->ptridx;
 		*cfg.sub[subnum[i]]=savsub;
 		cfg.sub[subnum[i]]->ptridx=ptridx;
@@ -331,7 +352,7 @@ while(1) {
 	                "\n"
 	                "Every sub-board must have its own unique code for Synchronet to refer\n"
 	                "to it internally. This code should be descriptive of the sub-board's\n"
-	                "topic, usually an abreviation of the sub-board's name.\n"
+	                "topic, usually an abbreviation of the sub-board's name.\n"
 	                "\n"
 	                "`Note:` The internal code displayed is the complete internal code\n"
 	                "constructed from the message group's code prefix and the sub-board's\n"
@@ -841,7 +862,7 @@ while(1) {
 								"`Operator Messages Automatically Permanent:`\n"
 								"\n"
 								"If you want messages posted by `System` and `Sub-board Operators` to be\n"
-								"automatically permanent (non-purgable) for this sub-board, set this\n"
+								"automatically permanent (non-purgeable) for this sub-board, set this\n"
 								"option to `Yes`.\n"
 							;
 							n=uifc.list(WIN_SAV|WIN_MID,0,0,0,&n,0
@@ -858,7 +879,7 @@ while(1) {
 								cfg.sub[i]->misc&=~SUB_SYSPERM; 
 							}
                             break;
-#if 0 /* This is not actually imlemented (yet?) */
+#if 0 /* This is not actually implemented (yet?) */
 						case 12:
 							if(cfg.sub[i]->misc&SUB_KILLP)
 								n=2;
@@ -1238,20 +1259,20 @@ while(1) {
 								"`Self-Packing` is the slowest storage method because it conserves disk\n"
 								"  space as it imports messages by using deleted message header and data\n"
 								"  blocks for new messages automatically. If you use this storage method,\n"
-								"  you will not need to run `SMBUTIL P` on this message base unless you\n"
+								"  you will not need to run `smbutil p` on this message base unless you\n"
 								"  accumilate a large number of deleted message blocks and wish to free\n"
 								"  that disk space. You can switch from self-packing to fast allocation\n"
 								"  storage method and back again as you wish.\n"
 								"`Fast Allocation` is faster than self-packing because it does not search\n"
 								"  for deleted message blocks for new messages. It automatically places\n"
 								"  all new message blocks at the end of the header and data files. If you\n"
-								"  use this storage method, you will need to run `SMBUTIL P` on this\n"
+								"  use this storage method, you will need to run `smbutil p` on this\n"
 								"  message base periodically or it will continually use up disk space.\n"
 								"`Hyper Allocation` is the fastest storage method because it does not\n"
 								"  maintain allocation files at all. Once a message base is setup to use\n"
 								"  this storage method, it should not be changed without first deleting\n"
-								"  the message base data files in your `DATA\\DIRS\\SUBS` directory for this\n"
-								"  sub-board. You must use `SMBUTIL P` as with the fast allocation method.\n"
+								"  the message base data files in your `data/subs` directory for this\n"
+								"  sub-board. You must use `smbutil p` as with the fast allocation method.\n"
 							;
 							n=uifc.list(WIN_SAV|WIN_MID,0,0,0,&n,0
 								,"Storage Method",opt);