From 0e2b62f0663eefdacb128853aa8417a645d0c88d Mon Sep 17 00:00:00 2001 From: rswindell <> Date: Sun, 29 Mar 2020 06:16:31 +0000 Subject: [PATCH] Now supports a -overwrite cmdline option which can be used to allow the overwrite of existing items (i.e. programs with the same internal code). Add support for [exec:<file>.js] sections: for executing another JavaScript files as part of the install. Add support for [eval:string] sections: for evaluating a JavaScript expression as part of an install. Add support for an optional "prompt" key for each item. If set to a string, overrides the default confirmation prompt text. If set to false, disables the confirmation prompt for that item. --- exec/install-xtrn.js | 123 +++++++++++++++++++++++++++++++++---------- 1 file changed, 94 insertions(+), 29 deletions(-) diff --git a/exec/install-xtrn.js b/exec/install-xtrn.js index af3efc89d1..4e04f598b3 100644 --- a/exec/install-xtrn.js +++ b/exec/install-xtrn.js @@ -17,7 +17,7 @@ // The .ini sections and keys supported (zero or more of each may be included): // // [prog:<code>] -// name = Program name or description (40 chars max) +// name = program name or description (40 chars max) // cmd = command-line to execute (63 chars max) // clean_cmd = clean-up command-line, if needed (63 chars max) // settings = bit-flags (see XTRN_* in sbbsdefs.js) @@ -42,16 +42,24 @@ // months = bit-field representing which months to execute // // [editor:<code>] -// name = Editr name or description (40 chars max) +// name = editor name or description (40 chars max) // cmd = command-line to execute (63 chars max) // type = drop-file type (see XTRN_* in sbbsdefs.js) // settings = bit-flags (see XTRN_* in sbbsdefs.js) // ars = access requirements string (40 chars max) +// +// [exec:<file>.js] +// args = execute file.js with this argument string +// startup_dir = directory to make current before execution +// +// [eval:<js-expression>] +// cmd = evaluate this string rather than the js-expression -// Additionally, each object can have the following optional keys that are only -// used by this script -// note = Note to sysop displayed before installation -// required = If true, this item must be installed to continue +// 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 +// prompt = confirmation prompt (or false if no prompting) +// required = if true, this item must be installed to continue // // Notes: // @@ -65,8 +73,11 @@ "use strict"; load("sbbsdefs.js"); -const ini_fname = "install-xtrn.ini" -var debug = false; +const ini_fname = "install-xtrn.ini"; +var options = { + debug: false, + overwrite: false +}; function install_xtrn_item(cnf, type, desc, item) { @@ -79,13 +90,17 @@ function install_xtrn_item(cnf, type, desc, item) if (item.note) print(item.note); - if (!confirm("Install " + desc + ": " + item.name)) { + var prompt = "Install " + desc + ": " + item.name; + if (item.prompt !== undefined) + prompt = item.prompt; + + if (prompt && !confirm(prompt)) { if (item.required == true) return "Installation of " + item.name + " is required to continue"; return false; } - if(type == "xtrn") { + if (type == "xtrn") { if (!xtrn_area.sec_list.length) return "No external program sections have been created"; @@ -94,7 +109,7 @@ function install_xtrn_item(cnf, type, desc, item) var which; while (!which || which > xtrn_area.sec_list.length) - which = prompt("Install " + item.name + " into which External Program Section"); + which = js.global.prompt("Install " + item.name + " into which External Program Section"); which = parseInt(which, 10); if (!which) return false; @@ -104,16 +119,18 @@ function install_xtrn_item(cnf, type, desc, item) function find_code(objs, code) { - for(var i=0; i < objs.length; i++) - if(objs[i].code.toLowerCase() == code.toLowerCase()) - return i; + if (!options.overwrite) { + for (var i=0; i < objs.length; i++) + if (objs[i].code.toLowerCase() == code.toLowerCase()) + return i; + } return -1; } while (!item.code || (find_code(cnf[type], item.code) >= 0 && print(desc + " Internal Code (" + item.code + ") already exists!"))) - item.code = prompt(desc + " Internal code"); + item.code = js.global.prompt(desc + " Internal code"); try { item.code = item.code.toUpperCase(); @@ -127,7 +144,7 @@ function install_xtrn_item(cnf, type, desc, item) return e; } cnf[type].push(item); - if(debug) + if (options.debug) print(JSON.stringify(cnf[type], null, 4)); print(desc + " (" + item.name + ") installed successfully"); @@ -162,12 +179,13 @@ function main(ini_fname) editor: { desc: "External Editor", struct: "xedit" } }; - for(var t in types) { + for (var t in types) { var list = ini_file.iniGetAllObjects("code", t + ":"); for (var i = 0; i < list.length; i++) { - if (list[i].startup_dir === undefined) - list[i].startup_dir = startup_dir; - var result = install_xtrn_item(xtrn_cnf, types[t].struct, types[t].desc, list[i]); + var item = list[i]; + if (item.startup_dir === undefined) + item.startup_dir = startup_dir; + var result = install_xtrn_item(xtrn_cnf, types[t].struct, types[t].desc, item); if (typeof result !== 'boolean') return result; if (result === true) @@ -175,8 +193,58 @@ function main(ini_fname) } } + var list = ini_file.iniGetAllObjects("file", "exec:"); + for (var i = 0; i < list.length; i++) { + var item = list[i]; + + if (file_getext(item.file) != ".js") + return "Only '.js' files may be executed: " + item.file; + + if (item.note) + print(item.note); + + var prompt = "Execute: " + item.file; + if (item.prompt !== undefined) + prompt = item.prompt; + else if (item.args) + prompt += " " + item.args; + + 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 (typeof item.args == 'string' && item.args.indexOf(' ') > 0) + item.args = item.args.split(' '); + var result = js.exec(item.file, item.startup_dir, {}, item.args); + if (result !== 0 && item.required) + return "Error " + result + " executing " + item.file; + } + + var list = ini_file.iniGetAllObjects("str", "eval:"); + 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; + } + if (!eval(item.cmd)) { + if (item.required == true) + return "Truthful evaluation of '" + item.cmd + "' is required to continue"; + } + } + if (installed) { - if (!debug && !cnflib.write("xtrn.cnf", undefined, xtrn_cnf)) + if (!options.debug && !cnflib.write("xtrn.cnf", undefined, xtrn_cnf)) return "Failed to write xtrn.cnf"; print("Installed " + installed + " items from " + ini_fname + " successfully"); } @@ -187,15 +255,12 @@ function main(ini_fname) // Command-line argument parsing var ini_path; for (var i = 0; i < argc; i++) { - switch (argv[i]) { - case "-debug": - debug = true; - break; - default: - ini_path = argv[i]; - break; - } + if (argv[i][0] == '-') + options[argv[i].substr(1)] = true; + else if (!ini_path) + ini_path = argv[i]; } + // Locate the .ini file if (file_isdir(ini_path)) ini_path = backslash(ini_path) + ini_fname; -- GitLab