From 4eba7612bc06f3ebd6745ec08014235c2f13d8e9 Mon Sep 17 00:00:00 2001 From: Darren Date: Sat, 17 Aug 2013 19:55:28 +0100 Subject: [PATCH] Standardised server control interface --- server/controlinterface.js | 157 +++++++++++++++++++++++++++++++++++++ server/kiwi.js | 64 +-------------- server_modules/control.js | 111 +++++--------------------- 3 files changed, 178 insertions(+), 154 deletions(-) create mode 100644 server/controlinterface.js diff --git a/server/controlinterface.js b/server/controlinterface.js new file mode 100644 index 0000000..2d0a88a --- /dev/null +++ b/server/controlinterface.js @@ -0,0 +1,157 @@ +var _ = require('lodash'), + rehash = require('./rehash.js'), + config = require('../server/configuration.js'), + kiwiModules = require('../server/modules'); + + + +var ControlInterface = module.exports = function(stream_in, stream_out, opts) { + stream_out = stream_out || stream_in; + this.stream_out = stream_out; + this.stream_in = stream_in; + + opts = opts || {}; + this.prompt = (typeof opts.prompt === 'string') ? + opts.prompt : + 'Kiwi > '; + + this._custom_commands = {}; + + this._onData = this.onData.bind(this); + stream_in.on('data', this._onData); + + this.displayPrompt(); +}; + + + +ControlInterface.prototype.dispose = function() { + this.stream_in.removeListener('data', this._onData); + this.stream_in = null; + this.stream_out = null; +}; + + + +ControlInterface.prototype.write = function(data, append) { + if (typeof append === 'undefined') append = '\n'; + try { + this.stream_out.write(data + append); + } catch(err){} +}; + + + +ControlInterface.prototype.displayPrompt = function(prompt) { + prompt = prompt || this.prompt; + this.write(prompt, ''); +}; + + + +ControlInterface.prototype.onData = function(buffered) { + var data = buffered.toString().trim(), + data_parts = data.split(' '), + cmd = data_parts[0] || null; + + if (typeof this._custom_commands[cmd] === 'function') { + this._custom_commands[cmd].call(this, data_parts.slice(1), data); + + } else if (typeof commands[cmd] === 'function') { + commands[cmd].call(this, data_parts.slice(1), data); + + } else { + this.write('Unrecognised command: ' + cmd); + } + + this.displayPrompt(); +}; + + + +ControlInterface.prototype.addCommand = function(command, fn) { + this._custom_commands[command] = fn; +}; + + + +var commands = {}; +commands.stats = function(args, raw) { + this.write('Connected clients: ' + _.size(global.clients.clients).toString()); + this.write('Num. remote hosts: ' + _.size(global.clients.addresses).toString()); +}; + + +commands.reconfig = function(args, raw) { + if (config.loadConfig()) { + console.log('New config file loaded'); + } else { + console.log("No new config file was loaded"); + } +}; + + +commands.rehash = function(args, raw) { + rehash.rehashAll(); + console.log('Rehashed'); +}; + + +commands.jumpserver = function(args, raw) { + var num_clients = _.size(global.clients.clients), + packet = {}, args_idx; + + if (num_clients === 0) { + console.log('No connected clients'); + return; + } + + // For each word in the line minus the last, add it to the packet + for(args_idx=0; args_idx '; - this.write(prompt, ''); -}; - - - -SocketClient.prototype.onData = function(data) { - data = data.toString().trim(); - - - try { - var data_split = data.split(' '); - if (typeof socket_commands[data_split[0]] === 'function') { - socket_commands[data_split[0]].call(this, data_split.slice(1)); - } else { - this.write('Unrecognised command: ' + data); - } - - } catch (err) { - console.log('[Control error] ' + err); - this.write('An error occured. Check the Kiwi server log for more details'); - } - - this.displayPrompt(); +SocketClient.prototype.unbindEvents = function() { + this.socket.removeAllListeners(); }; SocketClient.prototype.onClose = function() { + this.control_interface.dispose(); + this.control_interface = null; + this.unbindEvents(); this.socket = null; + console.log('Control connection from ' + this.remoteAddress + ' closed'); }; @@ -89,56 +64,6 @@ SocketClient.prototype.onClose = function() { * Each function is run in context of the SocketClient */ var socket_commands = { - module: function(data) { - switch(data[0]) { - case 'reload': - if (!data[1]) { - this.write('A module name must be specified'); - return; - } - - if (!kiwiModules.unload(data[1])) { - this.write('Module ' + (data[1] || '') + ' is not loaded'); - return; - } - - if (!kiwiModules.load(data[1])) { - this.write('Error loading module ' + (data[1] || '')); - } - this.write('Module ' + data[1] + ' reloaded'); - - break; - - case 'list': - case 'ls': - default: - var module_names = []; - kiwiModules.getRegisteredModules().forEach(function(module) { - module_names.push(module.module_name); - }); - this.write('Loaded modules: ' + module_names.join(', ')); - } - - }, - - stats: function(data) { - this.write('Connected clients: ' + _.size(global.clients.clients).toString()); - this.write('Num. remote hosts: ' + _.size(global.clients.addresses).toString()); - }, - - rehash: function(data) { - rehash.rehashAll(); - this.write('Rehashed'); - }, - - reconfig: function(data) { - if (config.loadConfig()) { - this.write('New config file loaded'); - } else { - this.write("No new config file was loaded"); - } - }, - quit: function(data) { this.socket.destroy(); this.socket_closing = true; -- 2.25.1