diff --git a/exec/load/fido.js b/exec/load/fido.js index 30a2113621db47995c4aa207c3d7215626a05fa7..d1e449668087ed99731b0c71e1bfa57931218e86 100644 --- a/exec/load/fido.js +++ b/exec/load/fido.js @@ -27,6 +27,11 @@ * * FIDO.parse_flo_file_path(path, default_zone, domain) * Parses a flo filename and path into the returned FIDO.Addr object. + * + * FIDO.parse_nodelist(path, warn) + * Parses a nodelist and returns an object with an entries array in + * it containing all the nodelist entries. If warn is true, will + * warn on "illegal" values. */ var FIDO = { @@ -236,6 +241,152 @@ var FIDO = { }, this); f.close(); } + }, + Node:function(addr, hub) { + this.addr = addr.str; + this.hub = hub.str; + this.private = this.hold = this.down = false; + }, + parse_nodelist:function(filename, warn) + { + var f = new File(filename); + var ret = {}; + + if (warn === undefined) + warn = false; + + if (!f.open("r")) + throw("Unable to open '"+f.name+"'."); + + // Validate first line... + var line = f.readln(2048); + if (line == undefined) + throw("Unable to read first line in '"+f.name+"'"); + var m; + if ((m=line.match(/^;A (.*) Nodelist for (.*) -- Day number ([0-9]+) : ([0-9]{5})$/)) !== null) { + ret.domain = m[1]; + ret.date = m[2]; // TODO: Parse date into a Date() + ret.daynum = parseInt(m[3], 10); + ret.crc = parseInt(m[4], 10); + f.rewind(); + // TODO: Must exclude the EOF character... + /* if (ret.crc !== f.crc16) + log(LOG_WARNING, "CRC mismatch on '"+f.name+"'. Got "+f.crc16+" expected "+ret.crc); + */ + f.rewind(); + } + else + f.rewind(); + + var hub = new FIDO.Addr('0:0/0'); + var node = new FIDO.Addr('0:0/0'); + var fields; + var lineno = 0; + var entry; + var flags; + var flag; + var value; + ret.entries = []; + + while ((line = f.readln(2048))) { + lineno++; + if (line[0] === ';') + continue; + fields = line.split(/,/); + switch(fields[0]) { + case 'Zone': + node.zone = parseInt(fields[1], 10); + node.net = 0; + node.node = 0; + hub.zone = node.zone; + hub.net = 0; + hub.node = 0; + break; + case 'Region': + node.net = parseInt(fields[1], 10); + node.node = 0; + hub.net = node.net; + hub.node = 0; + break; + case 'Host': + node.net = parseInt(fields[1], 10); + node.node = 0; + hub.net = node.net; + hub.node = 0; + break; + case 'Hub': + hub.node = parseInt(fields[1], 10); + node.node = parseInt(fields[1], 10); + break; + case 'Pvt': + node.node = parseInt(fields[1], 10); + break; + case 'Hold': + node.node = parseInt(fields[1], 10); + break; + case 'Down': + node.node = parseInt(fields[1], 10); + break; + case '': + node.node = parseInt(fields[1], 10); + break; + case '\x1a': // EOF + continue; + default: + if (warn) + log(LOG_WARNING, "Unhandled nodelist Keyword line "+lineno+" of '"+f.name+"'"); + continue; + } + entry = new Node(node, hub); + switch(fields[0]) { + case 'Pvt': + entry.private = true; + break; + case 'Hold': + entry.hold = true; + break; + case 'Down': + entry.down = true; + break; + } + entry.name = fields[2].replace(/_/g, ' '); + entry.location = fields[3].replace(/_/g, ' '); + entry.sysop = fields[4].replace(/_/g, ' '); + entry.phone = fields[5]; + entry.baud = parseInt(fields[6]); + if (warn) { + switch(fields[6]) { + case '300': + case '1200': + case '2400': + case '9600': + case '19200': + case '38400': + break; + default: + log(LOG_WARNING, "Illegal nodelist baud rate '"+fields[6]+"' line "+lineno+" of '"+f.name+"'"); + } + } + flags = fields.slice(7); + entry.flags = {}; + while(flags.length > 0) { + flag = flags.shift(); + if (warn) { + if (flag.length > 32) + log(LOG_WARNING, "Illegal nodelist flag '"+flag+"' longer than 32 characters"); + } + if ((m = flag.match(/^(.*?):(.*)$/))) { + flag = m[1]; + value = m[2]; + entry.flags[flag] = value; + } + else + value = true; + entry.flags[flag] = value; + } + ret.entries.push(entry); + } + return ret; } }; Object.defineProperties(FIDO.Addr.prototype, { @@ -297,5 +448,53 @@ FIDO.Addr.prototype.flo_outbound = function(default_zone, default_domain) ret += format("%04x%04x.", this.net, this.node); return ret.substr(1); }; -FIDO.ReadDomainMap(); +Object.defineProperties(FIDO.Node.prototype, { + 'binkp_host': { + get: function() { + var iflags = ['INA', 'IFC', 'ITN', 'IVM', 'IFT', 'IP']; + var i; + if (this.flags.IBN === undefined) + return undefined; + if (this.flags.IBN !== true) { + // Address or port number included here... + if (this.flags.IBN.search(/^[0-9]+$/) == -1) { + if (this.flags.IBN.indexOf(':' !== -1)) + return this.flags.IBN.replace(/:.*$/,''); + return this.flags.IBN; + } + } + for (i in iflags) { + if (this.flags[iflags[i]] === undefined) + continue; + if (this.flags[iflags[i]] === true) + continue; + if (this.flags[iflags[i]].search(/^[0-9]+$/) == 0) + continue; + if (this.flags[iflags[i]].indexOf(':') !== -1) + return this.flags[iflags[i]].replace(/:.*$/,''); + return this.flags[iflags[i]]; + } + if (this.name.indexOf('.') !== -1) + return this.name.replace(/ /, '_'); + } + }, + 'binkp_port': { + get: function() { + if (this.flags.IBN === undefined) + return undefined; + if (this.flags.IBN !== true) { + // Address or port number included here... + if (this.flags.IBN.search(/^[0-9]+$/) == -1) { + if (this.flags.IBN.indexOf(':') === -1) + return 24554; + return parseInt(this.flags.IBN.replace(/^.*:([0-9]+)$/, '$1')); + } + return parseInt(this.flags.IBN, 10); + } + return 24554; + } + } +}); + +FIDO.ReadDomainMap();