SOCKS proxy conf and integration
[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'),
991091b7 6 modules = require('./modules.js');
fd779420 7
186531ed
D
8
9
11dbb00f
D
10process.chdir(__dirname + '/../');
11config.loadConfig();
12
13
14// If we're not running in the forground and we have a log file.. switch
15// console.log to output to a file
b737610b 16if (process.argv.indexOf('-f') === -1 && global.config.log) {
11dbb00f 17 (function () {
b737610b 18 var log_file_name = global.config.log;
11dbb00f
D
19
20 if (log_file_name[0] !== '/') {
21 log_file_name = __dirname + '/../' + log_file_name;
22 }
23
24
25
26 console.log = function() {
27 var logfile = fs.openSync(log_file_name, 'a'),
28 out;
29
30 out = Array.prototype.join.apply(arguments, [' ']);
31
32 // Make sure we out somthing to log and we have an open file
33 if (!out || !logfile) return;
34
35 out += '\n';
36 fs.writeSync(logfile, out, null);
37
38 fs.closeSync(logfile);
39 };
40 })();
41}
4a30a583 42
ab15f618 43
ab15f618 44
186531ed 45// Make sure we have a valid config file and at least 1 server
1f49a029
D
46if (!global.config || Object.keys(global.config).length === 0) {
47 console.log('Couldn\'t find a valid config.js file (Did you copy the config.example.js file yet?)');
a8bf3ea4 48 process.exit(1);
fd779420
D
49}
50
b737610b 51if ((!global.config.servers) || (global.config.servers.length < 1)) {
a8bf3ea4
JA
52 console.log('No servers defined in config file');
53 process.exit(2);
fd779420
D
54}
55
56
186531ed
D
57
58
1920a38e 59// Create a plugin interface
ae64bf07 60global.modules = new modules.Publisher();
1920a38e 61
874f28a5 62// Register as the active interface
ae64bf07 63modules.registerPublisher(global.modules);
1920a38e 64
991091b7 65// Load any modules in the config
d8002ae0
D
66if (global.config.module_dir) {
67 (global.config.modules || []).forEach(function (module_name) {
68 if (modules.load(global.config.module_dir + module_name + '.js')) {
69 console.log('Module ' + module_name + ' loaded successfuly');
70 } else {
71 console.log('Module ' + module_name + ' failed to load');
72 }
73 });
74}
1920a38e
D
75
76
77
186531ed 78
186531ed 79// Holder for all the connected clients
26322e8f
D
80global.clients = {
81 clients: Object.create(null),
c36ed4eb 82 addresses: Object.create(null),
26322e8f 83
c36ed4eb
JA
84 add: function (client) {
85 this.clients[client.hash] = client;
86 if (typeof this.addresses[client.real_address] === 'undefined') {
87 this.addresses[client.real_address] = Object.create(null);
88 }
89 this.addresses[client.real_address][client.hash] = client;
90 },
26322e8f 91
c36ed4eb
JA
92 remove: function (client) {
93 if (typeof this.clients[client.hash] !== 'undefined') {
94 delete this.clients[client.hash];
95 delete this.addresses[client.real_address][client.hash];
96 if (Object.keys(this.addresses[client.real_address]).length < 1) {
97 delete this.addresses[client.real_address];
98 }
99 }
100 },
26322e8f 101
c36ed4eb
JA
102 numOnAddress: function (addr) {
103 if (typeof this.addresses[addr] !== 'undefined') {
104 return Object.keys(this.addresses[addr]).length;
105 } else {
106 return 0;
107 }
108 }
109};
186531ed 110
26322e8f
D
111
112
113
114/*
115 * Web listeners
116 */
117
118
186531ed 119// Start up a weblistener for each found in the config
b737610b
JA
120_.each(global.config.servers, function (server) {
121 var wl = new WebListener(server, global.config.transports);
170a3d85 122
a8bf3ea4 123 wl.on('connection', function (client) {
c36ed4eb 124 clients.add(client);
a8bf3ea4 125 });
26322e8f 126
57566ca2 127 wl.on('client_dispose', function (client) {
c36ed4eb 128 clients.remove(client);
a8bf3ea4 129 });
e380bc9e
D
130
131 wl.on('listening', webListenerRunning);
a8bf3ea4 132});
68ad40c6 133
e380bc9e
D
134// Once all the listeners are listening, set the processes UID/GID
135var num_listening = 0;
136function webListenerRunning() {
137 num_listening++;
138 if (num_listening === global.config.servers.length) {
139 setProcessUid();
140 }
141}
b0ad9f0a 142
f52d8543 143
186531ed
D
144
145
146/*
147 * Process settings
148 */
149
150// Set process title
151process.title = 'kiwiirc';
152
153// Change UID/GID
e380bc9e
D
154function setProcessUid() {
155 if ((global.config.group) && (global.config.group !== '')) {
156 process.setgid(global.config.group);
157 }
158 if ((global.config.user) && (global.config.user !== '')) {
159 process.setuid(global.config.user);
160 }
fd779420 161}
709031df 162
186531ed 163
0bb21ab3
D
164// Make sure Kiwi doesn't simply quit on an exception
165process.on('uncaughtException', function (e) {
166 console.log('[Uncaught exception] ' + e);
caff44fe 167 console.log(e.stack);
0bb21ab3
D
168});
169
170
88f14637
D
171process.on('SIGUSR1', function() {
172 if (config.loadConfig()) {
173 console.log('New config file loaded');
174 } else {
175 console.log("No new config file was loaded");
176 }
177});
178
179
180
186531ed
D
181
182/*
183 * Listen for runtime commands
184 */
185
87a6abbe 186process.stdin.resume();
186531ed
D
187process.stdin.on('data', function (buffered) {
188 var data = buffered.toString().trim();
189
190 switch (data) {
191 case 'stats':
170a3d85
D
192 console.log('Connected clients: ' + _.size(global.clients.clients).toString());
193 console.log('Num. remote hosts: ' + _.size(global.clients.addresses).toString());
186531ed
D
194 break;
195
ab15f618 196 case 'reconfig':
88f14637
D
197 if (config.loadConfig()) {
198 console.log('New config file loaded');
199 } else {
200 console.log("No new config file was loaded");
201 }
ab15f618
D
202
203 break;
204
1286229a
D
205
206 case 'rehash':
207 (function () {
208 rehash.rehashAll();
209 console.log('Rehashed');
210 })();
211
212 break;
213
186531ed
D
214 default:
215 console.log('Unrecognised command: ' + data);
216 }
a8bf3ea4 217});