Server modules location in config. Control module included
[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 if (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 }
75
76
77
78
79 // Holder for all the connected clients
80 global.clients = {
81 clients: Object.create(null),
82 addresses: Object.create(null),
83
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 },
91
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 },
101
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 };
110
111
112
113
114 /*
115 * Web listeners
116 */
117
118
119 // Start up a weblistener for each found in the config
120 _.each(global.config.servers, function (server) {
121 var wl = new WebListener(server, global.config.transports);
122
123 wl.on('connection', function (client) {
124 clients.add(client);
125 });
126
127 wl.on('destroy', function (client) {
128 clients.remove(client);
129 });
130
131 wl.on('listening', webListenerRunning);
132 });
133
134 // Once all the listeners are listening, set the processes UID/GID
135 var num_listening = 0;
136 function webListenerRunning() {
137 num_listening++;
138 if (num_listening === global.config.servers.length) {
139 setProcessUid();
140 }
141 }
142
143
144
145
146 /*
147 * Process settings
148 */
149
150 // Set process title
151 process.title = 'kiwiirc';
152
153 // Change UID/GID
154 function 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 }
161 }
162
163
164 // Make sure Kiwi doesn't simply quit on an exception
165 process.on('uncaughtException', function (e) {
166 console.log('[Uncaught exception] ' + e);
167 });
168
169
170 process.on('SIGUSR1', function() {
171 if (config.loadConfig()) {
172 console.log('New config file loaded');
173 } else {
174 console.log("No new config file was loaded");
175 }
176 });
177
178
179
180
181 /*
182 * Listen for runtime commands
183 */
184
185 process.stdin.resume();
186 process.stdin.on('data', function (buffered) {
187 var data = buffered.toString().trim();
188
189 switch (data) {
190 case 'stats':
191 console.log('Connected clients: ' + _.size(global.clients.clients).toString());
192 console.log('Num. remote hosts: ' + _.size(global.clients.addresses).toString());
193 break;
194
195 case 'reconfig':
196 if (config.loadConfig()) {
197 console.log('New config file loaded');
198 } else {
199 console.log("No new config file was loaded");
200 }
201
202 break;
203
204
205 case 'rehash':
206 (function () {
207 rehash.rehashAll();
208 console.log('Rehashed');
209 })();
210
211 break;
212
213 default:
214 console.log('Unrecognised command: ' + data);
215 }
216 });