Logging output refactoring
[KiwiIRC.git] / server / kiwi.js
1 /*jslint continue: true, forin: true, regexp: true, undef: false, node: true, nomen: true, plusplus: true, maxerr: 50, indent: 4 */
2 "use strict";
3 var tls = require('tls'),
4 net = require('net'),
5 http = require('http'),
6 https = require('https'),
7 fs = require('fs'),
8 url = require('url'),
9 dns = require('dns'),
10 crypto = require('crypto'),
11 ws = require('socket.io'),
12 jsp = require("uglify-js").parser,
13 pro = require("uglify-js").uglify,
14 _ = require('./lib/underscore.min.js'),
15 starttls = require('./lib/starttls.js'),
16 app = require(__dirname + '/app.js');
17
18
19
20
21
22 // Libraries may need to know kiwi.js path as __dirname
23 // only gives that librarys path. Set it here for usage later.
24 this.kiwi_root = __dirname;
25
26
27
28 // How to handle log output
29 this.log = function(str, level) {
30 level = level || 0;
31 console.log(str);
32 }
33
34
35 /*
36 * Configuration and rehashing routines
37 */
38 var config_filename = 'config.json',
39 config_dirs = ['/etc/kiwiirc/', this.kiwi_root + '/'];
40
41 this.config = {};
42 this.loadConfig = function () {
43 var i, j,
44 nconf = {},
45 cconf = {},
46 found_config = false;
47
48 for (i in config_dirs) {
49 try {
50 if (fs.lstatSync(config_dirs[i] + config_filename).isDirectory() === false) {
51 found_config = true;
52 nconf = JSON.parse(fs.readFileSync(config_dirs[i] + config_filename, 'ascii'));
53 for (j in nconf) {
54 // If this has changed from the previous config, mark it as changed
55 if (!_.isEqual(this.config[j], nconf[j])) {
56 cconf[j] = nconf[j];
57 }
58
59 this.config[j] = nconf[j];
60 }
61
62 this.log('Loaded config file ' + config_dirs[i] + config_filename);
63 break;
64 }
65 } catch (e) {
66 switch (e.code) {
67 case 'ENOENT': // No file/dir
68 break;
69 default:
70 this.log('An error occured parsing the config file ' + config_dirs[i] + config_filename + ': ' + e.message);
71 return false;
72 }
73 continue;
74 }
75 }
76 if (Object.keys(this.config).length === 0) {
77 if (!found_config) {
78 this.log('Couldn\'t find a config file!');
79 }
80 return false;
81 }
82 return [nconf, cconf];
83 };
84
85
86 // Reloads the config during runtime
87 this.rehash = function () {
88 return app.rehash();
89 }
90
91 // Reloads app.js during runtime for any recoding
92 this.recode = function () {
93 if (typeof require.cache[this.kiwi_root + '/app.js'] !== 'undefined'){
94 delete require.cache[this.kiwi_root + '/app.js'];
95 }
96
97 app = null;
98 app = require(__dirname + '/app.js');
99
100 var objs = {tls:tls, net:net, http:http, https:https, fs:fs, url:url, dns:dns, crypto:crypto, ws:ws, jsp:jsp, pro:pro, _:_, starttls:starttls};
101 app.init(objs);
102
103 return true;
104 }
105
106
107
108
109
110
111 /*
112 * Before we continue we need the config loaded
113 */
114 if (!this.loadConfig()) {
115 process.exit(0);
116 }
117
118
119
120
121
122
123
124 /*
125 * HTTP file serving
126 */
127 if (this.config.handle_http) {
128 this.fileServer = new (require('node-static').Server)(__dirname + this.config.public_http);
129 this.jade = require('jade');
130 this.cache = {alljs: '', html: []};
131 }
132 this.httpServers = [];
133 this.httpHandler = function (request, response) {
134 return app.httpHandler(request, response);
135 }
136
137
138
139
140
141
142 /*
143 * Websocket handling
144 */
145 this.connections = {};
146 this.io = [];
147 this.websocketListen = function (servers, handler) {
148 return app.websocketListen(servers, handler);
149 }
150 this.websocketConnection = function (websocket) {
151 return app.websocketConnection(websocket);
152 }
153 this.websocketDisconnect = function () {
154 return app.websocketDisconnect(this);
155 }
156 this.websocketMessage = function (msg, callback) {
157 return app.websocketMessage(this, msg, callback);
158 }
159 this.websocketIRCConnect = function (nick, host, port, ssl, callback) {
160 return app.websocketIRCConnect(this, nick, host, port, ssl, callback);
161 }
162
163
164
165
166 /*
167 * IRC handling
168 */
169 this.parseIRCMessage = function (websocket, ircSocket, data) {
170 return app.parseIRCMessage(websocket, ircSocket, data);
171 }
172 this.ircSocketDataHandler = function (data, websocket, ircSocket) {
173 return app.ircSocketDataHandler(data, websocket, ircSocket);
174 }
175
176
177
178
179
180
181
182
183
184 /*
185 * Load up main application source
186 */
187 if (!this.recode()) {
188 process.exit(0);
189 }
190
191
192
193 // Set the process title
194 app.setTitle();
195
196
197
198 /*
199 * Load the modules as set in the config and print them out
200 */
201 this.kiwi_mod = require('./lib/kiwi_mod.js');
202 this.kiwi_mod.loadModules(this.kiwi_root, this.config);
203 this.kiwi_mod.printMods();
204
205
206 // Make sure Kiwi doesn't simply quit on an exception
207 process.on('uncaughtException', function (e) {
208 this.log('[Uncaught exception] ' + e);
209 });
210
211
212 // Start the server up
213 this.websocketListen(this.config.servers, this.httpHandler);
214
215 // Now we're listening on the network, set our UID/GIDs if required
216 app.changeUser();
217
218 // Listen for controll messages
219 process.stdin.resume();
220 process.stdin.on('data', function (data) { app.manageControll(data); });
221
222
223
224