diff --git a/src/sbbs3/sbbs.h b/src/sbbs3/sbbs.h
index 70809f25301f9e33f4ed03ff7ca5464e66933784..a86b644f8862518c6d246177b11fc7819e704430 100644
--- a/src/sbbs3/sbbs.h
+++ b/src/sbbs3/sbbs.h
@@ -773,6 +773,10 @@ public:
 	int		dir_op(int dirnum);
 	bool	is_valid_subnum(int subnum) { return ::is_valid_subnum(&cfg, subnum); }
 	bool	is_valid_dirnum(int dirnum) { return ::is_valid_dirnum(&cfg, dirnum); }
+	char*	dir_name(int dirnum) { return ::dir_name(&cfg, dirnum); }
+	char*	lib_name(int dirnum) { return ::lib_name(&cfg, dirnum); }
+	char*	sub_name(int subnum) { return ::sub_name(&cfg, subnum); }
+	char*	grp_name(int subnum) { return ::grp_name(&cfg, subnum); }
 
 	void	getmsgptrs(void);
 	void	putmsgptrs(void);
diff --git a/src/sbbs3/scfglib.h b/src/sbbs3/scfglib.h
index 6cbfb67796a73c3f812a276b3f373f9104e7e796..ccdad5f687b8f99bd6c97808d30c00d8059d2a36 100644
--- a/src/sbbs3/scfglib.h
+++ b/src/sbbs3/scfglib.h
@@ -65,6 +65,10 @@ int		getgurunum(scfg_t*, const char* code);
 int		getchatactset(scfg_t*, const char* name);
 int		getxeditnum(scfg_t*, const char* code);
 int		getshellnum(scfg_t*, const char* code);
+char*	lib_name(scfg_t*, int dirnum);
+char*	dir_name(scfg_t*, int dirnum);
+char*	grp_name(scfg_t*, int subnum);
+char*	sub_name(scfg_t*, int subnum);
 
 DLLEXPORT bool	is_valid_dirnum(scfg_t*, int);
 DLLEXPORT bool	is_valid_libnum(scfg_t*, int);
diff --git a/src/sbbs3/scfglib1.c b/src/sbbs3/scfglib1.c
index 2b14c5ac6b83b879691e642394f02ceeb5ed42e1..cda1bbd196f699823fb84c0941ed64cf8d693904 100644
--- a/src/sbbs3/scfglib1.c
+++ b/src/sbbs3/scfglib1.c
@@ -739,6 +739,40 @@ int getgrpnum(scfg_t* cfg, const char* code)
 	return i;
 }
 
+char* lib_name(scfg_t* cfg, int dirnum)
+{
+	if(!is_valid_dirnum(cfg, dirnum))
+		return "<invalid dir>";
+	int libnum = cfg->dir[dirnum]->lib;
+	if(!is_valid_libnum(cfg, libnum))
+		return "<invalid lib>";
+	return cfg->lib[libnum]->sname;
+}
+
+char* dir_name(scfg_t* cfg, int dirnum)
+{
+	if(!is_valid_dirnum(cfg, dirnum))
+		return "<invalid dir>";
+	return cfg->dir[dirnum]->sname;
+}
+
+char* grp_name(scfg_t* cfg, int subnum)
+{
+	if(!is_valid_subnum(cfg, subnum))
+		return "<invalid sub>";
+	int grpnum = cfg->sub[subnum]->grp;
+	if(!is_valid_grpnum(cfg, grpnum))
+		return "<invalid grp>";
+	return cfg->grp[grpnum]->sname;
+}
+
+char* sub_name(scfg_t* cfg, int subnum)
+{
+	if(!is_valid_subnum(cfg, subnum))
+		return "<invalid sub>";
+	return cfg->sub[subnum]->sname;
+}
+
 int getgrpnum_from_name(scfg_t* cfg, const char* name)
 {
 	int i;