BSD and expact license modified
[KiwiIRC.git] / server / controlinterface.js
CommitLineData
4eba7612
D
1var _ = require('lodash'),
2 rehash = require('./rehash.js'),
3 config = require('../server/configuration.js'),
4 kiwiModules = require('../server/modules');
5
6
7
8var ControlInterface = module.exports = function(stream_in, stream_out, opts) {
9 stream_out = stream_out || stream_in;
10 this.stream_out = stream_out;
11 this.stream_in = stream_in;
12
13 opts = opts || {};
14 this.prompt = (typeof opts.prompt === 'string') ?
15 opts.prompt :
16 'Kiwi > ';
17
18 this._custom_commands = {};
19
20 this._onData = this.onData.bind(this);
21 stream_in.on('data', this._onData);
22
23 this.displayPrompt();
24};
25
26
27
28ControlInterface.prototype.dispose = function() {
29 this.stream_in.removeListener('data', this._onData);
30 this.stream_in = null;
31 this.stream_out = null;
32};
33
34
35
36ControlInterface.prototype.write = function(data, append) {
37 if (typeof append === 'undefined') append = '\n';
38 try {
39 this.stream_out.write(data + append);
40 } catch(err){}
41};
42
43
44
45ControlInterface.prototype.displayPrompt = function(prompt) {
46 prompt = prompt || this.prompt;
47 this.write(prompt, '');
48};
49
50
51
52ControlInterface.prototype.onData = function(buffered) {
53 var data = buffered.toString().trim(),
54 data_parts = data.split(' '),
55 cmd = data_parts[0] || null;
56
57 if (typeof this._custom_commands[cmd] === 'function') {
58 this._custom_commands[cmd].call(this, data_parts.slice(1), data);
59
60 } else if (typeof commands[cmd] === 'function') {
61 commands[cmd].call(this, data_parts.slice(1), data);
62
63 } else {
64 this.write('Unrecognised command: ' + cmd);
65 }
66
67 this.displayPrompt();
68};
69
70
71
72ControlInterface.prototype.addCommand = function(command, fn) {
73 this._custom_commands[command] = fn;
74};
75
76
77
78var commands = {};
895d2f62
D
79commands.help = function(args, raw) {
80 var help = 'Available commands:\n';
81 help += 'help\n';
82 help += ' This help menu\n';
b5852db6
D
83 help += 'exit\n';
84 help += ' Close and exit this Kiwi admin console\n';
895d2f62
D
85 help += 'reconfig\n';
86 help += ' Reload the config.js file\n';
87 help += 'stats\n';
88 help += ' Show connection statistics\n';
89 help += 'module list\n';
90 help += ' List the loaded server modules\n';
91 help += 'module reload module_name\n';
92 help += ' Reload the module_name module\n';
93 help += 'jumpserver [force] http://kiwi-server.com\n';
94 help += ' Tell all connected clients to reconnect to a different kiwi server. If \'force\' is given, they will be forced to reconnect in 5 minutes. \n';
95
96 this.write(help);
97};
98
99
4eba7612
D
100commands.stats = function(args, raw) {
101 this.write('Connected clients: ' + _.size(global.clients.clients).toString());
102 this.write('Num. remote hosts: ' + _.size(global.clients.addresses).toString());
103};
104
105
106commands.reconfig = function(args, raw) {
107 if (config.loadConfig()) {
40966766 108 this.write('New config file loaded');
4eba7612 109 } else {
40966766 110 this.write("No new config file was loaded");
4eba7612
D
111 }
112};
113
114
115commands.rehash = function(args, raw) {
116 rehash.rehashAll();
40966766 117 this.write('Rehashed');
4eba7612
D
118};
119
120
121commands.jumpserver = function(args, raw) {
40966766
D
122 var that = this,
123 num_clients = _.size(global.clients.clients),
4eba7612
D
124 packet = {}, args_idx;
125
126 if (num_clients === 0) {
40966766 127 this.write('No connected clients');
4eba7612
D
128 return;
129 }
130
131 // For each word in the line minus the last, add it to the packet
132 for(args_idx=0; args_idx<args.length-1; args_idx++){
133 packet[args[args_idx]] = true;
134 }
135
136 packet.kiwi_server = args[args_idx];
137
7b8d3350
D
138 if (!packet.kiwi_server) {
139 this.write('No Kiwi server specified');
140 return;
141 }
142
40966766 143 this.write('Broadcasting jumpserver to ' + num_clients.toString() + ' clients..');
4eba7612 144 global.clients.broadcastKiwiCommand('jumpserver', packet, function() {
40966766 145 that.write('Broadcast complete.');
4eba7612
D
146 });
147};
148
149
150commands.module = function(args, raw) {
151 switch(args[0]) {
152 case 'reload':
153 if (!args[1]) {
154 this.write('A module name must be specified');
155 return;
156 }
157
158 if (!kiwiModules.unload(args[1])) {
159 this.write('Module ' + (args[1] || '') + ' is not loaded');
160 return;
161 }
162
163 if (!kiwiModules.load(args[1])) {
164 this.write('Error loading module ' + (args[1] || ''));
165 }
166 this.write('Module ' + args[1] + ' reloaded');
167
168 break;
169
2aab8fbb
D
170 case 'load':
171 if (!args[1]) {
172 this.write('A module name must be specified');
173 return;
174 }
175
176 if (!kiwiModules.load(args[1])) {
177 this.write('Error loading module ' + (args[1] || ''));
178 }
179 this.write('Module ' + args[1] + ' loaded');
180
181 break;
182
183 case 'unload':
184 if (!args[1]) {
185 this.write('A module name must be specified');
186 return;
187 }
188
189 if (!kiwiModules.unload(args[1])) {
190 this.write('Module ' + (args[1] || '') + ' is not loaded');
191 return;
192 }
193
194 this.write('Module ' + args[1] + ' unloaded');
195
196 break;
197
4eba7612
D
198 case 'list':
199 case 'ls':
200 default:
201 var module_names = [];
202 kiwiModules.getRegisteredModules().forEach(function(module) {
203 module_names.push(module.module_name);
204 });
205 this.write('Loaded modules: ' + module_names.join(', '));
206 }
207};
208
209
210commands.hello = function(args, raw) {
211 this.write('Hello, beautiful :)');
212};