From e99f19ea829a6ef3c8a54448f5a88bc720dc8a18 Mon Sep 17 00:00:00 2001
From: deuce <>
Date: Thu, 14 Jan 2016 08:22:54 +0000
Subject: [PATCH] Add a new FIDO object that does generic FIDO stuff...
 currently just a strongly enforced address type.

---
 exec/load/binkp.js |  52 ++------------
 exec/load/fido.js  | 176 +++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 183 insertions(+), 45 deletions(-)
 create mode 100644 exec/load/fido.js

diff --git a/exec/load/binkp.js b/exec/load/binkp.js
index 9343dfe823..f1d265647f 100644
--- a/exec/load/binkp.js
+++ b/exec/load/binkp.js
@@ -1,4 +1,5 @@
 load("sockdefs.js");
+load("fido.js");
 
 /*
  * A binkp implementation...
@@ -8,6 +9,7 @@ load("sockdefs.js");
  * 
  * Next, adjust defaults as needed...
  * default_zone    - if no zone is specified, use this one for all addresses.
+ * default_domain  - if no domain is specified, use this one for all addresses.
  * debug		   - If set, logs all sent/received frames via log(LOG_DEBUG)
  * require_md5	   - Require that the remote support MD5
  * timeout		   - Max timeout
@@ -56,9 +58,8 @@ function BinkP(name_ver, inbound, rx_callback)
 	this.rx_callback = rx_callback;
 
 	this.default_zone = 1;
-	addr = this.parse_addr(system.fido_addr_list[0]);
-	if (addr.zone !== undefined)
-		this.default_zone = addr.zone;
+	addr = FIDO.parse_addr(system.fido_addr_list[0], this.default_zone);
+	this.default_zone = addr.zone;
 	this.senteob = false;
 	this.goteob = false;
 	this.pending_ack = [];
@@ -74,7 +75,7 @@ function BinkP(name_ver, inbound, rx_callback)
 	this.system_name = system.name;
 	this.system_operator = system.operator;
 	this.system_location = system.location;
-	system.fido_addr_list.forEach(function(addr){this.addr_list.push(addr);}, this);
+	system.fido_addr_list.forEach(function(faddr){this.addr_list.push(faddr);}, this);
 	this.want_callback = this.default_want;
 
 	this.sent_files = [];
@@ -130,43 +131,6 @@ BinkP.prototype.command_name = [
 	"M_GET",
 	"M_SKIP"
 ];
-BinkP.prototype.parse_addr = function(addr)
-{
-	var m;
-	var ret={};
-
-	m = addr.match(/^([0-9]+):/);
-	if (m !== null)
-		ret.zone = parseInt(m[1], 10);
-	else
-		ret.zone = this.default_zone;
-
-	m = addr.match(/([0-9]+)\//);
-	if (m !== null)
-		ret.net = parseInt(m[1], 10);
-
-	m = addr.match(/\/([0-9]+)/);
-	if (m !== null)
-		ret.node = parseInt(m[1], 10);
-
-	m = addr.match(/\.([0-9]+)/);
-	if (m !== null)
-		ret.point = parseInt(m[1], 10);
-
-	m = addr.match(/@.+$/);
-	if (m !== null)
-		ret.domain = m[1];
-
-	return ret;
-};
-BinkP.prototype.faddr_to_inetaddr = function(addr)
-{
-	var ret = '';
-	if (addr.point !== undefined && addr.point !== 0)
-		ret += format("p%d", addr.point);
-	ret += format("f%d.n%d.z%d.binkp.net", addr.node, addr.net, addr.zone);
-	return ret;
-};
 BinkP.prototype.ack_file = function()
 {
 	if (this.receiving !== undefined) {
@@ -235,9 +199,7 @@ BinkP.prototype.connect = function(addr, password, port)
 
 	if (addr === undefined)
 		throw("No address specified!");
-	addr = this.parse_addr(addr);
-	if (addr.net === undefined || addr.node == undefined)
-		return false;
+	addr = FIDO.parse_addr(addr, this.default_zone, this.default_domain);
 
 	if (password === undefined)
 		password = '-';
@@ -248,7 +210,7 @@ BinkP.prototype.connect = function(addr, password, port)
 	if (this.sock === undefined)
 		this.sock = new Socket(SOCK_STREAM, "binkp");
 
-	if(!this.sock.connect(this.faddr_to_inetaddr(addr), port)) {
+	if(!this.sock.connect(addr.inet_host, port)) {
 		this.sock = undefined;
 		return false;
 	}
diff --git a/exec/load/fido.js b/exec/load/fido.js
new file mode 100644
index 0000000000..75a2e19228
--- /dev/null
+++ b/exec/load/fido.js
@@ -0,0 +1,176 @@
+/*
+ * Public stuff:
+ * new FIDO.Addr(net, node, zone, point, domain)
+ * 		Returns a FIDO.Addr object with the following properties:
+ * 		net			- REQUIRED
+ * 		node		- REQUIRED
+ * 		zone
+ * 		point
+ * 		domain
+ * 
+ * 		These are type and value checked when assigned and throw an
+ * 		exception when illegal.
+ * 
+ * 		inet_host	- Internet hostname at the binkp.net domain
+ * 		str			- Address as a string in the most possible dimensions
+ * 		toString()	- Overrides the default... same as str
+ * 
+ * FIDO.parse_addr(string, default_zone, default_domain)
+ * 		Parses an address string filling in the default zone and domain
+ * 		if necessary and returns a FIDO.Addr object.
+ * 		I could have done a magic constructor that accepts this, but then
+ * 		Magic would be involved and I don't really like magic.
+ * 		
+ */
+
+var FIDO = {
+	Addr:function(orig_net, orig_node, orig_zone, orig_point, orig_domain)
+	{
+		var net = parseInt(orig_net, 10);
+		var node = parseInt(orig_node, 10);
+		var zone;
+		var point;
+		var domain;
+
+		if (orig_zone !== undefined)
+			zone = parseInt(orig_zone, 10);
+		else
+			zone = -1;
+		// TODO: Use the system default zone in system.fido_net_addrs[0]?
+		if (orig_point !== undefined)
+			point = parseInt(orig_point, 10);
+		else
+			point = 0;
+		if (orig_domain !== undefined)
+			domain = orig_domain.toString();
+		else
+			domain = '';
+
+		Object.defineProperties(this, {
+			"net": {
+				enumerable: true,
+				get: function() { return net; },
+				set: function(val) {
+					net = parseInt(val, 10);
+					if (typeof net !== 'number')
+						throw('net is not a number!');
+					if (net < 0 || net > 65535)
+						throw('net out of range');
+				}
+			},
+			"node": {
+				enumerable: true,
+				get: function() { return node; },
+				set: function(val) {
+					node = parseInt(val, 10);
+					if (typeof node !== 'number')
+						throw('node is not a number!');
+					if (node < 0 || node > 65535)
+						throw ('node out of range');
+				}
+			},
+			"zone": {
+				enumerable: true,
+				get: function() {
+					if (zone === -1)
+						return undefined;
+					return zone;
+				},
+				set: function(val) {
+					if (val == undefined)
+						zone = 0;
+					else
+						zone = parseInt(val, 10);
+					if (typeof zone !== 'number')
+						throw('zone is not a number!');
+					if (zone < -1 || zone > 65535)
+						throw('zone out of range');
+				}
+			},
+			"point": {
+				enumerable: true,
+				get: function() {
+					if (point === 0)
+						return undefined;
+					return point;
+				},
+				set: function(val) {
+					if (val == undefined)
+						point = 0;
+					else
+						point = parseInt(val, 10);
+					if (typeof point !== 'number')
+						throw('point is not a number!');
+					if (point < 0 || point > 65535)
+						throw ('point out of range');
+				}
+			},
+			"domain": {
+				enumerable: true,
+				get: function() {
+					if (domain === '')
+						return undefined;
+					return domain;
+				},
+				set: function(val) {
+					if (val == undefined)
+						domain = '';
+					else
+						domain = val.toString();
+					if (typeof domain !== 'string')
+						throw('domain is not a string');
+				}
+			}
+		});
+	},
+	parse_addr:function(addr, default_zone, default_domain)
+	{
+		var m;
+		var zone;
+		var domain;
+
+		m = addr.match(/^(?:([0-9]+):)?([0-9]+)\/([0-9]+)(?:\.([0-9]+))?(@.*)?$/);
+		if (m===null)
+			throw('invalid address '+addr);
+		zone = m[1];
+		domain = m[5];
+		if (zone == undefined)
+			zone = default_zone;
+		if (domain == undefined)
+			domain = default_domain;
+		return new FIDO.Addr(m[2], m[3], zone, m[4], domain);
+	},
+};
+Object.defineProperties(FIDO.Addr.prototype, {
+	'str': {
+		get: function() {
+			var ret = format("%d/%d", this.net, this.node);
+
+			if (this.zone !== undefined)
+				ret = format("%d:%s", this.zone, ret);
+			if (this.point !== undefined && this.point > 0)
+				ret = format("%s.%d", ret, this.point);
+			if (this.domain !== undefined)
+				ret = ret+'@'+this.domain;
+			return ret;
+		}
+	},
+	'inet_host': {
+		get: function() {
+			var ret = '';
+
+			// TODO: Use default zone from system.fido_net_addrs[0]?
+			if (this.zone === undefined)
+				throw('zone is undefined');
+
+			if (this.point !== undefined)
+				ret += format("p%d", this.point);
+			ret += format("f%d.n%d.z%d.binkp.net", this.node, this.net, this.zone);
+			return ret;
+		}
+	}
+});
+FIDO.Addr.prototype.toString = function()
+{
+	return this.str;
+};
-- 
GitLab