this.prepareSocketIoServer( (err, sockServer) => { if(err) { this.client.log.warn( { error : err.toString() }, 'Failed executing door'); return self.doorExited(); } // Expand arg strings, e.g. {dropFile} -> DOOR32.SYS let args = _.clone(self.exeInfo.args); // we need a copy so the original is not modified for(let i = 0; i < args.length; ++i) { args[i] = self.exeInfo.args[i].format({ dropFile : self.exeInfo.dropFile, node : self.exeInfo.node.toString(), srvPort : sockServer ? sockServer.address().port.toString() : '-1', userId : self.client.user.userId.toString(), }); } const door = pty.spawn(self.exeInfo.cmd, args, { cols : self.client.term.termWidth, rows : self.client.term.termHeight, // :TODO: cwd env : self.exeInfo.env, }); if('stdio' === self.exeInfo.io) { self.client.log.debug('Using stdio for door I/O'); self.client.term.output.pipe(door); door.on('data', self.doorDataHandler); door.once('close', () => { return self.restoreIo(door); }); } else if('socket' === self.exeInfo.io) { self.client.log.debug( { port : sockServer.address().port }, 'Using temporary socket server for door I/O'); } door.once('exit', exitCode => { self.client.log.info( { exitCode : exitCode }, 'Door exited'); if(sockServer) { sockServer.close(); } // we may not get a close if('stdio' === self.exeInfo.io) { self.restoreIo(door); } door.removeAllListeners(); return self.doorExited(); }); });
function launch(callback) { // Expand arg strings, e.g. {dropFile} -> DOOR32.SYS var args = _.clone(self.exeInfo.args); // we need a copy so the original is not modified for(var i = 0; i < args.length; ++i) { args[i] = self.exeInfo.args[i].format({ dropFile : self.exeInfo.dropFile, node : self.exeInfo.node.toString(), //inhSocket : self.exeInfo.inhSocket.toString(), srvPort : sockServer ? sockServer.address().port.toString() : '-1', userId : self.client.user.userId.toString(), }); } var door = pty.spawn(self.exeInfo.cmd, args, { cols : self.client.term.termWidth, rows : self.client.term.termHeight, // :TODO: cwd env : self.exeInfo.env, }); if('stdio' === self.exeInfo.io) { self.client.log.debug('Using stdio for door I/O'); self.client.term.output.pipe(door); door.on('data', doorData); door.on('close', function closed() { restore(door); }); } else if('socket' === self.exeInfo.io) { self.client.log.debug( { port : sockServer.address().port }, 'Using temporary socket server for door I/O'); } door.on('exit', function exited(code) { self.client.log.info( { code : code }, 'Door exited'); if(sockServer) { sockServer.close(); } // we may not get a close if('stdio' === self.exeInfo.io) { restore(door); } door.removeAllListeners(); self.emit('finished'); }); }
listEntries(archivePath, archType, cb) { const archiver = this.getArchiver(archType); if(!archiver) { return cb(Errors.Invalid(`Unknown archive type: ${archType}`)); } const fmtObj = { archivePath : archivePath, }; const args = archiver.list.args.map( arg => stringFormat(arg, fmtObj) ); let proc; try { proc = pty.spawn(archiver.list.cmd, args, this.getPtyOpts()); } catch(e) { return cb(e); } let output = ''; proc.on('data', data => { // :TODO: hack for: execvp(3) failed.: No such file or directory output += data; }); proc.once('exit', exitCode => { if(exitCode) { return cb(Errors.ExternalProcess(`List failed with exit code: ${exitCode}`)); } const entryGroupOrder = archiver.list.entryGroupOrder || { byteSize : 1, fileName : 2 }; const entries = []; const entryMatchRe = new RegExp(archiver.list.entryMatch, 'gm'); let m; while((m = entryMatchRe.exec(output))) { entries.push({ byteSize : parseInt(m[entryGroupOrder.byteSize]), fileName : m[entryGroupOrder.fileName].trim(), }); } return cb(null, entries); }); }
executeAction(reason, cb) { Log.info( { eventName : this.name, action : this.action, reason : reason }, 'Executing scheduled event action...'); if('method' === this.action.type) { const modulePath = path.join(__dirname, '../', this.action.location); // enigma-bbs base + supplied location (path/file.js') try { const methodModule = require(modulePath); methodModule[this.action.what](this.action.args, err => { if(err) { Log.debug( { error : err.toString(), eventName : this.name, action : this.action }, 'Error performing scheduled event action'); } return cb(err); }); } catch(e) { Log.warn( { error : e.toString(), eventName : this.name, action : this.action }, 'Failed to perform scheduled event action'); return cb(e); } } else if('execute' === this.action.type) { const opts = { // :TODO: cwd name : this.name, cols : 80, rows : 24, env : process.env, }; const proc = pty.spawn(this.action.what, this.action.args, opts); proc.once('exit', exitCode => { if(exitCode) { Log.warn( { eventName : this.name, action : this.action, exitCode : exitCode }, 'Bad exit code while performing scheduled event action'); } return cb(exitCode ? new Error(`Bad exit code while performing scheduled event action: ${exitCode}`) : null); }); } }
extractTo(archivePath, extractPath, archType, fileList, cb) { let haveFileList; if(!cb && _.isFunction(fileList)) { cb = fileList; fileList = []; haveFileList = false; } else { haveFileList = true; } const archiver = this.getArchiver(archType); if(!archiver) { return cb(Errors.Invalid(`Unknown archive type: ${archType}`)); } const fmtObj = { archivePath : archivePath, extractPath : extractPath, }; const action = haveFileList ? 'extract' : 'decompress'; // we need to treat {fileList} special in that it should be broken up to 0:n args const args = archiver[action].args.map( arg => { return '{fileList}' === arg ? arg : stringFormat(arg, fmtObj); }); const fileListPos = args.indexOf('{fileList}'); if(fileListPos > -1) { // replace {fileList} with 0:n sep file list arguments args.splice.apply(args, [fileListPos, 1].concat(fileList)); } let proc; try { proc = pty.spawn(archiver[action].cmd, args, this.getPtyOpts()); } catch(e) { return cb(e); } return this.spawnHandler(proc, (haveFileList ? 'Extraction' : 'Decompression'), cb); }
compressTo(archType, archivePath, files, cb) { const archiver = this.getArchiver(archType); if(!archiver) { return cb(Errors.Invalid(`Unknown archive type: ${archType}`)); } const fmtObj = { archivePath : archivePath, fileList : files.join(' '), // :TODO: probably need same hack as extractTo here! }; const args = archiver.compress.args.map( arg => stringFormat(arg, fmtObj) ); let proc; try { proc = pty.spawn(archiver.compress.cmd, args, this.getPtyOpts()); } catch(e) { return cb(e); } return this.spawnHandler(proc, 'Compression', cb); }