diff --git a/docs/newfilebase.txt b/docs/newfilebase.txt
index 12b9e2a5e4cfbcefbfd71af00121673ec510b490..90fb84fc42c01b0c57939d9a4f93a8789b36e7a4 100644
--- a/docs/newfilebase.txt
+++ b/docs/newfilebase.txt
@@ -112,6 +112,20 @@ another file in a filebase already. Each directory is configurable as to
 whether or not to hash its files or use it for duplicate file detection
 (by name or hash).
 
+_Sorting_
+
+The new filebases are indexed in the order in which the files are imported
+into the database. Sorting of the files for display purposes in the terminal
+and FTP servers is optional and configured by the sysop:
+ Name Ascending (case-insensitive)
+ Name Descending (case-insensitive)
+ Name Ascending (case-sensitive)
+ Name Descending (case-sensitive)
+ Date Ascending
+ Date Descending
+
+As a result, the "RESORT" file transfer operator command has been removed.
+
 _Tags_
 
 Individual files can now be tagged for easy searching/grouping. This feature
diff --git a/src/sbbs3/addfiles.c b/src/sbbs3/addfiles.c
index 9f5f2d0ba27d75e746fa53c171bf064303497947..5084404f22c090cb727a79021fdbfc4dd0bf1425 100644
--- a/src/sbbs3/addfiles.c
+++ b/src/sbbs3/addfiles.c
@@ -165,7 +165,7 @@ void addlist(char *inpath, uint dirnum, const char* uploader, uint dskip, uint s
 		fprintf(stderr, "!Error %d (%s) opening %s\n", result, smb.last_error, smb.file);
 		return;
 	}
-	str_list_t fname_list = loadfilenames(&scfg, &smb, ALLFILES, /* time: */0, /* sort: */FALSE, /* count: */NULL);
+	str_list_t fname_list = loadfilenames(&smb, ALLFILES, /* time: */0, FILE_SORT_NATURAL, /* count: */NULL);
 	if(mode&SEARCH_DIR) {
 		SAFECOPY(str,cur_altpath ? scfg.altpath[cur_altpath-1] : scfg.dir[dirnum]->path);
 		printf("Searching %s\n\n",str);
@@ -463,7 +463,7 @@ void synclist(char *inpath, int dirnum)
 		return;
 	}
 	size_t file_count;
-	file_list = loadfiles(&scfg, &smb, NULL, 0, /* extdesc: */FALSE, /* sort: */TRUE, &file_count);
+	file_list = loadfiles(&smb, NULL, 0, /* extdesc: */FALSE, FILE_SORT_NATURAL, &file_count);
 
 	printf("\nSynchronizing %s with %s %s\n\n"
 		,listpath,scfg.lib[scfg.dir[dirnum]->lib]->sname,scfg.dir[dirnum]->sname);
diff --git a/src/sbbs3/delfiles.c b/src/sbbs3/delfiles.c
index d64f94388be487cf55d480ba91665ba9039693c8..f54c6d51495f01c54ef652aba2e26ca262687745 100644
--- a/src/sbbs3/delfiles.c
+++ b/src/sbbs3/delfiles.c
@@ -243,7 +243,7 @@ int main(int argc, char **argv)
 		printf("\nScanning %s %s\n", cfg.lib[cfg.dir[i]->lib]->sname, cfg.dir[i]->lname);
 
 		size_t file_count;
-		smbfile_t* file_list = loadfiles(&cfg, &smb, NULL, 0, /* extdesc: */FALSE, /* sort: */TRUE, &file_count);
+		smbfile_t* file_list = loadfiles(&smb, NULL, 0, /* extdesc: */FALSE, FILE_SORT_NATURAL, &file_count);
 
 		for(fi = 0; fi < file_count; fi++) {
 			smbfile_t* f = &file_list[fi];
diff --git a/src/sbbs3/filedat.c b/src/sbbs3/filedat.c
index 4a27ab01c590c5f3deaa1f009f031796a6667537..53e9e5ca9cc584e2969ac6232c074a7db7bd9200 100644
--- a/src/sbbs3/filedat.c
+++ b/src/sbbs3/filedat.c
@@ -110,19 +110,20 @@ static int filename_compare_dc(const void *arg1, const void *arg2)
    return strcmp(*(char**) arg2, *(char**) arg1);
 }
 
+// Note: does not support sorting by date
 void sortfilenames(str_list_t filelist, size_t count, enum file_sort order)
 {
 	switch(order) {
-		case SORT_NAME_A:
+		case FILE_SORT_NAME_A:
 			qsort(filelist, count, sizeof(*filelist), filename_compare_a);
 			break;
-		case SORT_NAME_D:
+		case FILE_SORT_NAME_D:
 			qsort(filelist, count, sizeof(*filelist), filename_compare_d);
 			break;
-		case SORT_NAME_AC:
+		case FILE_SORT_NAME_AC:
 			qsort(filelist, count, sizeof(*filelist), filename_compare_ac);
 			break;
-		case SORT_NAME_DC:
+		case FILE_SORT_NAME_DC:
 			qsort(filelist, count, sizeof(*filelist), filename_compare_dc);
 			break;
 		default:
@@ -131,7 +132,8 @@ void sortfilenames(str_list_t filelist, size_t count, enum file_sort order)
 }
 
 // Return an optionally-sorted dynamically-allocated string list of filenames added since date/time (t)
-str_list_t loadfilenames(scfg_t* cfg, smb_t* smb, const char* filespec, time_t t, bool sort, size_t* count)
+// Note: does not support sorting by date (exception: natural sort order of date-ascending)
+str_list_t loadfilenames(smb_t* smb, const char* filespec, time_t t, enum file_sort order, size_t* count)
 {
 	size_t count_;
 
@@ -171,14 +173,14 @@ str_list_t loadfilenames(scfg_t* cfg, smb_t* smb, const char* filespec, time_t t
 		file_list[*count] = strdup(fidx.name);
 		(*count)++;
 	}
-	if(sort)
-		sortfilenames(file_list, *count, (enum file_sort)cfg->dir[smb->dirnum]->sort);
+	if(order != FILE_SORT_NATURAL)
+		sortfilenames(file_list, *count, order);
 
 	return file_list;
 }
 
 // Load and optionally-sort files from an open filebase into a dynamically-allocated list of "objects"
-smbfile_t* loadfiles(scfg_t* cfg, smb_t* smb, const char* filespec, time_t t, enum file_detail detail, bool sort, size_t* count)
+smbfile_t* loadfiles(smb_t* smb, const char* filespec, time_t t, enum file_detail detail, enum file_sort order, size_t* count)
 {
 	*count = 0;
 
@@ -218,8 +220,8 @@ smbfile_t* loadfiles(scfg_t* cfg, smb_t* smb, const char* filespec, time_t t, en
 			break;
 		(*count)++;
 	}
-	if(sort)
-		sortfiles(file_list, *count, (enum file_sort)cfg->dir[smb->dirnum]->sort);
+	if(order != FILE_SORT_NATURAL)
+		sortfiles(file_list, *count, order);
 
 	return file_list;
 }
@@ -275,22 +277,22 @@ static int file_compare_date_d(const void* v1, const void* v2)
 void sortfiles(smbfile_t* filelist, size_t count, enum file_sort order)
 {
 	switch(order) {
-		case SORT_NAME_A:
+		case FILE_SORT_NAME_A:
 			qsort(filelist, count, sizeof(*filelist), file_compare_name_a);
 			break;
-		case SORT_NAME_D:
+		case FILE_SORT_NAME_D:
 			qsort(filelist, count, sizeof(*filelist), file_compare_name_d);
 			break;
-		case SORT_NAME_AC:
+		case FILE_SORT_NAME_AC:
 			qsort(filelist, count, sizeof(*filelist), file_compare_name_ac);
 			break;
-		case SORT_NAME_DC:
+		case FILE_SORT_NAME_DC:
 			qsort(filelist, count, sizeof(*filelist), file_compare_name_dc);
 			break;
-		case SORT_DATE_A:
+		case FILE_SORT_DATE_A:
 			qsort(filelist, count, sizeof(*filelist), file_compare_date_a);
 			break;
-		case SORT_DATE_D:
+		case FILE_SORT_DATE_D:
 			qsort(filelist, count, sizeof(*filelist), file_compare_date_d);
 			break; 
 	}
diff --git a/src/sbbs3/filedat.h b/src/sbbs3/filedat.h
index 8a3f01375f8851ac34ab7413eb3768b654f5867d..8f3bad952b3048435022652b8b48d7e233431caf 100644
--- a/src/sbbs3/filedat.h
+++ b/src/sbbs3/filedat.h
@@ -39,12 +39,12 @@ DLLEXPORT time_t		dir_newfiletime(scfg_t*, uint dirnum);
 DLLEXPORT time_t		lastfiletime(smb_t*); // Reads the last index record
 
 DLLEXPORT bool			findfile(scfg_t* cfg, uint dirnum, const char *filename, smbfile_t*);
-DLLEXPORT bool			loadfile(scfg_t*, uint dirnum, const char* filename, smbfile_t*, enum file_detail detail);
-DLLEXPORT smbfile_t*	loadfiles(scfg_t*, smb_t*, const char* filespec, time_t, enum file_detail detail, bool sort, size_t* count);
+DLLEXPORT bool			loadfile(scfg_t*, uint dirnum, const char* filename, smbfile_t*, enum file_detail);
+DLLEXPORT smbfile_t*	loadfiles(smb_t*, const char* filespec, time_t, enum file_detail, enum file_sort, size_t* count);
 DLLEXPORT void			sortfiles(smbfile_t*, size_t count, enum file_sort);
 DLLEXPORT void			freefiles(smbfile_t*, size_t count);
-DLLEXPORT str_list_t	loadfilenames(scfg_t*, smb_t*, const char* filespec, time_t t, bool sort, size_t* count);
-DLLEXPORT void			sortfilenames(str_list_t, size_t count, enum file_sort order);
+DLLEXPORT str_list_t	loadfilenames(smb_t*, const char* filespec, time_t t, enum file_sort, size_t* count);
+DLLEXPORT void			sortfilenames(str_list_t, size_t count, enum file_sort);
 DLLEXPORT bool			updatefile(scfg_t*, smbfile_t*);
 DLLEXPORT char*			getfilepath(scfg_t*, smbfile_t*, char* path);
 DLLEXPORT off_t			getfilesize(scfg_t*, smbfile_t*);
diff --git a/src/sbbs3/filelist.c b/src/sbbs3/filelist.c
index 2750337307ee0d6de17fc32e38635b529b276275..5775fbf7f43dd63dbe680f4327cb1606998a22e1 100644
--- a/src/sbbs3/filelist.c
+++ b/src/sbbs3/filelist.c
@@ -339,8 +339,8 @@ int main(int argc, char **argv)
 		if(max_age)
 			t = time(NULL) - (max_age * 24 * 60 * 60);
 		ulong file_count;
-		smbfile_t* file_list = loadfiles(&scfg, &smb
-			,/* filespec: */pattern, /* time: */t, /* extdesc: */TRUE, /* sort: */TRUE, &file_count);
+		smbfile_t* file_list = loadfiles(&smb
+			,/* filespec: */pattern, /* time: */t, /* extdesc: */TRUE, scfg.dir[i]->sort, &file_count);
 
 		if(misc&AUTO) {
 			sprintf(str,"%sFILES.BBS",scfg.dir[i]->path);
diff --git a/src/sbbs3/ftpsrvr.c b/src/sbbs3/ftpsrvr.c
index 7ca7b89d4ecde99c7b753192e4d1a70d7e836a53..303d0bc4d09ac065c49b5c1aae76bfed82825543 100644
--- a/src/sbbs3/ftpsrvr.c
+++ b/src/sbbs3/ftpsrvr.c
@@ -3730,8 +3730,8 @@ static void ctrl_thread(void* arg)
 					}
 					time_t start = time(NULL);
 					size_t file_count = 0;
-					smbfile_t* file_list = loadfiles(&scfg, &smb
-						,/* filespec */NULL, /* time: */0, file_detail_normal, /* sort: */TRUE, &file_count);
+					smbfile_t* file_list = loadfiles(&smb
+						,/* filespec */NULL, /* time: */0, file_detail_normal, scfg.dir[dir]->sort, &file_count);
 					for(size_t i = 0; i < file_count; i++) {
 						smbfile_t* f = &file_list[i];
 						if (cmd[3] != 'D' && strcmp(f->name, mls_fname) != 0)
@@ -4017,8 +4017,8 @@ static void ctrl_thread(void* arg)
 				}
 				time_t start = time(NULL);
 				size_t file_count = 0;
-				smbfile_t* file_list = loadfiles(&scfg, &smb
-					,filespec, /* time: */0, file_detail_normal, /* sort: */TRUE, &file_count);
+				smbfile_t* file_list = loadfiles(&smb
+					,filespec, /* time: */0, file_detail_normal, scfg.dir[dir]->sort, &file_count);
 				for(size_t i = 0; i < file_count; i++) {
 					smbfile_t* f = &file_list[i];
 					if(detail) {
@@ -4306,8 +4306,8 @@ static void ctrl_thread(void* arg)
 						}
 						time_t start = time(NULL);
 						size_t file_count = 0;
-						smbfile_t* file_list = loadfiles(&scfg, &smb
-							,/* filespec */NULL, /* time: */0, file_detail_normal, /* sort: */TRUE, &file_count);
+						smbfile_t* file_list = loadfiles(&smb
+							,/* filespec */NULL, /* time: */0, file_detail_normal, scfg.dir[dir]->sort, &file_count);
 						for(size_t i = 0; i < file_count; i++) {
 							smbfile_t* f = &file_list[i];
 							fprintf(fp,"%-*s %s\r\n",INDEX_FNAME_LEN
diff --git a/src/sbbs3/js_filebase.c b/src/sbbs3/js_filebase.c
index 22f41e9f1dcfe810b2ef06a0d3c694f2ded2ceda..fa203015d7f6adad67c792026c0ab7de25c322f1 100644
--- a/src/sbbs3/js_filebase.c
+++ b/src/sbbs3/js_filebase.c
@@ -568,7 +568,7 @@ js_get_file_list(JSContext *cx, uintN argc, jsval *arglist)
 	time_t		t = 0;
 	char*		filespec = NULL;
 	enum file_detail detail = file_detail_normal;
-	BOOL		sort = TRUE;
+	enum file_sort sort = FILE_SORT_NAME_A;
 	jsrefcount	rc;
 
 	JS_SET_RVAL(cx, arglist, JSVAL_FALSE);
@@ -587,6 +587,9 @@ js_get_file_list(JSContext *cx, uintN argc, jsval *arglist)
 		return JS_FALSE;
 	}
 
+	if(p->smb.dirnum != INVALID_DIR)
+		sort = scfg->dir[p->smb.dirnum]->sort;
+
 	uintN argn = 0;
 	if(argn < argc && JSVAL_IS_STRING(argv[argn]))	{
 		JSVALUE_TO_MSTRING(cx, argv[argn], filespec, NULL);
@@ -604,8 +607,12 @@ js_get_file_list(JSContext *cx, uintN argc, jsval *arglist)
 		argn++;
 	}
 	if(argn < argc && JSVAL_IS_BOOLEAN(argv[argn])) {
-		sort = JSVAL_TO_BOOLEAN(argv[argn]);
-		argn++;
+		if(argv[argn++] == JSVAL_FALSE)
+			sort = FILE_SORT_NATURAL;
+		else if(argn < argc && JSVAL_IS_NUMBER(argv[argn])) {
+			sort = JSVAL_TO_INT(argv[argn]);
+			argn++;
+		}
 	}
 
 	rc=JS_SUSPENDREQUEST(cx);
@@ -618,7 +625,7 @@ js_get_file_list(JSContext *cx, uintN argc, jsval *arglist)
 	}
 
 	size_t file_count;
-	smbfile_t* file_list = loadfiles(scfg, &p->smb, filespec, t, detail, sort, &file_count);
+	smbfile_t* file_list = loadfiles(&p->smb, filespec, t, detail, sort, &file_count);
 	if(file_list != NULL) {
 		for(size_t i = 0; i < file_count; i++) {
 			JSObject* fobj;
@@ -646,7 +653,7 @@ js_get_file_names(JSContext *cx, uintN argc, jsval *arglist)
 	private_t*	p;
 	time_t		t = 0;
 	char*		filespec = NULL;
-	BOOL		sort = TRUE;
+	enum file_sort sort = FILE_SORT_NAME_A;
 	jsrefcount	rc;
 
 	JS_SET_RVAL(cx, arglist, JSVAL_FALSE);
@@ -665,6 +672,9 @@ js_get_file_names(JSContext *cx, uintN argc, jsval *arglist)
 		return JS_FALSE;
 	}
 
+	if(p->smb.dirnum != INVALID_DIR)
+		sort = scfg->dir[p->smb.dirnum]->sort;
+
 	uintN argn = 0;
 	if(argn < argc && JSVAL_IS_STRING(argv[argn]))	{
 		JSVALUE_TO_MSTRING(cx, argv[argn], filespec, NULL);
@@ -678,8 +688,12 @@ js_get_file_names(JSContext *cx, uintN argc, jsval *arglist)
 		argn++;
 	}
 	if(argn < argc && JSVAL_IS_BOOLEAN(argv[argn])) {
-		sort = JSVAL_TO_BOOLEAN(argv[argn]);
-		argn++;
+		if(argv[argn++] == JSVAL_FALSE)
+			sort = FILE_SORT_NATURAL;
+		else if(argn < argc && JSVAL_IS_NUMBER(argv[argn])) {
+			sort = JSVAL_TO_INT(argv[argn]);
+			argn++;
+		}
 	}
 
 	rc=JS_SUSPENDREQUEST(cx);
@@ -691,7 +705,7 @@ js_get_file_names(JSContext *cx, uintN argc, jsval *arglist)
 		return JS_FALSE;
 	}
 
-	str_list_t file_list = loadfilenames(scfg, &p->smb, filespec, t, sort, NULL);
+	str_list_t file_list = loadfilenames(&p->smb, filespec, t, sort, NULL);
 	if(file_list != NULL) {
 		for(size_t i = 0; file_list[i] != NULL; i++) {
 			JSString* js_str;
@@ -1319,7 +1333,7 @@ static char* filebase_prop_desc[] = {
 	,"maximum number of files before expiration - <small>READ ONLY</small>"
 	,"maximum age (in days) of files to store - <small>READ ONLY</small>"
 	,"file base attributes - <small>READ ONLY</small>"
-	,"directory number (0-based) - <small>READ ONLY</small>"
+	,"directory number (0-based, -1 if invalid) - <small>READ ONLY</small>"
 	,"<i>true</i> if the file base has been opened successfully - <small>READ ONLY</small>"
 	,NULL
 };
@@ -1342,13 +1356,16 @@ static jsSyncMethodSpec js_filebase_functions[] = {
 		,31900
 	},
 	{"get_file_list",	js_get_file_list,	4, JSTYPE_ARRAY
-		,JSDOCSTR("[filespec] [,detail=FileBase.DETAIL.NORM] [,since_time=0] [,sort=true]")
-		,JSDOCSTR("get a list of file objects")
+		,JSDOCSTR("[filespec] [,detail=FileBase.DETAIL.NORM] [,since-time=0] [,sort=true [,order]]")
+		,JSDOCSTR("get a list of file objects"
+			", the default sort order is the sysop-configured order or <tt>FileBase.SORT.NAME_A</tt>"
+			)
 		,31900
 	},
 	{"get_file_names",	js_get_file_names,	3, JSTYPE_ARRAY
-		,JSDOCSTR("[filespec] [,since-time=0] [,sort=true]")
-		,JSDOCSTR("get a list of file names (strings)")
+		,JSDOCSTR("[filespec] [,since-time=0] [,sort=true [,order]]")
+		,JSDOCSTR("get a list of file names (strings)"
+			", the default sort order is the sysop-configured order or <tt>FileBase.SORT.NAME_A</tt>")
 		,31900
 	},
 	{"get_file_path",	js_get_file_path,	1, JSTYPE_STRING
@@ -1508,7 +1525,6 @@ JSObject* DLLCALL js_CreateFileBaseClass(JSContext* cx, JSObject* parent, scfg_t
 {
 	JSObject*	obj;
 	JSObject*	constructor;
-	JSObject*	detail;
 	jsval		val;
 
 	obj = JS_InitClass(cx, parent, NULL
@@ -1521,7 +1537,7 @@ JSObject* DLLCALL js_CreateFileBaseClass(JSContext* cx, JSObject* parent, scfg_t
 
 	if(JS_GetProperty(cx, parent, js_filebase_class.name, &val) && !JSVAL_NULL_OR_VOID(val)) {
 		JS_ValueToObject(cx, val, &constructor);
-		detail = JS_DefineObject(cx, constructor, "DETAIL", NULL, NULL, JSPROP_PERMANENT|JSPROP_ENUMERATE|JSPROP_READONLY);
+		JSObject* detail = JS_DefineObject(cx, constructor, "DETAIL", NULL, NULL, JSPROP_PERMANENT|JSPROP_ENUMERATE|JSPROP_READONLY);
 		if(detail != NULL) {
 			JS_DefineProperty(cx, detail, "MIN", INT_TO_JSVAL(file_detail_index), NULL, NULL
 				, JSPROP_PERMANENT|JSPROP_ENUMERATE|JSPROP_READONLY);
@@ -1532,6 +1548,23 @@ JSObject* DLLCALL js_CreateFileBaseClass(JSContext* cx, JSObject* parent, scfg_t
 			JS_DefineProperty(cx, detail, "MAX", INT_TO_JSVAL(file_detail_extdesc + 1), NULL, NULL
 				, JSPROP_PERMANENT|JSPROP_ENUMERATE|JSPROP_READONLY);
 		}
+		JSObject* sort = JS_DefineObject(cx, constructor, "SORT", NULL, NULL, JSPROP_PERMANENT|JSPROP_ENUMERATE|JSPROP_READONLY);
+		if(sort != NULL) {
+			JS_DefineProperty(cx, sort, "NATURAL", INT_TO_JSVAL(FILE_SORT_NATURAL), NULL, NULL
+				, JSPROP_PERMANENT|JSPROP_ENUMERATE|JSPROP_READONLY);
+			JS_DefineProperty(cx, sort, "NAME_A", INT_TO_JSVAL(FILE_SORT_NAME_A), NULL, NULL
+				, JSPROP_PERMANENT|JSPROP_ENUMERATE|JSPROP_READONLY);
+			JS_DefineProperty(cx, sort, "NAME_D", INT_TO_JSVAL(FILE_SORT_NAME_D), NULL, NULL
+				, JSPROP_PERMANENT|JSPROP_ENUMERATE|JSPROP_READONLY);
+			JS_DefineProperty(cx, sort, "NAME_AC", INT_TO_JSVAL(FILE_SORT_NAME_AC), NULL, NULL
+				, JSPROP_PERMANENT|JSPROP_ENUMERATE|JSPROP_READONLY);
+			JS_DefineProperty(cx, sort, "NAME_DC", INT_TO_JSVAL(FILE_SORT_NAME_DC), NULL, NULL
+				, JSPROP_PERMANENT|JSPROP_ENUMERATE|JSPROP_READONLY);
+			JS_DefineProperty(cx, sort, "DATE_A", INT_TO_JSVAL(FILE_SORT_DATE_A), NULL, NULL
+				, JSPROP_PERMANENT|JSPROP_ENUMERATE|JSPROP_READONLY);
+			JS_DefineProperty(cx, sort, "DATE_D", INT_TO_JSVAL(FILE_SORT_DATE_D), NULL, NULL
+				, JSPROP_PERMANENT|JSPROP_ENUMERATE|JSPROP_READONLY);
+		}
 	}
 	return obj;
 }
diff --git a/src/sbbs3/listfile.cpp b/src/sbbs3/listfile.cpp
index a6d1d45d29d6920d544503fa486cba46a2d1b601..09be3b75bbf863bc8cde2083e392c0812b5e374e 100644
--- a/src/sbbs3/listfile.cpp
+++ b/src/sbbs3/listfile.cpp
@@ -57,11 +57,11 @@ int sbbs_t::listfiles(uint dirnum, const char *filespec, FILE* tofile, long mode
 		return 0;
 
 	size_t file_count = 0;
-	smbfile_t* file_list = loadfiles(&cfg, &smb
+	smbfile_t* file_list = loadfiles(&smb
 		, (mode&(FL_FINDDESC|FL_EXFIND)) ? NULL : filespec
 		, (mode&FL_ULTIME) ? ns_time : 0
 		, file_detail_extdesc
-		, /* sort: */true
+		, (enum file_sort)cfg.dir[dirnum]->sort
 		, &file_count);
 	if(file_list == NULL || file_count < 1) {
 		smb_close(&smb);
@@ -750,11 +750,11 @@ int sbbs_t::listfileinfo(uint dirnum, const char *filespec, long mode)
 		return 0;
 
 	size_t file_count = 0;
-	smbfile_t* file_list = loadfiles(&cfg, &smb
+	smbfile_t* file_list = loadfiles(&smb
 		, filespec
 		, /* time_t */0
 		, file_detail_extdesc
-		, /* sort: */true
+		, (enum file_sort)cfg.dir[dirnum]->sort
 		, &file_count);
 	if(file_list == NULL || file_count < 1) {
 		smb_close(&smb);
diff --git a/src/sbbs3/main.cpp b/src/sbbs3/main.cpp
index e8b623993483b454e58555dac82f729d59811a8d..ff27a6aebaedf946510f5742939a3d619e24ab85 100644
--- a/src/sbbs3/main.cpp
+++ b/src/sbbs3/main.cpp
@@ -4886,14 +4886,6 @@ void DLLCALL bbs_thread(void* arg)
 
 	status("Initializing");
 
-	/* Defeat the lameo hex0rs - the name and copyright must remain intact */
-	if(crc32(COPYRIGHT_NOTICE,0)!=COPYRIGHT_CRC
-		|| crc32(VERSION_NOTICE,10)!=SYNCHRONET_CRC) {
-		lprintf(LOG_CRIT,"!CORRUPTED LIBRARY FILE");
-		cleanup(1);
-		return;
-	}
-
 	memset(text, 0, sizeof(text));
     memset(&scfg, 0, sizeof(scfg));
 
diff --git a/src/sbbs3/sbbsdefs.h b/src/sbbs3/sbbsdefs.h
index 25a6d01377277e35b8d9f258bd8aae94d8ac23cd..dfcc8a594e054e347c4d5c9f692036463f2e5299 100644
--- a/src/sbbs3/sbbsdefs.h
+++ b/src/sbbs3/sbbsdefs.h
@@ -41,9 +41,7 @@
 
 #define VERSION_NOTICE		"Synchronet BBS for " PLATFORM_DESC\
 								"  Version " VERSION
-#define SYNCHRONET_CRC		0x9BCDD162
-#define COPYRIGHT_NOTICE	"Copyright 2020 Rob Swindell"
-#define COPYRIGHT_CRC		0xB12E96E6
+#define COPYRIGHT_NOTICE	"Copyright 2021 Rob Swindell"
 
 #define SBBSCTRL_DEFAULT	"/sbbs/ctrl"
 
@@ -291,13 +289,14 @@
 #define ERR_SEEK	"seeking"		/* SEEKing error */
 
 enum file_sort {                    /* Values for dir[x].sort */
-     SORT_NAME_A	= 0	            /* Sort by filename, ascending (case-insensitive) */
-    ,SORT_NAME_D    = 1             /* Sort by filename, descending (case-insensitive) */
-	,SORT_NAME_AC	= 4				/* Sort by filename, ascending (case-sensitive) */
-	,SORT_NAME_DC   = 5             /* Sort by filename, descending (case-sensitive) */
-    ,SORT_DATE_A    = 2             /* Sort by upload date, ascending */
-    ,SORT_DATE_D    = 3             /* Sort by upload date, descending */
-    };
+     FILE_SORT_NAME_A   = 0	        /* Sort by filename, ascending (case-insensitive) */
+    ,FILE_SORT_NAME_D   = 1         /* Sort by filename, descending (case-insensitive) */
+	,FILE_SORT_NAME_AC  = 4			/* Sort by filename, ascending (case-sensitive) */
+	,FILE_SORT_NAME_DC  = 5         /* Sort by filename, descending (case-sensitive) */
+    ,FILE_SORT_DATE_A   = 2         /* Sort by upload date, ascending */
+    ,FILE_SORT_DATE_D   = 3         /* Sort by upload date, descending */
+	,FILE_SORT_NATURAL  = FILE_SORT_DATE_A
+};
 
 /* Values for grp[x].sort */
 enum area_sort {
diff --git a/src/sbbs3/scfg/scfgxfr2.c b/src/sbbs3/scfg/scfgxfr2.c
index 91139badbdfc4a9a05247adbb008147618b5c34a..40bb5d57145d15f76e67490f806ee16f95fd87a7 100644
--- a/src/sbbs3/scfg/scfgxfr2.c
+++ b/src/sbbs3/scfg/scfgxfr2.c
@@ -23,6 +23,16 @@
 #define DEFAULT_DIR_OPTIONS (DIR_FCHK|DIR_MULT|DIR_DUPES|DIR_CDTUL|DIR_CDTDL|DIR_DIZ)
 #define CUT_LIBNUM	USHRT_MAX
 
+char* file_sort_desc[] = {
+	"Name Ascending (case-insensitive)",
+	"Name Descending (case-insensitive)",
+	"Date Ascending",
+	"Date Descending",
+	"Name Ascending (case-sensitive)",
+	"Name Descending (case-sensitive)",
+	NULL
+};
+
 static bool new_dir(unsigned new_dirnum, unsigned libnum)
 {
 	dir_t* new_directory = malloc(sizeof(dir_t));
@@ -1891,10 +1901,7 @@ void dir_cfg(uint libnum)
 					sprintf(opt[n++],"%-27.27s%s","Upload Semaphore File"
 						,cfg.dir[i]->upload_sem);
 					sprintf(opt[n++],"%-27.27s%s","Sort Value and Direction"
-						, cfg.dir[i]->sort==SORT_NAME_A ? "Name Ascending"
-						: cfg.dir[i]->sort==SORT_NAME_D ? "Name Descending"
-						: cfg.dir[i]->sort==SORT_DATE_A ? "Date Ascending"
-						: "Date Descending");
+						,file_sort_desc[cfg.dir[i]->sort]);
 					sprintf(opt[n++],"%-27.27sNow %u / Was %u","Directory Index", i, cfg.dir[i]->dirnum);
 					opt[n][0]=0;
 					uifc.helpbuf=
@@ -1902,7 +1909,7 @@ void dir_cfg(uint libnum)
 						"\n"
 						"This is the advanced options menu for the selected file directory.\n"
 					;
-						n=uifc.list(WIN_ACT|WIN_SAV|WIN_RHT|WIN_BOT,3,4,60,&adv_dflt,0
+						n=uifc.list(WIN_ACT|WIN_SAV|WIN_RHT|WIN_BOT,3,4,65,&adv_dflt,0
 							,"Advanced Options",opt);
 						if(n==-1)
 							break;
@@ -1944,38 +1951,22 @@ void dir_cfg(uint libnum)
 									,cfg.dir[i]->upload_sem,sizeof(cfg.dir[i]->upload_sem)-1,K_EDIT);
 								break;
 							case 3:
-								n=0;
-								strcpy(opt[0],"Name Ascending");
-								strcpy(opt[1],"Name Descending");
-								strcpy(opt[2],"Date Ascending");
-								strcpy(opt[3],"Date Descending");
-								opt[4][0]=0;
+								n = cfg.dir[i]->sort;
 								uifc.helpbuf=
 									"`Sort Value and Direction:`\n"
 									"\n"
-									"This option allows you to determine the sort value and direction. Files\n"
-									"that are uploaded are automatically sorted by filename or upload date,\n"
-									"ascending or descending. If you change the sort value or direction after\n"
-									"a directory already has files in it, use the sysop transfer menu `;RESORT`\n"
-									"command to resort the directory with the new sort parameters.\n"
+									"This option allows you to determine the sort value and direction for\n"
+									"the display of file listings.\n"
+									"\n"
+									"The dates available for sorting are the file import/upload date/time.\n"
+									"\n"
+									"The natural (and thus fastest) sort order is `Date Ascending`."
 								;
 								n=uifc.list(WIN_MID|WIN_SAV,0,0,0,&n,0
-									,"Sort Value and Direction",opt);
-								if(n==0 && cfg.dir[i]->sort!=SORT_NAME_A) {
-									cfg.dir[i]->sort=SORT_NAME_A;
-									uifc.changes=1;
-								}
-								else if(n==1 && cfg.dir[i]->sort!=SORT_NAME_D) {
-									cfg.dir[i]->sort=SORT_NAME_D;
-									uifc.changes=1;
-								}
-								else if(n==2 && cfg.dir[i]->sort!=SORT_DATE_A) {
-									cfg.dir[i]->sort=SORT_DATE_A;
-									uifc.changes=1;
-								}
-								else if(n==3 && cfg.dir[i]->sort!=SORT_DATE_D) {
-									cfg.dir[i]->sort=SORT_DATE_D;
-									uifc.changes=1;
+									,"Sort Value and Direction", file_sort_desc);
+								if(n >= 0 && cfg.dir[i]->sort != n) {
+									cfg.dir[i]->sort = n;
+									uifc.changes = TRUE;
 								}
 								break; 
 							case 4:
diff --git a/src/sbbs3/upload.cpp b/src/sbbs3/upload.cpp
index 1f6301fbca0590bc7a7b349dbdf547b9755e2ebe..12d55616ab7403fd835e887edfee4030c9c79771 100644
--- a/src/sbbs3/upload.cpp
+++ b/src/sbbs3/upload.cpp
@@ -478,7 +478,7 @@ bool sbbs_t::bulkupload(uint dirnum)
 	}
 	action=NODE_ULNG;
 	SYNC;
-	str_list_t list = loadfilenames(&cfg, &smb, ALLFILES, /* time_t */0, /* sort */false, NULL);
+	str_list_t list = loadfilenames(&smb, ALLFILES, /* time_t */0, FILE_SORT_NATURAL, NULL);
 	smb_close(&smb);
 	dir=opendir(path);
 	while(dir!=NULL && (dirent=readdir(dir))!=NULL && !msgabort()) {