Including the node_modules folder for socket.io code.
[KiwiIRC.git] / irc_session.php
CommitLineData
54f4a22e
D
1<?php\r
2\r
3 /*\r
4 * CASE: Page requested to start a session.\r
5 * 1. Attempt connect to the server\r
6 * Fail?\r
7 * End session and send error to the client\r
8 * Connected?\r
9 * Create a listening UNIX socket and send OK to the client\r
10 *\r
11 * 2. Run the IRC client class as normal, while polling for connections\r
12 * on the listening socket. Save any messages for the web client into\r
13 * a buffer.\r
14 * This is the normal running state.\r
15 *\r
16 * 3. Upon a connection on the UNIX socket, send the oldest message from\r
17 * the buffer to the web client, FIFO style and close the connection.\r
18 */\r
19 \r
20 // If -d has been sent to start this session, start in debug mode\r
21 if(in_array('-d', $argv)){\r
22 define('DEBUG', true);\r
23 } else {\r
24 define('DEBUG', false);\r
25 }\r
26 \r
27 \r
28 require(dirname(__FILE__).'/config.php');\r
29 require(dirname(__FILE__).'/common.php');\r
30 require(dirname(__FILE__).'/class_session.php');\r
31 require(dirname(__FILE__).'/class_irc.php');\r
32 require(dirname(__FILE__).'/class_ircconnection.php');\r
33 require(dirname(__FILE__).'/ircd_profiles/hybrid.php');\r
34 \r
35 \r
36 // Make sure a session id has been specified\r
37 if(!isset($argv[1]) || empty($argv[1]))\r
38 die('no_session');\r
39 \r
40 $session_id = $argv[1];\r
41 $host_key = $argv[2]; // The remote host key in memcached\r
42 \r
43 // Process any arguments\r
44 $app_args = array();\r
45 foreach($argv as $a){\r
46 $value = substr($a, 2);\r
47 switch(substr($a, 0, 2)){\r
48 case '-h':\r
49 // Client host\r
50 $app_args['remote_host'] = $value;\r
51 break;\r
52 }\r
53 }\r
54 \r
55 \r
56 // Start the unix session, and if it fails quit here\r
57 $ipc_srv = SESSIONS::clStart($session_id);\r
58 if($ipc_srv === false) die("fail '$session_id' '$host_key'");\r
59 \r
60 // Debug mode runs in terminal to see output\r
61 if(!DEBUG){\r
62 // See if we can fork our process..\r
63 $pid = pcntl_fork();\r
64 if($pid === -1){\r
65 die('Forking error');\r
66 }elseif($pid){\r
67 // Parent process\r
68 die('ok');\r
69 }else{\r
70 // Child process\r
71 fclose(STDOUT);\r
72 }\r
73 }\r
74 \r
75 //posix_setsid();\r
76\r
77 \r
78 \r
79 ############################################\r
80 ## Main process\r
81 ############################################\r
82 \r
83 $old_error_handler = set_error_handler("errorHandler");\r
84 \r
85 $bot = null; // The IRC connection\r
86 $ipc = array(); // The IPC connections to the web clients\r
87 $ipc_read = array(); // The IPC connections wanting to read the buffer\r
88 $buffer = array(); // Messages to be sent to the web client\r
89 $send_debug = false;\r
90 \r
91 deb("Starting $session_id");\r
92 \r
93 $timeout = time();\r
94 $timeout_timer = 0;\r
95 while(true){\r
96 // If there are no webclients connected, start the timer to disconnect\r
97 if(!count($ipc)){\r
98 if($timeout == 0) $timeout = time();\r
99 $timeout_timer = time() - $timeout;\r
100 if($timeout_timer >= $config['timeout']) break;\r
101 } else {\r
102 $timeout = 0;\r
103 }\r
104 \r
105 processClients();\r
106 \r
107 if($bot != null){\r
108 // $bot handles the sleep time here\r
109 $bot->Process();\r
110 } else {\r
111 usleep(5000);\r
112 }\r
113 }\r
114 \r
115 \r
116 // We've quit, lower the counter for this host\r
117 if($config['memcache_use']){\r
118 @GLOB::$mc->decrement($host_key);\r
119 }\r
120 \r
121 deb('Exiting client');\r
122 \r
123 \r
124 ############################################\r
125 ## Functions / Classes\r
126 ############################################\r
127 \r
128 \r
129 \r
130 function processClients(){\r
131 global $ipc_srv;\r
132 global $ipc;\r
133 global $ipc_read;\r
134 global $buffer;\r
135 global $timeout;\r
136 \r
137 // Check for any new web client connections...\r
138 $read = array($ipc_srv);\r
139 $write = $excep = array();\r
140 $read_changed = stream_select($read, $write, $excep, 0);\r
141 for($i=0; $i<$read_changed; $i++) {\r
142 if($read[$i] === $ipc_srv){\r
143 $ipc[] = stream_socket_accept($ipc_srv);\r
144 deb("Connection...");\r
145 }\r
146 }\r
147 \r
148 \r
149 // Check for any changed web clients..\r
150 $read = $ipc;\r
151 $read_changed = (count($read)) ? stream_select($read, $write, $excep, 0) : array();\r
152 if($read_changed){\r
153 foreach($read as $cl){\r
154 $data = fread($cl, 1024);\r
155 if(!$data){\r
156 // Web client has disconnected\r
157 deb("Removing closed socket..");\r
158 $key = array_search($cl, $ipc);\r
159 unset($ipc[$key]);\r
160 \r
161 $key = array_search($cl, $ipc_read);\r
162 if($key !== false) unset($ipc_read[$key]);\r
163 } else {\r
164 //deb('Got data: '.$data);\r
165 processClientMessage($data, $cl);\r
166 }\r
167 }\r
168 }\r
169 \r
170 \r
171 \r
172 // Send the buffer messages to any connected web clients..\r
173 // 1 message at a time...\r
174 if(count($buffer) && count($ipc_read)){\r
175 //deb(print_r($ipc_read, 1));\r
176 $msg = array_shift($buffer);\r
177 //deb("Sending '$msg' to ".count($ipc_read)." clients..");\r
178 foreach($ipc_read as $cl){\r
179 if($cl) fwrite($cl, $msg."\n");\r
180 }\r
181 }\r
182 \r
183 // The whole buffer at a time...\r
184 /*\r
185 while(count($buffer)){\r
186 $msg = array_shift($buffer);\r
187 foreach($ipc as $cl) frwite($cl, $msg);\r
188 }\r
189 */\r
190 \r
191 }\r
192 \r
193 \r
194 function processClientMessage($data, $cl){\r
195 global $config;\r
196 global $buffer;\r
197 global $bot, $ipc_read;\r
198 global $timeout;\r
199 global $send_debug;\r
200 global $app_args;\r
201 \r
202 require('dev_processClientMessage.php');\r
203 return true;\r
204 }\r
205 \r
206 \r
207 \r
208 \r
209 function errorHandler($errno, $errstr, $errfile, $errline){\r
210 $ret = '';\r
211 switch ($errno) {\r
212 case E_USER_ERROR:\r
213 $ret .= "USER [$errno] $errstr\n";\r
214 $ret .= " Fatal error on line $errline in file $errfile";\r
215 $ret .= ", PHP " . PHP_VERSION . " (" . PHP_OS . ")\n";\r
216 $ret .= "Aborting...<br />\n";\r
217 exit(1);\r
218 break;\r
219\r
220 case E_USER_WARNING:\r
221 $ret .= "WARNING on line $errline in file $errfile: [$errno] $errstr\n";\r
222 break;\r
223\r
224 case E_USER_NOTICE:\r
225 $ret .= "NOTICE on line $errline in file $errfile: [$errno] $errstr\n";\r
226 break;\r
227\r
228 default:\r
229 $ret .= "UNKOWN ERR on line $errline in file $errfile: [$errno] $errstr\n";\r
230 break;\r
231 }\r
232 \r
233 if(!empty($ret)) deb($ret); \r
234 \r
235 \r
236 /* Don't execute PHP internal error handler */\r
237 return true;\r
238 }