Merge branch 'development'
[KiwiIRC.git] / server / kiwi.js
1 var fs = require('fs'),
2 _ = require('underscore'),
3 WebListener = require('./weblistener.js'),
4 config = require('./configuration.js'),
5 rehash = require('./rehash.js');
6
7
8
9 process.chdir(__dirname + '/../');
10 config.loadConfig();
11
12
13 // If we're not running in the forground and we have a log file.. switch
14 // console.log to output to a file
15 if (process.argv.indexOf('-f') === -1 && global.config.log) {
16 (function () {
17 var log_file_name = global.config.log;
18
19 if (log_file_name[0] !== '/') {
20 log_file_name = __dirname + '/../' + log_file_name;
21 }
22
23
24
25 console.log = function() {
26 var logfile = fs.openSync(log_file_name, 'a'),
27 out;
28
29 out = Array.prototype.join.apply(arguments, [' ']);
30
31 // Make sure we out somthing to log and we have an open file
32 if (!out || !logfile) return;
33
34 out += '\n';
35 fs.writeSync(logfile, out, null);
36
37 fs.closeSync(logfile);
38 };
39 })();
40 }
41
42
43
44 // Make sure we have a valid config file and at least 1 server
45 if (!global.config || Object.keys(global.config).length === 0) {
46 console.log('Couldn\'t find a valid config.js file (Did you copy the config.example.js file yet?)');
47 process.exit(1);
48 }
49
50 if ((!global.config.servers) || (global.config.servers.length < 1)) {
51 console.log('No servers defined in config file');
52 process.exit(2);
53 }
54
55
56
57
58
59 // Holder for all the connected clients
60 global.clients = {
61 clients: Object.create(null),
62 addresses: Object.create(null),
63
64 add: function (client) {
65 this.clients[client.hash] = client;
66 if (typeof this.addresses[client.real_address] === 'undefined') {
67 this.addresses[client.real_address] = Object.create(null);
68 }
69 this.addresses[client.real_address][client.hash] = client;
70 },
71
72 remove: function (client) {
73 if (typeof this.clients[client.hash] !== 'undefined') {
74 delete this.clients[client.hash];
75 delete this.addresses[client.real_address][client.hash];
76 if (Object.keys(this.addresses[client.real_address]).length < 1) {
77 delete this.addresses[client.real_address];
78 }
79 }
80 },
81
82 numOnAddress: function (addr) {
83 if (typeof this.addresses[addr] !== 'undefined') {
84 return Object.keys(this.addresses[addr]).length;
85 } else {
86 return 0;
87 }
88 }
89 };
90
91
92
93
94 /*
95 * Web listeners
96 */
97
98
99 // Start up a weblistener for each found in the config
100 _.each(global.config.servers, function (server) {
101 var wl = new WebListener(server, global.config.transports);
102
103 wl.on('connection', function (client) {
104 clients.add(client);
105 });
106
107 wl.on('destroy', function (client) {
108 clients.remove(client);
109 });
110
111 wl.on('listening', webListenerRunning);
112 });
113
114 // Once all the listeners are listening, set the processes UID/GID
115 var num_listening = 0;
116 function webListenerRunning() {
117 num_listening++;
118 if (num_listening === global.config.servers.length) {
119 setProcessUid();
120 }
121 }
122
123
124
125
126 /*
127 * Process settings
128 */
129
130 // Set process title
131 process.title = 'kiwiirc';
132
133 // Change UID/GID
134 function setProcessUid() {
135 if ((global.config.group) && (global.config.group !== '')) {
136 process.setgid(global.config.group);
137 }
138 if ((global.config.user) && (global.config.user !== '')) {
139 process.setuid(global.config.user);
140 }
141 }
142
143
144 // Make sure Kiwi doesn't simply quit on an exception
145 process.on('uncaughtException', function (e) {
146 console.log('[Uncaught exception] ' + e);
147 });
148
149
150 process.on('SIGUSR1', function() {
151 if (config.loadConfig()) {
152 console.log('New config file loaded');
153 } else {
154 console.log("No new config file was loaded");
155 }
156 });
157
158
159
160
161 /*
162 * Listen for runtime commands
163 */
164
165 process.stdin.resume();
166 process.stdin.on('data', function (buffered) {
167 var data = buffered.toString().trim();
168
169 switch (data) {
170 case 'stats':
171 console.log('Connected clients: ' + _.size(global.clients.clients).toString());
172 console.log('Num. remote hosts: ' + _.size(global.clients.addresses).toString());
173 break;
174
175 case 'reconfig':
176 if (config.loadConfig()) {
177 console.log('New config file loaded');
178 } else {
179 console.log("No new config file was loaded");
180 }
181
182 break;
183
184
185 case 'rehash':
186 (function () {
187 rehash.rehashAll();
188 console.log('Rehashed');
189 })();
190
191 break;
192
193 default:
194 console.log('Unrecognised command: ' + data);
195 }
196 });