var Zmodem = require('./zmodem'); module.exports = { /** * Return an array with the given number of random octet values. * * @param {Array} count - The number of octet values to return. * * @returns {Array} The octet values. */ get_random_octets(count) { if (!(count > 0)) throw( "Must be positive, not " + count ); var octets = []; //This assigns backwards both for convenience and so that //the initial assignment allocates the needed size. while (count) { octets[count - 1] = Math.floor( Math.random() * 256 ); count--; } return octets; }, //This is meant NOT to do UTF-8 stuff since it handles \xXX. string_to_octets(string) { return string.split("").map( (c) => c.charCodeAt(0) ); }, make_temp_dir() { return require('tmp').dirSync().name; }, make_temp_file(size) { const fs = require('fs'); const tmp = require('tmp'); var tmpobj = tmp.fileSync(); var content = Array(size).fill("x").join(""); fs.writeSync( tmpobj.fd, content ); fs.writeSync( tmpobj.fd, "=THE_END" ); fs.closeSync( tmpobj.fd ); return tmpobj.name; }, make_empty_temp_file() { const fs = require('fs'); const tmp = require('tmp'); var tmpobj = tmp.fileSync(); fs.closeSync( tmpobj.fd ); return tmpobj.name; }, exec_lrzsz_steps(t, binpath, z_args, steps) { const spawn = require('child_process').spawn; var child; var zsession; var zsentry = new Zmodem.Sentry( { to_terminal: Object, on_detect: (d) => { zsession = d.confirm() }, on_retract: console.error.bind(console), sender: (d) => { child.stdin.write( new Buffer(d) ); }, } ); var step = 0; var inputs = []; child = spawn(binpath, z_args); console.log("child PID:", child.pid); child.on("error", console.error.bind(console)); child.stdin.on("close", () => console.log(`# PID ${child.pid} STDIN closed`)); child.stdout.on("close", () => console.log(`# PID ${child.pid} STDOUT closed`)); child.stderr.on("close", () => console.log(`# PID ${child.pid} STDERR closed`)); //We can’t just pipe this on through because there can be lone CR //bytes which screw up TAP::Harness. child.stderr.on("data", (d) => { d = d.toString().replace(/\r\n?/g, "\n"); if (d.substr(-1) !== "\n") d += "\n"; process.stderr.write(`STDERR: ${d}`); }); child.stdout.on("data", (d) => { //console.log(`STDOUT from PID ${child.pid}`, d); inputs.push( Array.from(d) ); zsentry.consume( Array.from(d) ); if (zsession) { if ( steps[step] ) { if ( steps[step](zsession, child) ) { step++; } } else { console.log(`End of task list; closing PID ${child.pid}’s STDIN`); child.stdin.end(); } } }); var exit_promise = new Promise( (res, rej) => { child.on("exit", (code, signal) => { console.log(`# "${binpath}" exit: code ${code}, signal ${signal}`); res([code, signal]); } ); } ); return exit_promise.then( () => { return inputs } ); }, };