diff --git a/cli.js b/cli.js index 0e3350c2..c4b1a5c7 100755 --- a/cli.js +++ b/cli.js @@ -7,11 +7,11 @@ 'use strict'; const fs = require("fs"); -const path = require("path"); -const chef = require("cyberchef"); -const program = require("commander"); + +///////// Helper Functions ///////// let slurpStream = (istream) => { // {{{1 + // Slurp the contents of a stream up into a Buffer to pass to CyberChef var ret = []; var len = 0; return new Promise(resolve => { @@ -27,12 +27,13 @@ let slurpStream = (istream) => { // {{{1 }; // }}}1 let slurp = (fname) => { // {{{1 + // Slurp the contents of a file (or stdin) into a Buffer let istream; if (fname === undefined || fname == '-') { istream = process.stdin; if (istream.isTTY) { - throw new Error("TTY input not supported"); + return Promise.reject(new Error("TTY input not supported")); } } else { @@ -53,16 +54,30 @@ let getPort = (value, dummyPrevious) => { // {{{1 ///////// MAIN ///////// {{{1 +const chef = require("cyberchef"); +const program = require("commander"); + program .version(require('./package.json').version) + .description('Bake data from files and/or TCP clients ' + + 'using a CyberChef recipe.') .usage('[options] [file [file ...]]') .requiredOption('-r, --recipe-file ', 'recipe JSON file') .option('-l, --listen [port]', - 'listen on TCP port for data (default:random)', getPort, false) + 'listen on TCP port for data (random if not given)', getPort, false) .option('-o, --output ', - 'write result here (not for TCP; default:stdout)') - .parse(process.argv); + 'where to write result (file input only; default:stdout)'); + +try { + program.exitOverride().parse(process.argv); +} +catch (e) { + if (e.code != 'commander.helpDisplayed') { + console.error("Run with '--help' for usage"); + } + process.exit(1); +} // If we get no inputs and we aren't running a server, // make stdin our single input @@ -73,6 +88,7 @@ if (inputs.length == 0 && !program.listen) { // Likewise stdout for our output let ostream; +let path; let outputIsDir = false; if (program.output === undefined && !program.listen) { ostream = process.stdout; @@ -85,20 +101,22 @@ else if (inputs.length > 0) { outputIsDir = st.isDirectory(); } catch(err) { + // We're fine if the output doesn't exist yet if (err.code != 'ENOENT') throw err; } if (!outputIsDir) { ostream = fs.createWriteStream(program.output); } } +if (outputIsDir) path = require("path"); let recipe; slurp(program.recipeFile).then((data) => { recipe = JSON.parse(data); }) .catch((err) => { - console.error(`Error parsing recipe: ${err}`); - process.exit(1); + console.error(`Error parsing recipe: ${err.message}`); + process.exit(2); }) .then(() => { // First, deal with any files we want to read @@ -113,9 +131,14 @@ slurp(program.recipeFile).then((data) => { } ostream.write(output.presentAs("string", true)); if (outputIsDir) ostream.end(); + }, + (err) => { + console.error(err.message); + process.exitCode = 2; }) .catch((err) => { - console.error(err); + console.error(err.message); + process.exitCode = 2; }); } @@ -135,7 +158,7 @@ slurp(program.recipeFile).then((data) => { }); }); - // If no port given, let the OS choose one + // If no port given by user, let the OS choose one if (program.listen === true) program.listen = 0; server.listen(program.listen, '127.0.0.1') .on('listening', () => { @@ -153,5 +176,5 @@ slurp(program.recipeFile).then((data) => { }) .catch((err) => { console.error(err); - process.exit(2); + process.exit(3); })