diff --git a/exec/init-fidonet.js b/exec/init-fidonet.js
index 07d0115cdf05fbde7b59a60842e19c028ec060db..70f85ca62046f75dae74fdec1771871048a41f5e 100644
--- a/exec/init-fidonet.js
+++ b/exec/init-fidonet.js
@@ -55,6 +55,53 @@ function aborted()
 	return false;
 }
 
+function find_sys_addr(addr)
+{
+	for(var i = 0; i < system.fido_addr_list.length; i++) {
+		if(system.fido_addr_list[i] == addr)
+			return true;
+	}
+	return false;
+}
+
+function send_app_netmail(destaddr)
+{
+	var hdr = {
+		to: link.Name,
+		to_net_addr: destaddr,
+		from: sysop,
+		from_ext: 1,
+		subject: netname + " node number request"
+	}
+	print("Message text:");
+	var body_text = "Hello, this is " + sysop + " from " + system.location + "\r\n";
+	body_text += "and I am requesting a node number for zone " + netzone + " in " + netname + ".\r\n";
+	body_text += "\r\n";
+	body_text += "I am using Synchronet-" + system.platform + " v" + system.full_version 
+		+ " with SBBSecho and BinkIT.\r\n";
+	body_text += "\r\n";
+	body_text += "My requested AreaFix password is: '" + link.AreaFixPwd + "'\r\n";
+	body_text += "My requested BinkP Session password is: '" + link.SessionPwd + "'\r\n";
+	print(body_text);
+	while(confirm("Add more text") && !aborted()) {
+		body_text += "\r\n";
+		var str;
+		while((str=prompt("[done]")) && !aborted()) body_text += str + "\r\n";
+	}
+	if(aborted())
+		return false;
+	var msgbase = new MsgBase("mail");
+	if(msgbase.open() == false)
+		return "Error opening mail base: " + msgbase.last_error;
+	if(!msgbase.save_msg(hdr, body_text)) {
+		msgbase.close();
+		return "Error saving message: " + msgbase.last_error;
+	}
+	msgbase.close();
+	print("Application NetMail message created successfully for " + destaddr);
+	return true;
+}
+
 function lookup_network(info)
 {
 	print("Looking up network/zone: " + info);
@@ -65,7 +112,6 @@ function lookup_network(info)
 			return result;
 	}
 	
-	print("Reading FTN configuration file: sbbsecho.ini");
 	var file = new File("sbbsecho.ini");
 	if (!file.open("r")) {
 		alert("Error " + file.error + " opening " + file.name);
@@ -108,6 +154,111 @@ function lookup_network(info)
 	return result;
 }
 
+function get_linked_node(addr)
+{
+	var file = new File("sbbsecho.ini");
+	if (!file.open("r"))
+		return false;
+	var result = file.iniGetObject("node:" + addr);
+	file.close();
+	return result;
+}
+
+function get_binkp_sysop()
+{
+	var file = new File("sbbsecho.ini");
+	if (!file.open("r"))
+		return false;
+	var result = file.iniGetValue("Binkp", "Sysop");
+	file.close();
+	return result;
+}
+
+function update_sbbsecho_ini(hub, link, echolist_fname)
+{
+	function makepath(path)
+	{
+		if(mkpath(path))
+			return true;
+		alert("Error " + errno + " (" + errno_str + ") creating " + path);
+		return false;
+	}
+
+	var file = new File("sbbsecho.ini");
+	if(!file.open("r+")) {
+		return "Error " + file.error + " opening " + file.name;
+	}
+	var path = file.iniGetValue(null, "Inbound");
+	if(!path)
+		path = "../fido/nonsecure";
+	while((!path
+		|| !confirm("Non-secure inbound directory is '" + path + "'")
+		|| !makepath(path)) && !aborted())
+		path = prompt("Non-secure inbound directory");
+	file.iniSetValue(null, "Inbound", path);
+
+	path = file.iniGetValue(null, "SecureInbound");
+	if(!path)
+		path = "../fido/inbound";
+	while((!path
+		|| !confirm("Secure inbound directory is '" + path + "'")
+		|| !makepath(path)) && !aborted())
+		path = prompt("Secure inbound directory");
+	file.iniSetValue(null, "SecureInbound", path);
+
+	path = file.iniGetValue(null, "Outbound");
+	if(!path)
+		path = "../fido/outbound";
+	while((!path
+		|| !confirm("Outbound directory is '" + path + "'")
+		|| !makepath(path)) && !aborted())
+		path = prompt("Outbound directory");
+	file.iniSetValue(null, "Outbound", path);
+
+	var binkp = file.iniGetObject("BinkP");
+	if(!binkp) binkp = {};
+	binkp.sysop = sysop;
+	if(!file.iniSetObject("binkp", binkp)) {
+		return "Error" + file.error + " writign to " + file.name;
+	}
+	var section = "node:" + fidoaddr.to_str(hub);
+	if(!file.iniGetObject(section)
+		|| confirm("Overwrite hub [" + section + "] configuration in " + file.name)) {
+		if(!file.iniSetObject(section, link)) {
+			return "Error " + file.error + " writing to " + file.name;
+		}
+	}
+	var section = "node:" + hub.zone + ":ALL";
+	if(confirm("Route all zone " + hub.zone + " netmail through your hub")) {
+		if(!file.iniSetObject(section,
+			{
+				Comment: "Everyone in zone " + hub.zone,
+				Route: fidoaddr.to_str(hub)
+			})) {
+			return "Error " + file.error + " writing to " + file.name;
+		}
+	}
+	if(echolist_fname) {
+		var section = "echolist:" + echolist_fname;
+		if(!file.iniGetObject(section)
+			|| confirm("Overwrite [" + section + "] configuration in " + file.name)) {
+			if(!file.iniSetObject(section,
+				{
+					Hub: fidoaddr.to_str(hub),
+					Pwd: link.AreaFixPwd
+				})) {
+				return "Error " + file.error + " writing to " + file.name;
+			}
+		}
+	}
+	file.close();
+	print(file.name + " updated successfully.");
+	return true;
+}
+
+/****************************/
+/* DETERMINE NETWORK (ZONE) */
+/****************************/
 if(netzone)
 	network = lookup_network(netzone);
 else if(netname) {
@@ -146,7 +297,7 @@ if(netzone <= 6)
 	netname = "FidoNet";
 else {
 	while((!netname || netname.indexOf(' ') >= 0 || netname.length > 8 
-		|| !confirm("Network name is " + netname)) && !aborted()) {
+		|| !confirm("Network name is '" + netname + "'")) && !aborted()) {
 		var str = prompt("Network name (no spaces or illegal filename chars) [" + netname + "]");
 		if(str)
 			netname = str;
@@ -181,6 +332,9 @@ for(var i = 0; i < system.fido_addr_list.length; i++) {
 	break;
 }
 
+/*********************************/
+/* DETERMINE YOUR HUB'S ADDRESSS */
+/*********************************/
 var hub = {zone: netzone ? netzone : NaN, net: NaN, node: NaN};
 if(network.addr)
 	hub = fidoaddr.parse(network.addr);
@@ -193,25 +347,42 @@ do {
 		hub.node = parseInt(prompt("Your hub's node number"));
 } while(!confirm("Your hub's address is " + fidoaddr.to_str(hub)) && !aborted());
 
-if(fidoaddr.to_str(hub) == network.addr)
-	hub_name = network.coord;
+var link = get_linked_node(fidoaddr.to_str(hub));
+if(!link)
+	link = {};
 
-var hub_name;
-while((!hub_name || !confirm("Your hub's sysop's name is " + hub_name)) && !aborted()) {
-	hub_name = prompt("Your hub's sysop's name");
+if(!link.Name && fidoaddr.to_str(hub) == network.addr)
+	link.Name = network.coord;
+
+while((!link.Name || !confirm("Your hub's sysop's name is '" + link.Name + "'")) && !aborted()) {
+	link.Name = prompt("Your hub's sysop's name");
 }
 
-var hub_host = network.host;
-while(!network.dns && (!hub_host
-	|| !confirm("Your hub's hostname or IP address is " + hub_host)) && !aborted()) {
-	hub_host = prompt("Your hub's hostname or IP address");
+if(!link.BinkpHost)
+	link.BinkpHost = network.host;
+while(!network.dns && (!link.BinkpHost
+	|| !confirm("Your hub's hostname or IP address is " + link.BinkpHost)) && !aborted()) {
+	link.BinkpHost = prompt("Your hub's hostname or IP address");
 }
 
-var hub_port = network.port || 24554;
-while(!hub_port || !confirm("Your hub's BinkP/TCP port number is " + hub_port) && !aborted()) {
-	hub_port = paseInt(prompt("Your hub's BinkP/TCP port number"));
+if(!link.BinkpPort)
+	link.BinkpPort = network.port || 24554;
+while(!link.BinkpPort || !confirm("Your hub's BinkP/TCP port number is " + link.BinkpPort) && !aborted()) {
+	link.BinkpPort = paseInt(prompt("Your hub's BinkP/TCP port number"));
 }
 
+if(!link.Comment)
+	link.Comment = network.email;
+
+if(!link.GroupHub)
+	link.GroupHub = netname;
+
+if(link.BinkpPoll === undefined)
+	link.BinkpPoll = true;
+
+/***************************/
+/* DETERMINE YOUR ADDRESSS */
+/***************************/
 if(!your.zone)
 	your.zone = hub.zone;
 if(!your.net)
@@ -229,30 +400,54 @@ while(!confirm("Your node address is " + fidoaddr.to_str(your)) && !aborted()) {
 	while((isNaN(your.point)) && !aborted())
 		your.point = parseInt(prompt("Your point number (i.e. 0 for a normal node)"));
 }
-msgs_cnf.fido_addr_list.push(your);
 
-if(!msgs_cnf.fido_default_origin)
-	msgs_cnf.fido_default_origin = system.name + " - " + system.inet_addr;
-while(!msgs_cnf.fido_default_origin
-	|| !confirm("Your origin line is (" +	msgs_cnf.fido_default_origin + ")")) {
-	msgs_cnf.fido_default_origin = prompt("Your origin line");
-}
-
-var areafixpwd;
-while(!areafixpwd && !aborted())
-	areafixpwd = prompt("Your AreaFix (a.k.a. Area Manager) Password (case in-sensitive)");
-var sessionpwd;
-while(!sessionpwd && !aborted())
-	sessionpwd = prompt("Your BinkP Session Password (case sensitive)");
+while((!link.AreaFixPwd || !confirm("Your AreaFix Password is '" + link.AreaFixPwd + "'")) && !aborted())
+	link.AreaFixPwd = prompt("Your AreaFix (a.k.a. Area Manager) Password (case in-sensitive)");
+while((!link.SessionPwd || !confirm("Your BinkP Session Passowrd is '" + link.SessionPwd + "'")) && !aborted())
+	link.SessionPwd = prompt("Your BinkP Session Password (case sensitive)");
 var sysop = system.operator;
 if(system.stats.total_users) {
 	var u = new User(1);
 	if(u && u.name)
 		sysop = u.name;
 }
-while((!sysop || !confirm("Your name is " + sysop)) && !aborted())
+sysop = get_binkp_sysop() || sysop;
+while((!sysop || !confirm("Your name is '" + sysop + "'")) && !aborted())
 	sysop = prompt("Your name");
 
+/***********************************************/
+/* SEND NODE NUMBER REQUEST NETMAIL (Internet) */
+/***********************************************/
+if(your.node === 9999 && network.email 
+	&& confirm("Send a node number application to " + network.email)) {
+	var result = send_app_netmail(network.email);
+	if(result !== true) {
+		alert(result);
+		exit(1);
+	}
+	if(confirm("Come back when you have your permanently-assigned node address")) {
+		if(confirm("Save changes to FidoNet configuration file: sbbsecho.ini")) {
+			var result = update_sbbsecho_ini(hub, link);
+			if (result != true) {
+				alert(result);
+				exit(1);
+			}
+		}
+		exit(0);
+	}
+}
+
+if(!find_sys_addr(fidoaddr.to_str(your))
+	&& confirm("Add node address " + fidoaddr.to_str(your) + " to your configuration"))
+	msgs_cnf.fido_addr_list.push(your);
+
+if(!msgs_cnf.fido_default_origin)
+	msgs_cnf.fido_default_origin = system.name + " - " + system.inet_addr;
+while((!msgs_cnf.fido_default_origin
+	|| !confirm("Your origin line is '" +	msgs_cnf.fido_default_origin + "'")) && !aborted()) {
+	msgs_cnf.fido_default_origin = prompt("Your origin line");
+}
+
 /*******************/
 /* UPDATE MSGS.CNF */
 /*******************/
@@ -266,7 +461,7 @@ if(!msg_area.grp[netname]
 			"code_prefix": netname.toUpperCase() + "_"
 			});
 }
-if(confirm("Update Message Area configuration file: msgs.cnf")) {
+if(confirm("Save Changes to Message Area configuration file: msgs.cnf")) {
 	if(!cnflib.write("msgs.cnf", undefined, msgs_cnf)) {
 		alert("Failed to write msgs.cnf");
 		exit(1);
@@ -280,11 +475,11 @@ if(confirm("Update Message Area configuration file: msgs.cnf")) {
 var echolist_fname = file_getname(network.echolist);
 if(network.echolist 
 	&& (network.echolist.indexOf("http://") == 0 || network.echolist.indexOf("https://") == 0)
-	&& confirm("Download " + netname + " EchoList: " + network.echolist)) {
+	&& confirm("Download " + netname + " EchoList")) {
 	var echolist_url = network.echolist;
 	load("http.js");
 	while(!aborted()) {
-		while((!echolist_url || !confirm("Download EchoList from: " + echolist_url)) && !aborted()) {
+		while((!echolist_url || !confirm("Download from: " + echolist_url)) && !aborted()) {
 			echolist_url = prompt("Echolist URL");
 		}
 		var file = new File(echolist_fname);
@@ -303,11 +498,11 @@ if(network.echolist
 		alert("Error " + http_request.respons_code + " downloading " + echolist_url);
 	}
 }
-while(!file_getcase(echolist_fname)) {
+while(!file_getcase(echolist_fname) && !aborted()) {
 	alert(system.ctrl_dir + echolist_fname + " does not exist");
 	if(!confirm("Install " + netname + " EchoList: " + echolist_fname))
 		break;
-	prompt("Download and extract " + echolist_fname + " now. Enter to continue");
+	prompt("Download and extract " + echolist_fname + " now... Press enter to continue");
 }
 echolist_fname = file_getcase(echolist_fname)	
 if(echolist_fname && confirm("Import " + netname + " EchoList: " + echolist_fname)) {
@@ -318,103 +513,15 @@ if(echolist_fname && confirm("Import " + netname + " EchoList: " + echolist_fnam
 		+ " -faddr=" + fidoaddr.to_str(your));
 }
 
-
-function makepath(path)
-{
-	if(mkpath(path))
-		return true;
-	alert("Error " + errno + " (" + errno_str + ") creating " + path);
-	return false;
-}
-
 /***********************/
 /* UPDATE SBBSECHO.INI */
 /***********************/
-if(confirm("Update FidoNet configuration file: sbbsecho.ini")) {
-	var file = new File("sbbsecho.ini");
-	if(!file.open("r+")) {
-		alert("Error " + file.error + " opening " + file.name);
-		exit(1);
-	}
-	var path = file.iniGetValue(null, "Inbound");
-	if(!path)
-		path = "../fido/nonsecure";
-	while((!path
-		|| !confirm("Non-secure inbound directory is " + path)
-		|| !makepath(path)) && !aborted())
-		path = prompt("Non-secure inbound directory");
-	file.iniSetValue(null, "Inbound", path);
-
-	path = file.iniGetValue(null, "SecureInbound");
-	if(!path)
-		path = "../fido/inbound";
-	while((!path
-		|| !confirm("Secure inbound directory is " + path)
-		|| !makepath(path)) && !aborted())
-		path = prompt("Secure inbound directory");
-	file.iniSetValue(null, "SecureInbound", path);
-
-	path = file.iniGetValue(null, "Outbound");
-	if(!path)
-		path = "../fido/outbound";
-	while((!path
-		|| !confirm("Outbound directory is " + path)
-		|| !makepath(path)) && !aborted())
-		path = prompt("Outbound directory");
-	file.iniSetValue(null, "Outbound", path);
-
-	var binkp = file.iniGetObject("BinkP");
-	if(!binkp) binkp = {};
-	binkp.sysop = sysop;
-	if(!file.iniSetObject("binkp", binkp)) {
-		alert("Error" + file.error + " writign to " + file.name);
+if(confirm("Save changes to FidoNet configuration file: sbbsecho.ini")) {
+	var result = update_sbbsecho_ini(hub, link, echolist_fname);
+	if (result != true) {
+		alert(result);
 		exit(1);
 	}
-	var section = "node:" + fidoaddr.to_str(hub);
-	if(!file.iniGetObject(section)
-		|| confirm("Overwrite hub [" + section + "] configuration in " + file.name)) {
-		if(!file.iniSetObject(section,
-			{
-				Name: hub_name,
-				Comment: network.email,
-				AreaFixPwd: areafixpwd,
-				SessionPwd: sessionpwd,
-				GroupHub: netname,
-				BinkpPoll: true,
-				BinkpHost: hub_host,
-				BinkpPort: hub_port
-			})) {
-			alert("Error " + file.error + " writing to " + file.name);
-			exit(1);
-		}
-	}
-	var section = "node:" + hub.zone + ":ALL";
-	if(confirm("Route all zone " + hub.zone + " netmail through your hub")) {
-		if(!file.iniSetObject(section,
-			{
-				Comment: "Everyone in zone " + hub.zone,
-				Route: fidoaddr.to_str(hub)
-			})) {
-			alert("Error " + file.error + " writing to " + file.name);
-			exit(1);
-		}
-	}
-	if(echolist_fname) {
-		var section = "echolist:" + echolist_fname;
-		if(!file.iniGetObject(section)
-			|| confirm("Overwrite [" + section + "] configuration in " + file.name)) {
-			if(!file.iniSetObject(section,
-				{
-					Hub: fidoaddr.to_str(hub),
-					Pwd: areafixpwd
-				})) {
-				alert("Error " + file.error + " writing to " + file.name);
-				exit(1);
-			}
-		}
-	}
-	file.close();
-	print(file.name + " updated successfully.");
 }
 
 /******************/
@@ -432,11 +539,27 @@ print("Requesting Synchronet recycle (configuration-reload)");
 if(!file_touch(system.ctrl_dir + "recycle"))
 	alert("Recycle semaphore file update failure");
 
+/******************************************/
+/* SEND NODE NUMBER REQUEST NETMAIL (FTN) */
+/******************************************/
+if(your.node === 9999
+	&& confirm("Send a node number application to "
+		+ fidoaddr.to_str(hub))) {
+	var result = send_app_netmail(fidoaddr.to_str(hub));
+	if(result !== true) {
+		alert(result);
+		exit(1);
+	}
+	if(confirm("Come back when you have a permanently-assigned node address"))
+		exit(0);
+}
+
 /************************/
 /* SEND AREAFIX NETMAIL */
 /************************/
-if(confirm("Create an AreaFix request to link ALL EchoMail areas with "
-	+ fidoaddr.to_str(hub))) {
+if(your.node !== 9999
+	&& confirm("Create an AreaFix request to link ALL EchoMail areas with "
+		+ fidoaddr.to_str(hub))) {
 	var msgbase = new MsgBase("mail");
 	if(msgbase.open() == false) {
 		alert("Error opening mail base: " + msgbase.last_error);
@@ -447,7 +570,7 @@ if(confirm("Create an AreaFix request to link ALL EchoMail areas with "
 			to_net_addr: fidoaddr.to_str(hub),
 			from: sysop,
 			from_ext: 1,
-			subject: areafixpwd
+			subject: link.AreaFixPwd
 		}, /* body text: */ "%+ALL")) {
 		alert("Error saving message: " + msgbase.last_error);
 		exit(1);