Fix typo
[KiwiIRC.git] / server_modules / control.js
1 /**
2 * Server control via TCP socket
3 *
4 * Listens on localhost:8888 by default
5 */
6
7 var net = require('net'),
8 kiwiModules = require('../server/modules'),
9 rehash = require('../server/rehash.js'),
10 config = require('../server/configuration.js'),
11 _ = require('lodash');
12
13 var control_module = new kiwiModules.Module('Control');
14
15
16 /**
17 * The socket client
18 */
19 function SocketClient (socket) {
20 this.socket = socket;
21 this.socket_closing = false;
22
23 this.remoteAddress = this.socket.remoteAddress;
24 console.log('Control connection from ' + this.socket.remoteAddress + ' opened');
25
26 this.bindEvents();
27
28 socket.write("\nHello, you are connected to the Kiwi server :)\n\n");
29 this.displayPrompt();
30 }
31
32 SocketClient.prototype.bindEvents = function() {
33 var that = this;
34
35 this.socket.on('data', function() { that.onData.apply(that, arguments); });
36 this.socket.on('close', function() { that.onClose.apply(that, arguments); });
37 };
38 SocketClient.prototype.unbindEvents = function() {
39 this.socket.removeAllListeners();
40 };
41
42
43
44 SocketClient.prototype.write = function(data, append) {
45 if (typeof append === 'undefined') append = '\n';
46 if (this.socket && !this.socket_closing)
47 this.socket.write(data + append);
48 };
49 SocketClient.prototype.displayPrompt = function(prompt) {
50 prompt = prompt || 'Kiwi > ';
51 this.write(prompt, '');
52 };
53
54
55
56 SocketClient.prototype.onData = function(data) {
57 data = data.toString().trim();
58
59
60
61 try {
62 var data_split = data.split(' ');
63
64 if (typeof socket_commands[data_split[0]] === 'function') {
65 socket_commands[data_split[0]].call(this, data_split.slice(1));
66 } else {
67 this.write('Unrecognised command: ' + data);
68 }
69
70 } catch (err) {
71 console.log('[Control error] ' + err);
72 this.write('An error occured. Check the Kiwi server log for more details');
73 }
74
75 this.displayPrompt();
76 };
77
78
79 SocketClient.prototype.onClose = function() {
80 this.unbindEvents();
81 this.socket = null;
82 console.log('Control connection from ' + this.remoteAddress + ' closed');
83 };
84
85
86
87 /**
88 * Available commands
89 * Each function is run in context of the SocketClient
90 */
91 var socket_commands = {
92 module: function(data) {
93 switch(data[0]) {
94 case 'reload':
95 if (!data[1]) {
96 this.write('A module name must be specified');
97 return;
98 }
99
100 if (!kiwiModules.unload(data[1])) {
101 this.write('Module ' + (data[1] || '') + ' is not loaded');
102 return;
103 }
104
105 if (!kiwiModules.load(data[1])) {
106 this.write('Error loading module ' + (data[1] || ''));
107 }
108 this.write('Module ' + data[1] + ' reloaded');
109
110 break;
111
112 case 'list':
113 case 'ls':
114 default:
115 var module_names = [];
116 kiwiModules.getRegisteredModules().forEach(function(module) {
117 module_names.push(module.module_name);
118 });
119 this.write('Loaded modules: ' + module_names.join(', '));
120 }
121
122 },
123
124 stats: function(data) {
125 this.write('Connected clients: ' + _.size(global.clients.clients).toString());
126 this.write('Num. remote hosts: ' + _.size(global.clients.addresses).toString());
127 },
128
129 rehash: function(data) {
130 rehash.rehashAll();
131 this.write('Rehashed');
132 },
133
134 reconfig: function(data) {
135 if (config.loadConfig()) {
136 this.write('New config file loaded');
137 } else {
138 this.write("No new config file was loaded");
139 }
140 },
141
142 quit: function(data) {
143 this.socket.destroy();
144 this.socket_closing = true;
145 },
146 exit: function(data) {
147 this.socket.destroy();
148 this.socket_closing = true;
149 }
150 };
151
152
153 /**
154 * Start the control socket server to serve connections
155 */
156 var server = net.createServer(function (socket) {
157 new SocketClient(socket);
158 });
159 server.listen(8888);
160
161 control_module.on('dispose', function() {
162 server.close();
163 });