...
 
Commits (1)
  • Rob Swindell's avatar
    Support 2 new section types: pre-exec and pre-eval · bda6ea96
    Rob Swindell authored
    Just like the exec and eval sections, except executed/evaluated *before*
    any external programs are installed.
    New optional 'fail' key to specify a custom failure message.
    Example:
    [pre-eval:file_exists(startup_dir + 'test.txt')]
    prompt = false
    required = true
    fail = You must create text.txt before you can install.
    bda6ea96
......@@ -25,6 +25,12 @@
//
// The .ini sections and keys supported (zero or more of each may be included):
//
// [pre-exec:<file>.js [args]] ; execute file.js before installing programs
// startup_dir = directory to make current before execution
//
// [pre-eval:<js-expression>] ; evaluate js-expression before installing progs
// cmd = evaluate this string rather than the js-expression
//
// [prog:<code>]
// name = program name or description (40 chars max)
// cats = additional target installation categories (sections)
......@@ -61,10 +67,10 @@
// [service:<protocol>]
// see ctrl/services.ini
//
// [exec:<file>.js [args]] ; execute file.js with these arguments
// [exec:<file>.js [args]] ; execute file.js with these arguments - after
// startup_dir = directory to make current before execution
//
// [eval:<js-expression>]
// [eval:<js-expression>] ; evaluate js-expression after installing programs
// cmd = evaluate this string rather than the js-expression
//
// [ini:<filename.ini>[:section]]
......@@ -75,8 +81,9 @@
// Additionally, each section can have the following optional keys that are
// only used by this script (i.e. not written to any configuration files):
// note = note to sysop displayed before installation
// fail = note to sysop displayed upon failure
// prompt = confirmation prompt (or false if no prompting)
// required = if true, this item must be installed to continue
// required = if true, this item must be successful to continue
// last = if true, this item will be the last of its type
// done = if true, no more installer items will be processed
//
......@@ -91,7 +98,7 @@
"use strict";
const REVISION = "3.18b";
const REVISION = "3.18c";
const ini_fname = "install-xtrn.ini";
load("sbbsdefs.js");
......@@ -210,6 +217,76 @@ function install_xtrn_item(cnf, type, name, desc, item, cats)
return true;
}
function install_exec_cmd(ini_file, section, startup_dir)
{
var list = ini_file.iniGetAllObjects("cmd", section);
for (var i = 0; i < list.length; i++) {
var item = list[i];
var js_args = item.cmd.split(/\s+/);
var js_file = js_args.shift();
if (file_getext(js_file).toLowerCase() != ".js")
return "Only '.js' files may be executed: " + js_file;
if (item.note)
print(item.note);
var prompt = "Execute: " + item.cmd;
if (item.prompt !== undefined)
prompt = item.prompt;
if (prompt && !confirm(prompt)) {
if (item.required == true)
return prompt + " is required to continue";
continue;
}
if (item.startup_dir === undefined)
item.startup_dir = startup_dir;
if (!item.args)
item.args = "";
var result = js.exec.apply(null
,[js_file, item.startup_dir, {}].concat(js_args));
if (result !== 0 && item.required)
return item.fail || ("Error " + result + " executing " + item.cmd);
if (item.last === true)
break;
if (item.done)
return false;
}
return true;
}
function install_eval_cmd(ini_file, section, startup_dir)
{
var list = ini_file.iniGetAllObjects("str", section);
for (var i = 0; i < list.length; i++) {
var item = list[i];
if (!item.cmd)
item.cmd = item.str; // the str can't contain [], so allow cmd to override
var prompt = "Evaluate: " + item.cmd;
if (item.prompt !== undefined)
prompt = item.prompt;
if (prompt && !confirm(prompt)) {
if (item.required == true)
return prompt + " is required to continue";
continue;
}
try {
var result = eval(item.cmd);
} catch(e) {
return e;
}
if (!result && item.required)
return item.fail || ("Truthful evaluation of '" + item.cmd + "' is required to continue");
if (item.last === true)
break;
if (item.done)
return false;
}
return true;
}
function install(ini_fname)
{
ini_fname = fullpath(ini_fname);
......@@ -254,6 +331,14 @@ function install(ini_fname)
var startup_dir = ini_fname.substr(0, Math.max(ini_fname.lastIndexOf("/"), ini_fname.lastIndexOf("\\"), 0));
startup_dir = relpath.get(system.ctrl_dir, startup_dir);
var result = install_exec_cmd(ini_file, "pre-exec:", startup_dir);
if(result !== true)
return result;
result = install_eval_cmd(ini_file, "pre-eval:", startup_dir);
if(result !== true)
return result;
const types = {
prog: { desc: "External Program", struct: "xtrn" },
event: { desc: "External Timed Event", struct: "event" },
......@@ -276,7 +361,7 @@ function install(ini_fname)
return false;
if(item.last === true)
break;
done = item.done;
done = Boolean(item.done);
}
}
......@@ -318,7 +403,7 @@ function install(ini_fname)
return false;
if(item.last === true)
break;
done = item.done;
done = Boolean(item.done);
}
var services_ini = new File(file_cfgname(system.ctrl_dir, "services.ini"));
......@@ -358,69 +443,21 @@ function install(ini_fname)
return false;
if(item.last === true)
break;
done = item.done;
done = Boolean(item.done);
}
var list = ini_file.iniGetAllObjects("cmd", "exec:");
for (var i = 0; i < list.length && !done; i++) {
var item = list[i];
var js_args = item.cmd.split(/\s+/);
var js_file = js_args.shift();
if (file_getext(js_file).toLowerCase() != ".js")
return "Only '.js' files may be executed: " + js_file;
if (item.note)
print(item.note);
var prompt = "Execute: " + item.cmd;
if (item.prompt !== undefined)
prompt = item.prompt;
if (prompt && !confirm(prompt)) {
if (item.required == true)
return prompt + " is required to continue";
continue;
}
if (item.startup_dir === undefined)
item.startup_dir = startup_dir;
if (!item.args)
item.args = "";
var result = js.exec.apply(null
,[js_file, item.startup_dir, {}].concat(js_args));
if (result !== 0 && item.required)
return "Error " + result + " executing " + item.cmd;
if(item.last === true)
return true;
done = item.done;
if(done === false) {
result = install_exec_cmd(ini_file, "exec:", startup_dir);
if(typeof result !== 'boolean')
return result;
done = !result;
}
var list = ini_file.iniGetAllObjects("str", "eval:");
for (var i = 0; i < list.length && !done; i++) {
var item = list[i];
if (!item.cmd)
item.cmd = item.str; // the str can't contain [], so allow cmd to override
var prompt = "Evaluate: " + item.cmd;
if (item.prompt !== undefined)
prompt = item.prompt;
if (prompt && !confirm(prompt)) {
if (item.required == true)
return prompt + " is required to continue";
continue;
}
try {
var result = eval(item.cmd);
} catch(e) {
return e;
}
if (!result) {
if (item.required == true)
return "Truthful evaluation of '" + item.cmd + "' is required to continue";
}
if(item.last === true)
return true;
done = item.done;
if(done === false) {
result = install_eval_cmd(ini_file, "eval:", startup_dir);
if(typeof result !== 'boolean')
return result;
done = !result;
}
if (installed) {
......