shh
Version:
Quiet the ssh client.
267 lines (230 loc) • 7.23 kB
JavaScript
// Generated by CoffeeScript 1.6.2
var BUFFER_LENGTH, Client, Connection, END_TOKEN, EventEmitter, PRIVATE_KEY, START_TOKEN, USERNAME, fs, os, stripColors, wrapper, _ref,
__hasProp = {}.hasOwnProperty,
__extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; };
Connection = require('ssh2');
EventEmitter = require('events').EventEmitter;
fs = require('fs');
os = require('os');
BUFFER_LENGTH = 5000;
END_TOKEN = '__SHH_END_TOKEN__';
START_TOKEN = '__SHH_START_TOKEN__';
USERNAME = process.env['USER'];
PRIVATE_KEY = (_ref = process.env['SHH_PRIVATE_KEY']) != null ? _ref : process.env['HOME'] + '/.ssh/id_rsa';
stripColors = function(str) {
return str.replace(/\033\[[0-9;]*m/g, '');
};
Client = (function(_super) {
__extends(Client, _super);
function Client(options) {
var _ref1, _ref2, _ref3, _ref4, _ref5, _ref6, _ref7, _ref8, _ref9;
if (options == null) {
options = {};
}
if ((_ref1 = options.host) == null) {
options.host = 'localhost';
}
if ((_ref2 = options.port) == null) {
options.port = 22;
}
if ((_ref3 = options.username) == null) {
options.username = USERNAME;
}
if ((_ref4 = options.privateKey) == null) {
options.privateKey = PRIVATE_KEY;
}
this.options = options;
this.bufferLength = (_ref5 = options.bufferLength) != null ? _ref5 : 5000;
this.colors = (_ref6 = options.colors) != null ? _ref6 : false;
this.debug = (_ref7 = options.debug) != null ? _ref7 : false;
this.endToken = (_ref8 = options.endToken) != null ? _ref8 : '__SHH_END_TOKEN__';
this.startToken = (_ref9 = options.startToken) != null ? _ref9 : '__SHH_START_TOKEN__';
this._connection = new Connection();
this._stderr = [];
this._stdout = [];
this._callbacks = [];
this._lastFragment = null;
this._streaming = false;
}
Client.prototype.connect = function(callback) {
var _this = this;
if (callback == null) {
callback = function() {};
}
this._connection.on('connect', function() {
if (_this.debug) {
return console.log('[ssh :: connect]');
}
});
this._connection.on('ready', function() {
if (_this.debug) {
console.log('[ssh :: ready]');
}
return _this._connection.shell(function(err, _stream) {
_this._stream = _stream;
if (err != null) {
throw err;
}
_this._stream.on('end', function() {
if (this.debug) {
return console.log('[stream :: end]');
}
});
_this._stream.on('close', function() {
if (this.debug) {
return console.log('[stream :: close]');
}
});
_this._stream.on('exit', function(code, signal) {
if (this.debug) {
return console.log('[stream :: exit]', code, signal);
}
});
_this._stream.on('data', function(data, extended) {
if (data == null) {
data = '';
}
if (!_this.colors) {
data = stripColors(data.toString());
}
if (_this.debug) {
console.log('[stream :: data]', data);
}
return _this.parse(data, extended);
});
return callback(null, _this._stream);
});
});
this._connection.on('error', function(err) {
if (err != null) {
throw err;
}
});
this._connection.on('close', function(hadError) {
if (hadError) {
throw new Error('Connection closed unexpectedly');
}
});
return fs.exists(this.options.privateKey, function(exists) {
if (!exists) {
throw new Error('Private key not found');
}
return fs.readFile(_this.options.privateKey, function(err, data) {
if (err != null) {
throw err;
}
_this.options.privateKey = data;
return _this._connection.connect(_this.options);
});
});
};
Client.prototype.prependLastFragment = function(lines) {
var firstLine;
firstLine = lines.shift();
lines.unshift(this._lastFragment + firstLine);
this._lastFragment = null;
return lines;
};
Client.prototype.parse = function(data, type) {
var end, lines, start;
if (type == null) {
type = 'stdout';
}
if (typeof data === 'string') {
lines = data.split(os.EOL);
} else {
lines = data;
}
if (type === 'stderr') {
if (this._streaming) {
return this.stream(lines, 'stderr');
}
}
if (this._lastFragment) {
lines = this.prependLastFragment(lines);
}
if (!this._streaming) {
start = lines.indexOf(this.startToken);
if (start === -1) {
start = lines.indexOf(this.startToken + '\r');
}
if (start !== -1) {
this.start();
this.parse(lines.slice(start + 1));
} else {
this._lastFragment = lines.pop();
}
} else {
end = lines.indexOf(this.endToken);
if (end === -1) {
end = lines.indexOf(this.endToken + '\r');
}
if (end !== -1) {
this.stream(lines.slice(0, end));
this.end();
this.parse(lines.slice(end + 1));
} else {
this._lastFragment = lines.pop();
this.stream(lines);
}
}
};
Client.prototype.stream = function(lines, type) {
var buffer, line, _i, _len;
if (type == null) {
type = 'stdout';
}
buffer = this['_' + type];
for (_i = 0, _len = lines.length; _i < _len; _i++) {
line = lines[_i];
if (!this.colors) {
line = stripColors(line);
buffer.push(line);
if (buffer.length === this.bufferLength) {
buffer.shift();
}
this.emit(type, line);
}
}
};
Client.prototype.start = function() {
this.emit('startcommand');
return this._streaming = true;
};
Client.prototype.end = function() {
var callback, stderr, stdout;
stderr = this._stderr.join(os.EOL);
stdout = this._stdout.join(os.EOL);
this.emit('endcommand', stderr, stdout);
this._stderr = [];
this._stdout = [];
this._streaming = false;
callback = this._callbacks.shift();
if (typeof callback === 'function') {
if (!stderr.trim()) {
stderr = null;
}
return callback(stderr, stdout);
}
};
Client.prototype.close = function() {
return this._connection.end();
};
Client.prototype.exec = function(cmd, callback) {
this._callbacks.push(callback);
return this._stream.write("echo; echo " + this.startToken + "; " + cmd + "; echo " + this.endToken + "\r\n");
};
return Client;
})(EventEmitter);
module.exports = wrapper = function(options) {
return new Client(options);
};
wrapper.Client = Client;
wrapper.USERNAME = USERNAME;
wrapper.PRIVATE_KEY = PRIVATE_KEY;
wrapper.BUFFER_LENGTH = BUFFER_LENGTH;
wrapper.END_TOKEN = END_TOKEN;
wrapper.START_TOKEN = START_TOKEN;
/*
//@ sourceMappingURL=index.map
*/