diff --git a/exec/sbbslist.js b/exec/sbbslist.js
index 6c9d72d323dc057534a819125fa3652df295ade9..542368d07c71ba277acba97773c86866f21b4430 100644
--- a/exec/sbbslist.js
+++ b/exec/sbbslist.js
@@ -9,8 +9,10 @@
 // sbbslist[.exe]   - Exports BBS entries to HTML and various plain-text formats (e.g. sbbs.lst, sbbsimsg.lst, syncterm.lst)
 
 var REVISION = "$Revision$".split(' ')[1];
+var version_notice = "Synchronet BBS List v4." + REVISION;
 var sbl_dir = "../xtrn/sbl/";
 
+load("sbbsdefs.js");
 load("sockdefs.js");
 load("portdefs.js");
 var options={sub:"syncdata"};
@@ -666,15 +668,240 @@ function verify_list(list)
         if(js.terminated)
             break;
     }
+
+	list.sort(verify_compare);
+}
+
+function verify_compare(a, b)
+{
+	var diff;
+	
+	if(a.entry.verified && b.entry.verified)
+		diff = new Date(b.entry.verified.on.substr(0,10)).getTime() - new Date(a.entry.verified.on.substr(0,10)).getTime();
+
+	if(diff) return diff;
+
+	if(a.entry.autoverify && b.entry.autoverify) {
+		diff = b.entry.autoverify.successes - a.entry.autoverify.successes;
+
+		if(diff) return diff;
+
+		diff = a.entry.autoverify.attempts - b.entry.autoverify.attempts;
+	}
+
+	return diff;
 }
 
-function unique_strings(a, offset) {
+function unique_strings(a, offset)
+{
     var seen = {};
     return a.filter(function(item) {
         return seen.hasOwnProperty(item.substring(offset)) ? false : (seen[item.substring(offset)] = true);
     });
 }
 
+function console_color(arg, selected)
+{
+	if(selected)
+		arg |= BG_BLUE;
+	if(js.global.console != undefined)
+		console.attributes = arg;
+}
+
+function list_bbs_entry(bbs, selected, prop1, prop2)
+{
+	var sysop="";
+	console_color(WHITE, selected);
+	printf("%-*s ", lib.max_len.name, bbs.name);
+	if(!js.global.console || console.screen_columns >= 80) {
+		if(prop1) {
+			var len = Math.max(prop1.length, lib.max_len[prop1]);
+			console_color(LIGHTMAGENTA, selected);
+			printf("%-*s", len, lib.property_value(bbs, prop1));
+		}
+		if(prop2 && lib.property_value(bbs, prop2)) {
+			console_color(YELLOW, selected);
+			printf("%*.*s"
+				,console.screen_columns - console.current_column -1
+				,console.screen_columns - console.current_column -1
+				,lib.property_value(bbs, prop2));
+		}
+	}
+}
+
+function browse(list)
+{
+	var top=0;
+	var current=0;
+	var pagesize=console.screen_rows-3;
+	var find;
+	var orglist=list.slice();
+	var prop1 = "sysop_name", prop2 = "service_address";
+
+	if(!js.global.console) {
+		alert("This feature requires the Synchronet terminal server (and console object)");
+		return false;
+	}
+	console.line_counter = 0;
+	console.clear(LIGHTGRAY);
+	while(!js.terminated) {
+		console.home();
+		console.attributes = BLACK | BG_LIGHTGRAY;
+		console.write(version_notice);
+		if(console.screen_columns >= 80)
+			console.write(format("%*s[%u BBS entries]", console.screen_columns-48, "", list.length));
+		console.cleartoeol();
+		console.crlf();
+		printf("%-*s ", lib.max_len.name, "name");
+		printf("%-*s", lib.max_len[prop1], prop1);
+		printf("%*s", console.screen_columns - console.current_column-1, prop2);
+		console.cleartoeol();
+		console.crlf();
+
+		log(LOG_DEBUG,"before current=" + current + " top=" + top + " pagesize=" + pagesize);
+		/* Bounds checking: */
+		if(current < 0) {
+			console.beep();
+			current = 0;
+		} else if(current >= list.length) {
+			console.beep();
+			current = list.length-1;
+		}
+		if(top > current)
+			top = current;
+		else if(top < 0)
+			top = 0;
+		if(top && top+pagesize > list.length)
+			top = list.length-pagesize;
+		if(top + pagesize  <= current)
+			top = (current+1) - pagesize;
+		log(LOG_DEBUG,"after current=" + current + " top=" + top + " pagesize=" + pagesize);
+		for(var i=top; i-top < pagesize; i++) {
+			console.line_counter = 0;
+			if(list[i]) {
+				list_bbs_entry(list[i], i==current, prop1, prop2);	
+				console.cleartoeol(i==current ? BG_BLUE : LIGHTGRAY);
+			} else
+				console.clearline(LIGHTGRAY);
+			console.crlf();
+		}
+
+		console.attributes=LIGHTGRAY;
+		console.mnemonics("~Up, ~Down, ~Next, ~Prev, ~Sort, ~Find, Format(~1-~9), ~Quit or [~View]: ");
+		var key = console.getkey(K_UPPER);
+		switch(key) {
+			case 'V':
+			case '\r':
+				view(list[current]);
+				continue;
+			case 'Q':
+				return;
+			case KEY_HOME:
+				current=top=0;
+				continue;
+			case KEY_END:
+				current=list.length-1;
+				continue;
+			case KEY_UP:
+			case 'U':
+				current--;
+				break;
+			case KEY_DOWN:
+			case 'D':
+				current++;
+				break;
+			case 'N':
+				current += pagesize;
+				top += pagesize;
+				break;
+			case 'P':
+				current -= pagesize;
+				top -= pagesize;
+				break;
+			case 'F':
+				list = orglist;
+				console.clearline();
+				console.print("\1n\1y\1hFind: ");
+				find=console.getstr(60,K_LINE|K_UPPER|K_NOCRLF);
+				console.clearline(LIGHTGRAY);
+				if(find && find.length) {
+					var new_list=[];
+					for(var i in list)
+						if(JSON.stringify(list[i]).toUpperCase().indexOf(find) >= 0)
+							new_list.push(list[i]);
+					list = new_list;
+				}
+				break;
+			case 'S':
+				console.clearline();
+				console.print("\1n\1y\1hSort: ");
+				console.mnemonics("~Name, ~Sysop, ~Address, ~Location, or [None]: ");
+				switch(console.getkey(K_UPPER)) {
+					case 'N':
+						lib.sort_property = "name";
+						list.sort(lib.compare);
+						break;
+					case 'S':
+						lib.sort_property = "sysop_name";
+						list.sort(lib.compare);
+						break;
+					case 'A':
+						lib.sort_property = "service_address";
+						list.sort(lib.compare);
+					default:
+						list = orglist;
+						break;
+				}
+				break;
+			case '1':
+				prop1="sysop_name";
+				prop2="service_address";
+				break;
+			case '2':
+				prop1="sysop_name";
+				prop2="location";
+				break;
+			case '3':
+				prop1="since";
+				prop2="description";
+				break;
+			case '4':
+				prop1="bbs_software";
+				prop2="web_site";
+				break;
+			case '5':
+				prop1=undefined;
+				prop2="networks";
+				break;
+		}
+	}
+}
+
+function view(bbs)
+{
+	console.line_counter = 0;
+	console.clear(LIGHTGRAY);
+	while(!js.terminated) {
+		console.home();
+		console.attributes = BLACK | BG_LIGHTGRAY;
+		console.write(version_notice);
+		console.cleartoeol();
+		console.crlf();
+
+		printf("\1n\1gBBS Name: \1h%s", bbs.name);
+		if(bbs.first_online)
+			printf("\1n\1g since \1h%s", bbs.first_online.substring(0,4));
+		console.crlf();
+
+		console.mnemonics("~Edit, ~Verify, ~Delete or ~Quit");
+		var key = console.getkey(K_UPPER);
+		switch(key) {
+			case 'Q':
+				return;
+		}
+	}
+}
+
 function main()
 {
     var i,j;
@@ -685,7 +912,7 @@ function main()
     var verbose = 0;
     var msgbase;
 
-    print("Synchronet BBS List v4 Rev " + REVISION);
+    print(version_notice);
 
     for(i in argv) {
         switch(argv[i]) {
@@ -843,12 +1070,23 @@ function main()
             }
             printf("%-25s %-25s %-25s", list[i].name, list[i].entry.created.by, list[i].sysop[0] ? list[i].sysop[0].name: '');
             if(list[i].entry.updated)
-                print(new Date(list[i].entry.updated.on).toISOString());
+                print(new Date(list[i].entry.updated.on.substr(0,10)).toISOString());
             else
                 print();
         }
         print(list.length + " BBS entries");
     }
+
+	if(argv.indexOf("list") >= 0) {
+		for(i in list) {
+			list_bbs_entry(list[i]);
+			writeln();
+		}
+	}
+
+	if(argv.indexOf("browse") >= 0) {
+		browse(list);
+	}
 }
 
 main();