Commit | Line | Data |
---|---|---|
69b7b1e6 D |
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 | node_static = require('node-static'), | |
8 | fs = require('fs'), | |
9 | url = require('url'), | |
10 | dns = require('dns'), | |
11 | crypto = require('crypto'), | |
12 | events = require("events"), | |
13 | util = require('util'), | |
14 | ws = require('socket.io'), | |
15 | jsp = require("uglify-js").parser, | |
16 | pro = require("uglify-js").uglify, | |
17 | _ = require('./lib/underscore.min.js'), | |
18 | starttls = require('./lib/starttls.js'), | |
19 | app = require(__dirname + '/app.js'); | |
fd779420 D |
20 | |
21 | ||
69b7b1e6 D |
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 | */ | |
fd779420 | 38 | var config_filename = 'config.json', |
69b7b1e6 D |
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; | |
4a30a583 | 74 | } |
69b7b1e6 D |
75 | } |
76 | if (Object.keys(this.config).length === 0) { | |
77 | if (!found_config) { | |
78 | this.log('Couldn\'t find a config file!'); | |
4926321f | 79 | } |
69b7b1e6 | 80 | return false; |
fd779420 | 81 | } |
69b7b1e6 D |
82 | return [nconf, cconf]; |
83 | }; | |
84 | ||
85 | ||
86 | // Reloads the config during runtime | |
87 | this.rehash = function () { | |
88 | return app.rehash(); | |
4926321f | 89 | } |
4a30a583 | 90 | |
69b7b1e6 D |
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, node_static:node_static, fs:fs, url:url, dns:dns, crypto:crypto, events:events, util:util, ws:ws, jsp:jsp, pro:pro, _:_, starttls:starttls}; | |
101 | app.init(objs); | |
102 | app.rebindIRCCommands(); | |
103 | ||
104 | return true; | |
fd779420 D |
105 | } |
106 | ||
69b7b1e6 D |
107 | |
108 | ||
109 | ||
110 | ||
111 | ||
112 | /* | |
113 | * Before we continue we need the config loaded | |
114 | */ | |
115 | if (!this.loadConfig()) { | |
116 | process.exit(0); | |
117 | } | |
118 | ||
119 | ||
120 | ||
121 | ||
122 | ||
123 | ||
124 | ||
125 | /* | |
126 | * HTTP file serving | |
127 | */ | |
128 | if (this.config.handle_http) { | |
129 | this.fileServer = new (require('node-static').Server)(__dirname + this.config.public_http); | |
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.websocketKiwiMessage = function (msg, callback) { | |
160 | return app.websocketKiwiMessage(this, msg, callback); | |
161 | } | |
162 | this.websocketIRCConnect = function (nick, host, port, ssl, callback) { | |
163 | return app.websocketIRCConnect(this, nick, host, port, ssl, callback); | |
fd779420 D |
164 | } |
165 | ||
166 | ||
68ad40c6 | 167 | |
b0ad9f0a | 168 | |
69b7b1e6 D |
169 | /* |
170 | * IRC handling | |
171 | */ | |
172 | this.parseIRCMessage = function (websocket, ircSocket, data) { | |
173 | return app.parseIRCMessage(websocket, ircSocket, data); | |
174 | } | |
175 | this.ircSocketDataHandler = function (data, websocket, ircSocket) { | |
176 | return app.ircSocketDataHandler(data, websocket, ircSocket); | |
177 | } | |
178 | this.IRCConnection = function (websocket, nick, host, port, ssl, password, callback) { | |
179 | return app.IRCConnection.call(this, websocket, nick, host, port, ssl, password, callback); | |
180 | } | |
181 | util.inherits(this.IRCConnection, events.EventEmitter); | |
f52d8543 | 182 | |
69b7b1e6 D |
183 | this.bindIRCCommands = function (irc_connection, websocket) { |
184 | return app.bindIRCCommands.call(this, irc_connection, websocket); | |
897abfc3 | 185 | } |
69b7b1e6 D |
186 | this.rebindIRCCommands = function () { |
187 | return app.rebindIRCCommands.call(this); | |
fd779420 | 188 | } |
709031df | 189 | |
69b7b1e6 D |
190 | |
191 | ||
192 | ||
193 | ||
194 | ||
195 | /* | |
196 | * Load up main application source | |
197 | */ | |
198 | if (!this.recode()) { | |
199 | process.exit(0); | |
200 | } | |
201 | ||
202 | ||
203 | ||
204 | // Set the process title | |
205 | app.setTitle(); | |
206 | ||
207 | ||
208 | ||
209 | /* | |
210 | * Load the modules as set in the config and print them out | |
211 | */ | |
212 | this.kiwi_mod = require('./lib/kiwi_mod.js'); | |
213 | this.kiwi_mod.loadModules(this.kiwi_root, this.config); | |
214 | this.kiwi_mod.printMods(); | |
215 | ||
216 | ||
217 | // Make sure Kiwi doesn't simply quit on an exception | |
3c892e03 D |
218 | process.on('uncaughtException', function (e) { |
219 | console.log('[Uncaught exception] ' + e); | |
220 | }); | |
69b7b1e6 D |
221 | |
222 | // Start the server up | |
223 | this.websocketListen(this.config.servers, this.httpHandler); | |
224 | ||
225 | // Now we're listening on the network, set our UID/GIDs if required | |
226 | app.changeUser(); | |
227 | ||
228 | // Listen for controll messages | |
87a6abbe | 229 | process.stdin.resume(); |
69b7b1e6 D |
230 | process.stdin.on('data', function (data) { app.manageControll(data); }); |
231 | ||
232 | ||
233 | ||
234 |