1c7520d33cae028a249d5b17ffa918476248460b
[KiwiIRC.git] / server / kiwi.js
1 var fs = require('fs'),
2 _ = require('lodash'),
3 WebListener = require('./weblistener.js'),
4 config = require('./configuration.js'),
5 rehash = require('./rehash.js'),
6 modules = require('./modules.js');
7
8
9
10 process.chdir(__dirname + '/../');
11 config.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
16 if (process.argv.indexOf('-f') === -1 && global.config.log) {
17 (function () {
18 var log_file_name = global.config.log;
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 }
42
43
44
45 // Make sure we have a valid config file and at least 1 server
46 if (!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?)');
48 process.exit(1);
49 }
50
51 if ((!global.config.servers) || (global.config.servers.length < 1)) {
52 console.log('No servers defined in config file');
53 process.exit(2);
54 }
55
56
57
58
59 // Create a plugin interface
60 global.modules = new modules.Publisher();
61
62 // Register as the active interface
63 modules.registerPublisher(global.modules);
64
65 // Load any modules in the config
66 (global.config.modules || []).forEach(function (module_name) {
67 if (modules.load('../server_modules/' + module_name + '.js')) {
68 console.log('Module ' + module_name + ' loaded successfuly');
69 } else {
70 console.log('Module ' + module_name + ' failed to load');
71 }
72 });
73
74
75
76
77
78 // Holder for all the connected clients
79 global.clients = {
80 clients: Object.create(null),
81 addresses: Object.create(null),
82
83 add: function (client) {
84 this.clients[client.hash] = client;
85 if (typeof this.addresses[client.real_address] === 'undefined') {
86 this.addresses[client.real_address] = Object.create(null);
87 }
88 this.addresses[client.real_address][client.hash] = client;
89 },
90
91 remove: function (client) {
92 if (typeof this.clients[client.hash] !== 'undefined') {
93 delete this.clients[client.hash];
94 delete this.addresses[client.real_address][client.hash];
95 if (Object.keys(this.addresses[client.real_address]).length < 1) {
96 delete this.addresses[client.real_address];
97 }
98 }
99 },
100
101 numOnAddress: function (addr) {
102 if (typeof this.addresses[addr] !== 'undefined') {
103 return Object.keys(this.addresses[addr]).length;
104 } else {
105 return 0;
106 }
107 }
108 };
109
110
111
112
113 /*
114 * Web listeners
115 */
116
117
118 // Start up a weblistener for each found in the config
119 _.each(global.config.servers, function (server) {
120 var wl = new WebListener(server, global.config.transports);
121
122 wl.on('connection', function (client) {
123 clients.add(client);
124 });
125
126 wl.on('destroy', function (client) {
127 clients.remove(client);
128 });
129
130 wl.on('listening', webListenerRunning);
131 });
132
133 // Once all the listeners are listening, set the processes UID/GID
134 var num_listening = 0;
135 function webListenerRunning() {
136 num_listening++;
137 if (num_listening === global.config.servers.length) {
138 setProcessUid();
139 }
140 }
141
142
143
144
145 /*
146 * Process settings
147 */
148
149 // Set process title
150 process.title = 'kiwiirc';
151
152 // Change UID/GID
153 function setProcessUid() {
154 if ((global.config.group) && (global.config.group !== '')) {
155 process.setgid(global.config.group);
156 }
157 if ((global.config.user) && (global.config.user !== '')) {
158 process.setuid(global.config.user);
159 }
160 }
161
162
163 // Make sure Kiwi doesn't simply quit on an exception
164 process.on('uncaughtException', function (e) {
165 console.log('[Uncaught exception] ' + e);
166 });
167
168
169 process.on('SIGUSR1', function() {
170 if (config.loadConfig()) {
171 console.log('New config file loaded');
172 } else {
173 console.log("No new config file was loaded");
174 }
175 });
176
177
178
179
180 /*
181 * Listen for runtime commands
182 */
183
184 process.stdin.resume();
185 process.stdin.on('data', function (buffered) {
186 var data = buffered.toString().trim();
187
188 switch (data) {
189 case 'stats':
190 console.log('Connected clients: ' + _.size(global.clients.clients).toString());
191 console.log('Num. remote hosts: ' + _.size(global.clients.addresses).toString());
192 break;
193
194 case 'reconfig':
195 if (config.loadConfig()) {
196 console.log('New config file loaded');
197 } else {
198 console.log("No new config file was loaded");
199 }
200
201 break;
202
203
204 case 'rehash':
205 (function () {
206 rehash.rehashAll();
207 console.log('Rehashed');
208 })();
209
210 break;
211
212 default:
213 console.log('Unrecognised command: ' + data);
214 }
215 });