Stop notices appearing twice in server panel
[KiwiIRC.git] / server / kiwi.js
CommitLineData
a8bf3ea4 1var fs = require('fs'),
f9ff7686 2 _ = require('lodash'),
1360a454 3 WebListener = require('./weblistener.js'),
1286229a 4 config = require('./configuration.js'),
1920a38e 5 rehash = require('./rehash.js'),
adefb6bd
D
6 modules = require('./modules.js'),
7 Identd = require('./identd.js');
fd779420 8
186531ed
D
9
10
11dbb00f
D
11process.chdir(__dirname + '/../');
12config.loadConfig();
13
14
15// If we're not running in the forground and we have a log file.. switch
16// console.log to output to a file
38ef7086 17if (process.argv.indexOf('-f') === -1 && global.config && global.config.log) {
11dbb00f 18 (function () {
b737610b 19 var log_file_name = global.config.log;
11dbb00f
D
20
21 if (log_file_name[0] !== '/') {
22 log_file_name = __dirname + '/../' + log_file_name;
23 }
24
25
26
27 console.log = function() {
28 var logfile = fs.openSync(log_file_name, 'a'),
29 out;
30
31 out = Array.prototype.join.apply(arguments, [' ']);
32
33 // Make sure we out somthing to log and we have an open file
34 if (!out || !logfile) return;
35
36 out += '\n';
37 fs.writeSync(logfile, out, null);
38
39 fs.closeSync(logfile);
40 };
41 })();
42}
4a30a583 43
ab15f618 44
ab15f618 45
186531ed 46// Make sure we have a valid config file and at least 1 server
1f49a029
D
47if (!global.config || Object.keys(global.config).length === 0) {
48 console.log('Couldn\'t find a valid config.js file (Did you copy the config.example.js file yet?)');
a8bf3ea4 49 process.exit(1);
fd779420
D
50}
51
b737610b 52if ((!global.config.servers) || (global.config.servers.length < 1)) {
a8bf3ea4
JA
53 console.log('No servers defined in config file');
54 process.exit(2);
fd779420
D
55}
56
57
186531ed
D
58
59
1920a38e 60// Create a plugin interface
ae64bf07 61global.modules = new modules.Publisher();
1920a38e 62
874f28a5 63// Register as the active interface
ae64bf07 64modules.registerPublisher(global.modules);
1920a38e 65
991091b7 66// Load any modules in the config
d8002ae0
D
67if (global.config.module_dir) {
68 (global.config.modules || []).forEach(function (module_name) {
69 if (modules.load(global.config.module_dir + module_name + '.js')) {
70 console.log('Module ' + module_name + ' loaded successfuly');
71 } else {
72 console.log('Module ' + module_name + ' failed to load');
73 }
74 });
75}
1920a38e
D
76
77
78
186531ed 79
186531ed 80// Holder for all the connected clients
26322e8f
D
81global.clients = {
82 clients: Object.create(null),
c36ed4eb 83 addresses: Object.create(null),
26322e8f 84
c36ed4eb
JA
85 add: function (client) {
86 this.clients[client.hash] = client;
87 if (typeof this.addresses[client.real_address] === 'undefined') {
88 this.addresses[client.real_address] = Object.create(null);
89 }
90 this.addresses[client.real_address][client.hash] = client;
91 },
26322e8f 92
c36ed4eb
JA
93 remove: function (client) {
94 if (typeof this.clients[client.hash] !== 'undefined') {
95 delete this.clients[client.hash];
96 delete this.addresses[client.real_address][client.hash];
97 if (Object.keys(this.addresses[client.real_address]).length < 1) {
98 delete this.addresses[client.real_address];
99 }
100 }
101 },
26322e8f 102
c36ed4eb
JA
103 numOnAddress: function (addr) {
104 if (typeof this.addresses[addr] !== 'undefined') {
105 return Object.keys(this.addresses[addr]).length;
106 } else {
107 return 0;
108 }
109 }
110};
186531ed 111
8838bdd6
JA
112global.servers = {
113 servers: Object.create(null),
114
115 addConnection: function (connection) {
116 var host = connection.irc_host.hostname;
117 if (!this.servers[host]) {
118 this.servers[host] = [];
119 }
120 this.servers[host].push(connection);
121 },
122
123 removeConnection: function (connection) {
124 var host = connection.irc_host.hostname
125 if (this.servers[host]) {
126 this.servers[host] = _.without(this.servers[host], connection);
127 if (this.servers[host].length === 0) {
128 delete this.servers[host];
129 }
130 }
131 },
132
133 numOnHost: function (host) {
134 if (this.servers[host]) {
135 return this.servers[host].length;
136 } else {
137 return 0;
138 }
139 }
140};
141
26322e8f
D
142
143
144
adefb6bd
D
145/*
146 * Identd server
147 */
148if (global.config.identd && global.config.identd.enabled) {
149 new Identd({
150 bind_addr: global.config.identd.address,
151 bind_port: global.config.identd.port
152 }).start();
153}
154
155
156
157
26322e8f
D
158/*
159 * Web listeners
160 */
161
162
186531ed 163// Start up a weblistener for each found in the config
b737610b
JA
164_.each(global.config.servers, function (server) {
165 var wl = new WebListener(server, global.config.transports);
170a3d85 166
a8bf3ea4 167 wl.on('connection', function (client) {
c36ed4eb 168 clients.add(client);
a8bf3ea4 169 });
26322e8f 170
57566ca2 171 wl.on('client_dispose', function (client) {
c36ed4eb 172 clients.remove(client);
a8bf3ea4 173 });
e380bc9e 174
d558508c
JA
175 wl.on('listening', function () {
176 console.log('Listening on %s:%s %s SSL', server.address, server.port, (server.ssl ? 'with' : 'without'));
177 webListenerRunning();
178 });
179
180 wl.on('error', function (err) {
181 console.log('Error listening on %s:%s: %s', server.address, server.port, err.code);
182 // TODO: This should probably be refactored. ^JA
183 webListenerRunning();
184 });
a8bf3ea4 185});
68ad40c6 186
e380bc9e
D
187// Once all the listeners are listening, set the processes UID/GID
188var num_listening = 0;
189function webListenerRunning() {
190 num_listening++;
191 if (num_listening === global.config.servers.length) {
192 setProcessUid();
193 }
194}
b0ad9f0a 195
f52d8543 196
186531ed
D
197
198
199/*
200 * Process settings
201 */
202
203// Set process title
204process.title = 'kiwiirc';
205
206// Change UID/GID
e380bc9e
D
207function setProcessUid() {
208 if ((global.config.group) && (global.config.group !== '')) {
209 process.setgid(global.config.group);
210 }
211 if ((global.config.user) && (global.config.user !== '')) {
212 process.setuid(global.config.user);
213 }
fd779420 214}
709031df 215
186531ed 216
0bb21ab3
D
217// Make sure Kiwi doesn't simply quit on an exception
218process.on('uncaughtException', function (e) {
219 console.log('[Uncaught exception] ' + e);
caff44fe 220 console.log(e.stack);
0bb21ab3
D
221});
222
223
88f14637
D
224process.on('SIGUSR1', function() {
225 if (config.loadConfig()) {
226 console.log('New config file loaded');
227 } else {
228 console.log("No new config file was loaded");
229 }
230});
231
232
233
186531ed
D
234
235/*
236 * Listen for runtime commands
237 */
238
87a6abbe 239process.stdin.resume();
186531ed
D
240process.stdin.on('data', function (buffered) {
241 var data = buffered.toString().trim();
242
243 switch (data) {
244 case 'stats':
170a3d85
D
245 console.log('Connected clients: ' + _.size(global.clients.clients).toString());
246 console.log('Num. remote hosts: ' + _.size(global.clients.addresses).toString());
186531ed
D
247 break;
248
ab15f618 249 case 'reconfig':
88f14637
D
250 if (config.loadConfig()) {
251 console.log('New config file loaded');
252 } else {
253 console.log("No new config file was loaded");
254 }
ab15f618
D
255
256 break;
257
1286229a
D
258
259 case 'rehash':
260 (function () {
261 rehash.rehashAll();
262 console.log('Rehashed');
263 })();
264
265 break;
266
186531ed
D
267 default:
268 console.log('Unrecognised command: ' + data);
269 }
a8bf3ea4 270});