From 66c623a39053545c2c6e175a1c513b666cbeee82 Mon Sep 17 00:00:00 2001
From: deuce <>
Date: Sun, 10 Jan 2016 07:18:32 +0000
Subject: [PATCH] Split out the config parsing stuff into a separate load()
 file and generally clean up the code.

Add a new (and non-functional) tickitcfg jsexec script for setting up the
configuration.
---
 exec/load/fidocfg.js | 168 ++++++++++++++++++++++++++++++
 exec/tickit.js       | 237 +++++-------------------------------------
 exec/tickitcfg.js    | 242 +++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 437 insertions(+), 210 deletions(-)
 create mode 100644 exec/load/fidocfg.js
 create mode 100644 exec/tickitcfg.js

diff --git a/exec/load/fidocfg.js b/exec/load/fidocfg.js
new file mode 100644
index 0000000000..72aa6e7e7f
--- /dev/null
+++ b/exec/load/fidocfg.js
@@ -0,0 +1,168 @@
+function SBBSEchoCfg ()
+{
+	var ecfg = new File(system.ctrl_dir+'sbbsecho.cfg');
+	var line;
+	var m;
+
+	this.inb = [];
+	this.pktpass = {};
+	this.is_flo = false;
+	this.outboud = undefined;
+
+	if (!ecfg.open("r"))
+		throw("Unable to open '"+ecfg.name+"'");
+
+	while ((line=ecfg.readln(65535)) != undefined) {
+		m = line.match(/^\s*(?:secure_)?inbound\s+(.*)$/i);
+		if (m !== null)
+			this.inb.push(backslash(m[1]));
+
+		m = line.match(/^\s*pktpwd\s+(.*?)\s+(.*)\s*$/i);
+		if (m !== null)
+			this.pktpass[m[1].toUpperCase()] = m[2].toUpperCase();
+
+		m = line.match(/^\s*outbound\s+(.*?)\s*$/i);
+		if (m !== null)
+			this.outbound = m[1];
+
+		m = line.match(/^\s*flo_mailer\s*$/i);
+		if (m !== null)
+			this.is_flo = true;
+	}
+	ecfg.close();
+}
+SBBSEchoCfg.prototype.get_pw = function(node)
+{
+	var n = node;
+
+	while(n) {
+		if (this.pktpass[n] !== undefined)
+			return this.pktpass[n];
+		if (n === 'ALL')
+			break;
+		if (n.indexOf('ALL') !== -1)
+			n = n.replace(/[0-9]+[^0-9]ALL$/, 'ALL');
+		else
+			n = n.replace(/[0-9]+$/, 'ALL');
+	}
+	return undefined;
+};
+SBBSEchoCfg.prototype.match_pw = function(node, pw)
+{
+	var pktpw = this.get_pw(node);
+
+	if (pktpw === undefined || pktpw == '') {
+		if (pw === '' || pw === undefined)
+			return true;
+	}
+	if (pw.toUpperCase() === pktpw.toUpperCase())
+		return true;
+
+	log(LOG_WARNING, "Incorrect password "+pw+" (expected "+pktpw+")");
+	return false;
+};
+
+function TickITCfg() {
+	this.gcfg = undefined;
+	this.acfg = {};
+	var tcfg = new File(system.ctrl_dir+'tickit.ini');
+	var sects;
+	var i;
+
+	function lcprops(obj)
+	{
+		var i;
+
+		for (i in obj) {
+			if (i.toLowerCase() !== i) {
+				if (obj[i.toLowerCase()] === undefined)
+					obj[i.toLowerCase()] = obj[i];
+				if (typeof(obj[i]) == 'Object')
+					lcprops(obj[i]);
+			}
+		}
+	}
+
+	if (!tcfg.open("r")) {
+		tcfg.close();
+		throw("Unable to open '"+tcfg.name+"'");
+	}
+	this.gcfg = tcfg.iniGetObject();
+	lcprops(this.gcfg);
+	sects = tcfg.iniGetSections();
+	for (i=0; i<sects.length; i++) {
+		this.acfg[sects[i].toLowerCase()] = tcfg.iniGetObject(sects[i]);
+		lcprops(this.acfg[sects[i].toLowerCase()]);
+	}
+	tcfg.close();
+}
+TickITCfg.prototype.cset = '0123456789abcdefghijklmnopqrstuvwxyz0123456789-_';
+TickITCfg.prototype.basefn_to_num = function(num)
+{
+	var base = this.cset.length;
+	var part;
+	var ret=0;
+	var i;
+
+	for (i=0; i<num.length; i++) {
+		ret *= base;
+		ret += this.cset.indexOf(num[i]);
+	}
+	return ret;
+};
+TickITCfg.prototype.num_to_basefn = function(num)
+{
+	var base = this.cset.length;
+	var part;
+	var ret='';
+
+	while(num) {
+		part = num % base;
+		ret = this.cset.charAt(part) + ret;
+		num = parseInt((num/base), 10);
+	}
+	return ret;
+};
+/*
+ * Returns a filename in the format "ti_XXXXX.tic" where
+ * XXXXX is replaced by an incrementing base-48 number.
+ * This provides 254,803,967 unique filenames.
+ */
+TickITCfg.prototype.get_next_tic_filename = function()
+{
+	var f;
+	var val;
+	var ret;
+
+	// Get previous value or -1 if there is no previous value.
+	f = new File(system.data_dir+'tickit.seq');
+
+	if (f.open("r+b")) {
+		val = f.readBin();
+	}
+	else {
+		if (!f.open("web+")) {
+			log(LOG_ERROR, "Unable to open file "+f.name+"!");
+			return undefined;
+		}
+		val = -1;
+	}
+
+	// Increment by 1...
+	val++;
+
+	// Check for wrap...
+	if (val > this.basefn_to_num('_____'))
+		val = 0;
+
+	// Write back new value.
+	f.truncate();
+	f.writeBin(val);
+	f.close();
+
+	// Left-pad to five digits.
+	ret = ('00000'+this.num_to_basefn(val)).substr(-5);
+
+	// Add pre/suf-fix
+	return 'ti_'+ret+'.tic';
+};
diff --git a/exec/tickit.js b/exec/tickit.js
index f3b98cf4a8..6239a04eeb 100644
--- a/exec/tickit.js
+++ b/exec/tickit.js
@@ -1,118 +1,9 @@
 load("sbbsdefs.js");
+load("tickit_objs.js");
 
-var inb=[];
-var pktpass = {};
+var sbbsecho = new SBBSEchoCfg();
+var tickit = new TickITCfg();
 var files_bbs={};
-var outbound;
-var gcfg;
-var acfg={};
-var is_flo=false;
-const cset='0123456789abcdefghijklmnopqrstuvwxyz0123456789-_';
-
-function basefn_to_num(num)
-{
-	var base = cset.length;
-	var part;
-	var ret=0;
-	var i;
-
-	for (i=0; i<num.length; i++) {
-		ret *= base;
-		ret += cset.indexOf(num[i]);
-	}
-	return ret;
-	
-}
-
-function num_to_basefn(num)
-{
-	var base = cset.length;
-	var part;
-	var ret='';
-
-	while(num) {
-		part = num % base;
-		ret = cset.charAt(part) + ret;
-		num = parseInt((num/base), 10);
-	}
-	return ret;
-}
-
-/*
- * Returns a filename in the format "ti_XXXXX.tic" where
- * XXXXX is replaced by an incrementing base-48 number.
- * This provides 254,803,967 unique filenames.
- */
-function get_next_tic_filename()
-{
-	var f;
-	var val;
-	var ret;
-
-	// Get previous value or -1 if there is no previous value.
-	f = new File(system.data_dir+'tickit.seq');
-
-	if (f.open("r+b")) {
-		val = f.readBin();
-	}
-	else {
-		if (!f.open("web+")) {
-			log(LOG_ERROR, "Unable to open file "+f.name+"!");
-			return undefined;
-		}
-		val = -1;
-	}
-
-	// Increment by 1...
-	val++;
-
-	// Check for wrap...
-	if (val > basefn_to_num('_____'))
-		val = 0;
-
-	// Write back new value.
-	f.truncate();
-	f.writeBin(val);
-	f.close();
-
-	// Left-pad to five digits.
-	ret = ('00000'+num_to_basefn(val)).substr(-5);
-
-	// Add pre/suf-fix
-	return 'ti_'+ret+'.tic';
-}
-
-function get_pw(node)
-{
-	var n = node;
-
-	while(n) {
-		if (pktpass[n] !== undefined)
-			return pktpass[n];
-		if (n === 'ALL')
-			break;
-		if (n.indexOf('ALL') !== -1)
-			n = n.replace(/[0-9]+[^0-9]ALL$/, 'ALL');
-		else
-			n = n.replace(/[0-9]+$/, 'ALL');
-	}
-	return undefined;
-}
-
-function match_pw(node, pw)
-{
-	var pktpw = get_pw(node);
-
-	if (pktpw === undefined || pktpw == '') {
-		if (pw === '' || pw === undefined)
-			return true;
-	}
-	if (pw.toUpperCase() === pktpw.toUpperCase())
-		return true;
-
-	log(LOG_WARNING, "Incorrect password "+pw+" (expected "+pktpw+")");
-	return false;
-}
 
 function process_tic(tic)
 {
@@ -122,12 +13,12 @@ function process_tic(tic)
 	var i;
 	var cfg;
 
-	if (gcfg.path !== undefined)
-		path = backslash(gcfg.path);
-	if (gcfg.dir !== undefined)
-		dir = gcfg.dir.toLowerCase();
+	if (tickit.gcfg.path !== undefined)
+		path = backslash(tickit.gcfg.path);
+	if (tickit.gcfg.dir !== undefined)
+		dir = tickit.gcfg.dir.toLowerCase();
 
-	cfg = acfg[tic.area.toLowerCase()];
+	cfg = tickit.acfg[tic.area.toLowerCase()];
 	if (cfg !== undefined) {
 		if (cfg.path !== undefined) {
 			path = backslash(cfg.path);
@@ -193,7 +84,7 @@ function process_tic(tic)
 	return true;
 }
 
-function add_links(seenbys, list)
+function add_links(seenbys, links, list)
 {
 	var l;
 	var i;
@@ -276,11 +167,11 @@ function forward_tic(tic)
 		seenbys[tic.seenby[i]]='';
 
 	// Calculate links
-	if (gcfg.links !== undefined)
-		add_links(seenbys, gcfg.links);
-	cfg = acfg[tic.area.toLowerCase()];
+	if (tickit.gcfg.links !== undefined)
+		add_links(seenbys, links, tickit.gcfg.links);
+	cfg = tickit.acfg[tic.area.toLowerCase()];
 	if (cfg !== undefined && cfg.links !== undefined)
-		add_links(seenbys, cfg.links);
+		add_links(seenbys, links, cfg.links);
 
 	// Add links to seenbys
 	for (i in links)
@@ -288,12 +179,12 @@ function forward_tic(tic)
 
 	// Now, start generating the TIC/FLO files...
 	for (link in links) {
-		if (!is_flo) {
+		if (!sbbsecho.is_flo) {
 			log(LOG_ERROR, "TickIT doesn't support non-FLO mailers.");
 			return false;
 		}
 
-		pw = get_pw(link);
+		pw = sbbsecho.get_pw(link);
 		if (pw===undefined)
 			pw = '';
 
@@ -307,14 +198,14 @@ function forward_tic(tic)
 			continue;
 		}
 
-		outb = outbound.replace(/[\\\/]+$/g, '');;
+		outb = sbbsecho.outbound.replace(/[\\\/]+$/g, '');
 		if (addr.zone !== defzone)
 			outb += format(".%03x", addr.zone);
 		outb = file_getcase(outb);
 		backslash(outb);
 
 		// Create TIC file first...
-		tf = new File(outb+get_next_tic_filename());
+		tf = new File(outb+tickit.get_next_tic_filename());
 		if(!tf.open("wb")) {
 			log(LOG_ERROR, "Unable to create TIC file for "+link+".  He will not get file '"+tic.file+"'!");
 			continue;
@@ -328,7 +219,7 @@ function forward_tic(tic)
 			tf.write('Path '+tic.path[i]+'\r\n');
 		for (i=0; i<tic.seenby.length; i++)
 			tf.write('Path '+tic.seenby[i]+'\r\n');
-		tf.close;
+		tf.close();
 
 		// Create bsy file...
 		flobase = outb+format("%04x%04x", addr.net, addr.node);
@@ -351,7 +242,7 @@ function forward_tic(tic)
 		ff.writeln('^'+tf.name);
 		ff.close();
 		bf.close();
-		bg.remove();
+		bf.remove();
 	}
 
 	return true;
@@ -375,7 +266,7 @@ function parse_ticfile(fname)
 		log(LOG_ERROR, "Unable to open '"+f.name+"'");
 		return false;
 	}
-	while (line = f.readln(65535)) {
+	while ((line = f.readln(65535)) != undefined) {
 		m = line.match(/^\s*([^\s]+)\s+(.*)$/);
 		if (m !== null) {
 			key = m[1].toLowerCase();
@@ -423,15 +314,15 @@ function parse_ticfile(fname)
 					tic[key] = val;
 					break;
 
-				case 'filename':
+				case 'fullname':
 					outtic.push(line);
-					tic[lfile] = val;
+					tic.lfile = val;
 					break;
 
 				// Multi-line values
 				case 'ldesc':
 					outtic.push(line);
-					tic[key] += val+"\r\n"
+					tic[key] += val+"\r\n";
 					break;
 
 				default:
@@ -471,7 +362,7 @@ function parse_ticfile(fname)
 			return false;
 		}
 	}
-	if (!match_pw(tic.from, tic.pw))
+	if (!sbbsecho.match_pw(tic.from, tic.pw))
 		return false;
 
 	tic[' forward'] = outtic;
@@ -479,75 +370,6 @@ function parse_ticfile(fname)
 	return tic;
 }
 
-function parse_ecfg()
-{
-	var ecfg = new File(system.ctrl_dir+'sbbsecho.cfg');
-	var line;
-	var m;
-
-	if (!ecfg.open("r")) {
-		log(LOG_ERROR, "Unable to open '"+ecfg.name+"'");
-		return false;
-	}
-	while (line=ecfg.readln(65535)) {
-		m = line.match(/^\s*(?:secure_)?inbound\s+(.*)$/i);
-		if (m !== null) {
-			inb.push(backslash(m[1]));
-		}
-		m = line.match(/^\s*pktpwd\s+(.*?)\s+(.*)\s*$/i);
-		if (m !== null) {
-			pktpass[m[1].toUpperCase()] = m[2].toUpperCase();
-		}
-		m = line.match(/^\s*outbound\s+(.*?)\s*$/i);
-		if (m !== null) {
-			outbound = m[1];
-		}
-		m = line.match(/^\s*flo_mailer\s*$/i);
-		if (m !== null) {
-			is_flo = true;
-		}
-	}
-	ecfg.close();
-	return true;
-}
-
-function lcprops(obj)
-{
-	var i;
-
-	for (i in obj) {
-		if (i.toLowerCase() !== i) {
-			if (obj[i.toLowerCase()] === undefined)
-				obj[i.toLowerCase()] = obj[i];
-			if (typeof(obj[i]) == 'Object')
-				lcprops(obj[i]);
-		}
-	}
-}
-
-function parse_tcfg()
-{
-	var tcfg = new File(system.ctrl_dir+'tickit.ini');
-	var sects;
-	var i;
-
-	if (!tcfg.open("r")) {
-		log(LOG_ERROR, "Unable to open '"+tcfg.name+"'");
-		tcfg.close();
-		return false;
-	}
-	gcfg = tcfg.iniGetObject();
-	lcprops(gcfg);
-	sects = tcfg.iniGetSections();
-	for (i=0; i<sects.length; i++) {
-		acfg[sects[i].toLowerCase()] = tcfg.iniGetObject(sects[i]);
-		lcprops(acfg[sects[i].toLowerCase()]);
-	}
-	tcfg.close();
-
-	return true;
-}
-
 function import_files()
 {
 	var i;
@@ -579,16 +401,11 @@ function main() {
 	var tic;
 	var processed = 0;
 
-	if (!parse_ecfg())
-		return false;
-	if (!parse_tcfg())
-		return false;
-
-	for (i=0; i<inb.length; i++) {
+	for (i=0; i<sbbsecho.inb.length; i++) {
 		if (system.platform === 'Win32')
-			ticfiles = directory(inb[i]+'/*.tic');
+			ticfiles = directory(sbbsecho.inb[i]+'/*.tic');
 		else
-			ticfiles = directory(inb[i]+'/*.[Tt][Ii][Cc]');
+			ticfiles = directory(sbbsecho.inb[i]+'/*.[Tt][Ii][Cc]');
 
 		for (j=0; j<ticfiles.length; j++) {
 			tic = parse_ticfile(ticfiles[j]);
diff --git a/exec/tickitcfg.js b/exec/tickitcfg.js
new file mode 100644
index 0000000000..0ad11e01cd
--- /dev/null
+++ b/exec/tickitcfg.js
@@ -0,0 +1,242 @@
+load("sbbsdefs.js");
+load("uifcdefs.js");
+load("tickit_objs.js");
+var tickit = new TickITCfg();
+
+// Backward compatability hack.
+if (typeof uifc.list.CTX === "undefined") {
+	uifc.list.CTX = function () {
+		this.cur = 0;
+		this.bar = 0;
+	}
+}
+
+function pick_dir(obj)
+{
+	var cmd = 0;
+	var libs = Object.keys(file_area.lib);
+	var dirs;
+	var dircodes;
+	var dir;
+	var ctx = new uifc.list.CTX();
+	var dctx;
+	var i;
+
+	if (obj.dir !== undefined && file_area.lib[obj.dir.toLowerCase()] !== undefined) {
+		for (i=0; i<libs.length; i++) {
+			if (file_area.lib[obj.dir.toLowerCase()].dir_name.toLowerCase() === libs[i].toLowerCase()) {
+				ctx.cur = i;
+				ctx.bar = i;
+				break;
+			}
+		}
+	}
+	while (cmd >= 0) {
+		cmd = uifc.list(WIN_SAV|WIN_ACT|WIN_RHT, "Select Group" , libs, ctx);
+		if (cmd >= 0) {
+			dctx = new uifc.list.CTX();
+			dircodes = file_area.lib[libs[cmd]].dir_list.map(function(v){return v.code;});
+			dirs = dircodes.map(function(v){return file_area.dir[v].name;});
+			if (obj.dir !== undefined) {
+				for (i=0; i<dircodes.length; i++) {
+					if (dircodes[i].toLowerCase() === obj.dir.toLowerCase()) {
+						dctx.cur = i;
+						dctx.bar = i;
+					}
+				}
+			}
+			dir = uifc.list(WIN_SAV|WIN_ACT|WIN_BOT, "Select Dir", dirs, dctx);
+			if (dir >= 0) {
+				return dirs[dir];
+			}
+		}
+	}
+	return undefined;
+}
+
+function set_location(obj)
+{
+	var cmd = 0;
+	var dir;
+	var ctx = new uifc.list.CTX();
+	var opts;
+
+	while (cmd >= 0) {
+		opts = ["Synchronet File Directory", "System Path"];
+		opts[0] = ((obj.dir === undefined) ? '  ' : '* ')+opts[0];
+		opts[1] = ((obj.path === undefined) ? '  ' : '* ')+opts[1];
+
+		cmd = uifc.list(WIN_SAV|WIN_ACT, "Location Type", opts, ctx);
+		switch(cmd) {
+		case 0:
+			dir = pick_dir(obj);
+			if (dir !== undefined) {
+				obj.dir = dir;
+				delete obj.path;
+				return;
+			}
+			cmd = 0;
+			break;
+		case 1:
+			dir = null;
+			while(dir !== undefined) {
+				dir = uifc.input(WIN_SAV|WIN_MID, "Path", tickit.gcfg.path === undefined ? '' : tickit.gcfg.path, 1024, K_EDIT);
+				if (dir != undefined) {
+					if (file_isdir(dir)) {
+						delete obj.dir;
+						obj.path = dir;
+						return;
+					}
+					else {
+						uifc.msg("Invalid path!");
+					}
+				}
+			}
+			break;
+		}
+	}
+}
+
+function edit_links(links)
+{
+	var tmp;
+	var link = 0;
+	var ctx = new uifc.list.CTX();
+
+	while (link >= 0) {
+		link = uifc.list(WIN_SAV|WIN_ACT|WIN_DEL|WIN_INS|WIN_DELACT|WIN_XTR, "Links", links, ctx);
+		if (link == -1) {
+			break;
+		}
+		if (link == links.length || (link & MSK_INS) == MSK_INS) {
+			link &= MSK_OFF;
+			tmp = uifc.input(WIN_SAV|WIN_MID, "Address", 30);
+			if (tmp !== undefined)
+				links.splice(link, 0, tmp);
+		}
+		if (link & MSK_DEL) {
+			link &= MSK_OFF;
+			links.splice(link, 1);
+		}
+	}
+
+	return links;
+}
+
+function edit_area(obj, name)
+{
+	var cmd = 0;
+	var link = 0;
+	var links;
+	var menu = ["Location", "Links"];
+	var tmp;
+	var tmp2;
+	var ctx = new uifc.list.CTX();
+
+	while(cmd >= 0) {
+		cmd = uifc.list(WIN_SAV|WIN_ACT|WIN_BOT|WIN_RHT, name+" Options", menu, ctx);
+		switch(cmd) {
+			case 0:
+				set_location(obj);
+				break;
+			case 1:
+				if (obj.links === undefined)
+					links = [];
+				else
+					links = obj.links.split(/,/);
+				tmp = edit_links(links);
+				if (tmp.length === 0)
+					delete obj.links;
+				else
+					obj.links = tmp.join(',');
+				break;
+			case -1:
+				// Save changes?
+				break;
+			default:
+				uifc.msg("Unhandled Return: "+cmd);
+				break;
+		}
+	}
+}
+
+function edit_areas()
+{
+	var areas;
+	var area = 0;
+	var tmp;
+	var ctx = new uifc.list.CTX();
+
+	while(area >= 0) {
+		areas = Object.keys(tickit.acfg).sort();
+		area = uifc.list(WIN_SAV|WIN_BOT|WIN_ACT|WIN_DEL|WIN_INS|WIN_DELACT|WIN_XTR, "Select Area", areas, ctx);
+		if (area == -1) {
+			break;
+		}
+		else if (area == areas.length || (area & MSK_INS) == MSK_INS) {
+			area &= MSK_OFF;
+			tmp = uifc.input(WIN_SAV|WIN_MID, "Area", 30);
+			if (tmp !== undefined) {
+				if (tickit.acfg[tmp.toLowerCase()] === undefined) {
+					tickit.acfg[tmp.toLowerCase()] = {};
+					edit_area(tickit.acfg[areas[area]], tmp.toLowerCase());
+				}
+				else {
+					uifc.msg("Area already in config!");
+				}
+			}
+		}
+		else if (area & MSK_DEL) {
+			area &= MSK_OFF;
+			delete tickit.acfg[areas[area]];
+		}
+		else {
+			edit_area(tickit.acfg[areas[area]], areas[area]);
+		}
+	}
+}
+
+function main()
+{
+	uifc.init("TickIT Config Program");
+
+	var cmd = 0;
+	var link = 0;
+	var links;
+	var menu = ["Global Location", "Global Links", "Areas..."];
+	var tmp;
+	var tmp2;
+	var ctx = new uifc.list.CTX();
+
+	while(cmd >= 0) {
+		cmd = uifc.list(WIN_ORG|WIN_ACT|WIN_MID, "Global Options", menu, ctx);
+		switch(cmd) {
+			case 0:
+				set_location(tickit.gcfg);
+				break;
+			case 1:
+				if (tickit.gcfg.links === undefined)
+					links = [];
+				else
+					links = tickit.gcfg.links.split(/,/);
+				tmp = edit_links(links);
+				if (tmp.length === 0)
+					delete tickit.gcfg.links;
+				else
+					tickit.gcfg.links = tmp.join(',');
+				break;
+			case 2:
+				edit_areas();
+				uifc.bail();
+				break;
+			case -1:
+				// TODO: Save changes?
+				break;
+			default:
+				uifc.msg("Unhandled Return: "+cmd);
+				break;
+		}
+	}
+}
+
+main();
-- 
GitLab