Skip to content
Snippets Groups Projects
Commit bda6ea96 authored by Rob Swindell's avatar Rob Swindell :speech_balloon:
Browse files

Support 2 new section types: pre-exec and pre-eval

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.
parent a21d87d8
No related branches found
No related tags found
1 merge request!463MRC mods by Codefenix (2024-10-20)
Pipeline #952 passed
...@@ -25,6 +25,12 @@ ...@@ -25,6 +25,12 @@
// //
// The .ini sections and keys supported (zero or more of each may be included): // 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>] // [prog:<code>]
// name = program name or description (40 chars max) // name = program name or description (40 chars max)
// cats = additional target installation categories (sections) // cats = additional target installation categories (sections)
...@@ -61,10 +67,10 @@ ...@@ -61,10 +67,10 @@
// [service:<protocol>] // [service:<protocol>]
// see ctrl/services.ini // 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 // 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 // cmd = evaluate this string rather than the js-expression
// //
// [ini:<filename.ini>[:section]] // [ini:<filename.ini>[:section]]
...@@ -75,8 +81,9 @@ ...@@ -75,8 +81,9 @@
// Additionally, each section can have the following optional keys that are // Additionally, each section can have the following optional keys that are
// only used by this script (i.e. not written to any configuration files): // only used by this script (i.e. not written to any configuration files):
// note = note to sysop displayed before installation // note = note to sysop displayed before installation
// fail = note to sysop displayed upon failure
// prompt = confirmation prompt (or false if no prompting) // 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 // last = if true, this item will be the last of its type
// done = if true, no more installer items will be processed // done = if true, no more installer items will be processed
// //
...@@ -91,7 +98,7 @@ ...@@ -91,7 +98,7 @@
"use strict"; "use strict";
const REVISION = "3.18b"; const REVISION = "3.18c";
const ini_fname = "install-xtrn.ini"; const ini_fname = "install-xtrn.ini";
load("sbbsdefs.js"); load("sbbsdefs.js");
...@@ -210,6 +217,76 @@ function install_xtrn_item(cnf, type, name, desc, item, cats) ...@@ -210,6 +217,76 @@ function install_xtrn_item(cnf, type, name, desc, item, cats)
return true; 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) function install(ini_fname)
{ {
ini_fname = fullpath(ini_fname); ini_fname = fullpath(ini_fname);
...@@ -254,6 +331,14 @@ function install(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)); 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); 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 = { const types = {
prog: { desc: "External Program", struct: "xtrn" }, prog: { desc: "External Program", struct: "xtrn" },
event: { desc: "External Timed Event", struct: "event" }, event: { desc: "External Timed Event", struct: "event" },
...@@ -276,7 +361,7 @@ function install(ini_fname) ...@@ -276,7 +361,7 @@ function install(ini_fname)
return false; return false;
if(item.last === true) if(item.last === true)
break; break;
done = item.done; done = Boolean(item.done);
} }
} }
...@@ -318,7 +403,7 @@ function install(ini_fname) ...@@ -318,7 +403,7 @@ function install(ini_fname)
return false; return false;
if(item.last === true) if(item.last === true)
break; break;
done = item.done; done = Boolean(item.done);
} }
var services_ini = new File(file_cfgname(system.ctrl_dir, "services.ini")); var services_ini = new File(file_cfgname(system.ctrl_dir, "services.ini"));
...@@ -358,69 +443,21 @@ function install(ini_fname) ...@@ -358,69 +443,21 @@ function install(ini_fname)
return false; return false;
if(item.last === true) if(item.last === true)
break; break;
done = item.done; done = Boolean(item.done);
} }
var list = ini_file.iniGetAllObjects("cmd", "exec:"); if(done === false) {
for (var i = 0; i < list.length && !done; i++) { result = install_exec_cmd(ini_file, "exec:", startup_dir);
var item = list[i]; if(typeof result !== 'boolean')
var js_args = item.cmd.split(/\s+/); return result;
var js_file = js_args.shift(); done = !result;
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;
} }
var list = ini_file.iniGetAllObjects("str", "eval:"); if(done === false) {
for (var i = 0; i < list.length && !done; i++) { result = install_eval_cmd(ini_file, "eval:", startup_dir);
var item = list[i]; if(typeof result !== 'boolean')
if (!item.cmd) return result;
item.cmd = item.str; // the str can't contain [], so allow cmd to override done = !result;
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 (installed) { if (installed) {
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment