133 lines
3.3 KiB
JavaScript
133 lines
3.3 KiB
JavaScript
/* jslint node: true */
|
|
'use strict';
|
|
|
|
// enigma-bbs
|
|
const MenuModule = require('./menu_module.js').MenuModule;
|
|
const Config = require('./config.js').config;
|
|
const stringFormat = require('./string_format.js');
|
|
|
|
// deps
|
|
const async = require('async');
|
|
const _ = require('lodash');
|
|
const pty = require('ptyw.js');
|
|
|
|
/*
|
|
Resources
|
|
|
|
ZModem
|
|
* http://gallium.inria.fr/~doligez/zmodem/zmodem.txt
|
|
* https://github.com/protomouse/synchronet/blob/master/src/sbbs3/zmodem.c
|
|
*/
|
|
|
|
exports.moduleInfo = {
|
|
name : 'Transfer file',
|
|
desc : 'Sends or receives a file(s)',
|
|
author : 'NuSkooler',
|
|
};
|
|
|
|
exports.getModule = class TransferFileModule extends MenuModule {
|
|
constructor(options) {
|
|
super(options);
|
|
|
|
this.config = this.menuConfig.config || {};
|
|
this.config.protocol = this.config.protocol || 'zmodem8kSz';
|
|
this.config.direction = this.config.direction || 'send';
|
|
|
|
this.protocolConfig = Config.fileTransferProtocols[this.config.protocol];
|
|
|
|
// :TODO: bring in extraArgs for path(s) to send when sending; Allow to hard code in config (e.g. for info pack/static downloads)
|
|
}
|
|
|
|
restorePipeAfterExternalProc(pipe) {
|
|
if(!this.pipeRestored) {
|
|
this.pipeRestored = true;
|
|
|
|
this.client.term.output.unpipe(pipe);
|
|
this.client.term.output.resume();
|
|
}
|
|
}
|
|
|
|
sendFiles(cb) {
|
|
async.eachSeries(this.sendQueue, (filePath, next) => {
|
|
// :TODO: built in protocols
|
|
// :TODO: use protocol passed in
|
|
this.executeExternalProtocolHandler(filePath, err => {
|
|
return next(err);
|
|
});
|
|
}, err => {
|
|
return cb(err);
|
|
});
|
|
}
|
|
|
|
executeExternalProtocolHandler(filePath, cb) {
|
|
const external = this.protocolConfig.external;
|
|
const cmd = external[`${this.config.direction}Cmd`];
|
|
const args = external[`${this.config.direction}Args`].map(arg => {
|
|
return stringFormat(arg, {
|
|
filePath : filePath,
|
|
});
|
|
});
|
|
|
|
/*this.client.term.rawWrite(new Buffer(
|
|
[
|
|
255, 253, 0, // IAC DO TRANSMIT_BINARY
|
|
255, 251, 0, // IAC WILL TRANSMIT_BINARY
|
|
]
|
|
));*/
|
|
|
|
const externalProc = pty.spawn(cmd, args, {
|
|
cols : this.client.term.termWidth,
|
|
rows : this.client.term.termHeight,
|
|
// :TODO: cwd
|
|
// :TODO: anything else??
|
|
//env : self.exeInfo.env,
|
|
});
|
|
|
|
this.client.term.output.pipe(externalProc);
|
|
|
|
/*this.client.term.output.on('data', data => {
|
|
// let tmp = data.toString('binary').replace(/\xff\xff/g, '\xff');
|
|
// proc.write(new Buffer(tmp, 'binary'));
|
|
proc.write(data);
|
|
});
|
|
*/
|
|
externalProc.on('data', data => {
|
|
// needed for things like sz/rz
|
|
if(external.escapeTelnet) {
|
|
const tmp = data.toString('binary').replace(/\xff/g, '\xff\xff');
|
|
this.client.term.rawWrite(new Buffer(tmp, 'binary'));
|
|
} else {
|
|
this.client.term.rawWrite(data);
|
|
}
|
|
});
|
|
|
|
externalProc.once('close', () => {
|
|
return this.restorePipeAfterExternalProc(externalProc);
|
|
});
|
|
|
|
externalProc.once('exit', exitCode => {
|
|
this.restorePipeAfterExternalProc(externalProc);
|
|
externalProc.removeAllListeners();
|
|
|
|
return cb(null);
|
|
});
|
|
}
|
|
|
|
initSequence() {
|
|
const self = this;
|
|
|
|
async.series(
|
|
[
|
|
function validateConfig(callback) {
|
|
// :TODO:
|
|
return callback(null);
|
|
},
|
|
function transferFiles(callback) {
|
|
self.sendQueue = [ '/home/nuskooler/Downloads/fdoor100.zip' ]; // :TODO: testing of course
|
|
return self.sendFiles(callback);
|
|
}
|
|
]
|
|
);
|
|
}
|
|
};
|