+++ /dev/null
-THOUGHTS
- The session ID posted from the webclient needs to be parsed. Eg. only allow chars [A-Za-z0-9]{number_of_chars}
-
-
-WEBIRC/CGIIRC NOTES
-
\ No newline at end of file
+++ /dev/null
-<?php\r
-\r
-class SocketStream {\r
- var $stream;\r
- function __construct($host = null, $port = null, $blocking = true) {\r
- if(!$host && !$port)\r
- return;\r
- $scheme = 'tcp';\r
- if($host{0}=='!')\r
- {\r
- $scheme = 'ssl';\r
- $port = 6697;\r
- $host = substr($host, 1);\r
- } \r
- $this->stream = @stream_socket_client("{$scheme}://$host:$port", $errno, $errstr, 4);\r
- if(!$this->stream)\r
- {\r
- debug("Error creating socket: $host $errstr\n");\r
- return;\r
- }\r
-// socket_set_timeout($this->stream, 30);\r
- stream_set_blocking($this->stream, $blocking);\r
- }\r
- function __destruct()\r
- {\r
- if($this->stream)\r
- {\r
- fclose($this->stream);\r
- $this->stream = null;\r
- }\r
- }\r
- function SetBlocking($blocking = true)\r
- {\r
- if(!$this->stream)\r
- return false;\r
- stream_set_blocking($this->stream, $blocking);\r
- }\r
- function SetTimeout($timeout, $ms=0)\r
- {\r
- if(!$this->stream)\r
- return false;\r
- stream_set_timeout($this->stream, $timeout, $ms);\r
- }\r
- function Eof()\r
- {\r
- if(!$this->stream)\r
- return true;\r
- $x = stream_get_meta_data($this->stream);\r
- if($x['eof'] && $x['unread_bytes']==0 && feof($this->stream))\r
- return true;\r
- return false;\r
- }\r
- function Read($length = 512, $type = PHP_BINARY_READ)\r
- {\r
- if(!$this->stream) return false;\r
- if($type == PHP_NORMAL_READ){\r
- $ret = fgets($this->stream, $length);\r
- } elseif($type == PHP_BINARY_READ) {\r
- $ret = fread($this->stream, $length);\r
- }\r
- //file_put_contents('/home/wok/public_html/kiwi/rawlog', '> '.$ret, FILE_APPEND);\r
- return $ret;\r
- }\r
- function Write($data)\r
- {\r
- global $totalup;\r
- if(!$this->stream) return false;\r
- \r
- //file_put_contents('/home/wok/public_html/kiwi/rawlog', '< '.$data, FILE_APPEND);\r
- $x = @fwrite($this->stream, $data);\r
- return $x;\r
- }\r
- function GetInfo()\r
- {\r
- if(!$this->stream)\r
- return false;\r
- return array('local'=>stream_socket_get_name($this->stream,false),'remote'=>stream_socket_get_name($this->stream, true));\r
- }\r
-}\r
-class SocketStreamSSL extends SocketStream\r
-{\r
- function __construct($host = null, $port = null, $blocking = true)\r
- {\r
- if(!$host && !$port)\r
- return;\r
- $this->stream = @stream_socket_client("ssl://$host:$port", $errno, $errstr, 4);\r
- if(!$this->stream)\r
- {\r
- debug("Error creating socket: $host $errstr\n");\r
- return;\r
- }\r
-// socket_set_timeout($this->stream, 30);\r
- stream_set_blocking($this->stream, $blocking);\r
- }\r
-}\r
-class IRC\r
-{\r
- var $stream;\r
- var $url, $urlinfo;\r
- var $nick;\r
- protected $msgqueue = array();\r
- protected $dccs = array();\r
- private $reconnect=0;\r
- private $nextping=0;\r
- public $modes;\r
- public $chanlist;\r
- public $connected;\r
- function __construct($url, $kiwi=null, $opts=array()){ \r
- $this->url = $url;\r
- $urlinfo = parse_url($url);\r
- $this->urlinfo = $urlinfo;\r
- if(!ereg("^ircs?$", $urlinfo['scheme']))\r
- return false;\r
- $ssl = ($urlinfo['scheme']=='ircs');\r
- $host = $urlinfo['host'];\r
- $port = isset($urlinfo['port'])?$urlinfo['port']:6667;\r
- $this->nick = $nick = isset($urlinfo['user'])?$urlinfo['user']:'kiwi_user|'.(string)rand(0,9999);\r
- //$ident = isset($urlinfo['pass'])?$urlinfo['pass']:$nick;\r
- $ident = (isset($opts['ident'])) ? "{$opts['ident']}_kiwi" : "{$nick}_kiwi";\r
- $chans = false;\r
- if(isset($urlinfo['path'])){\r
- $path = trim($urlinfo['path'], "/");\r
- $chans = explode(",", $path); //"#".str_replace(array(":", ","), array(" ", ",#"), $path);\r
- }\r
- $this->connected = false;\r
- if($ssl)\r
- $this->stream = new SocketStreamSSL($host, $port, false);\r
- else\r
- $this->stream = new SocketStream($host, $port, false);\r
- if(!$this->stream || !$this->stream->stream){\r
- return false;\r
- }\r
- \r
- // Send the login data\r
- if($kiwi != null) $this->stream->Write($kiwi."\r\n");\r
- if(isset($urlinfo['fragment'])) $this->stream->Write("PASS {$urlinfo['fragment']}\r\n");\r
- \r
- $this->stream->Write("NICK $nick\r\n");\r
- $this->stream->Write("USER $ident 0 0 :$nick\r\n");\r
- //if($chans){\r
- // foreach($chans as $chan)\r
- // $this->stream->Write("JOIN ".str_replace(":", " ", $chan)."\r\n");\r
- //} else {\r
- $chans = array();\r
- //}\r
- $this->chans = $chans;\r
- $this->connected = true;\r
- return true;\r
- }\r
- function __destruct(){\r
- if($this->stream){\r
- $this->stream->Write("QUIT :kiwi\r\n"); \r
- }\r
- }\r
- function Process(){\r
- if((!$this->stream || !$this->stream->stream)){\r
- if(time() > $this->reconnect) {\r
- $this->__construct($this->url);\r
- $this->reconnect = time() + 10;\r
- }\r
- usleep(50000);\r
- return;\r
- }\r
- if($this->stream->Eof()){\r
- $this->stream = null;\r
- return;\r
- }\r
- $r=array($this->stream->stream);\r
- $w = $e = array();\r
- if(($num=@stream_select($r, $w,$e,0,50000))===false){\r
- \r
- } elseif($num>0){\r
- $data=$this->stream->Read(512, PHP_NORMAL_READ);\r
- //deb($data);\r
- if(preg_match("/^(?::(?:([a-z0-9\x5B-\x60\x7B-\x7D\.\-]+)|([a-z0-9\x5B-\x60\x7B-\x7D\.\-]+)!([a-z0-9~\.\-_|]+)@([a-z0-9\.\-:]+)) )?([a-z0-9]+)(?:(?: ([^:]+))?(?: :(.+))?)$/i", $data, $regs))\r
- {\r
- unset($prefix, $nick, $ident, $hostname, $command, $params, $trailing, $flarp);\r
- $prefix = $regs[1];\r
- $nick = $regs[2];\r
- $ident = $regs[3];\r
- $hostname = $regs[4];\r
- $command = $regs[5];\r
- $params = isset($regs[6]) ? $regs[6] : '';\r
- $trailing = trim(isset($regs[7]) ? $regs[7] : '');\r
- $flarp = compact('prefix', 'nick', 'ident', 'hostname', 'command', 'params', 'trailing');\r
- $this->ProcessMessage($flarp);\r
- }\r
- }\r
- else\r
- {\r
- if(sizeof($this->msgqueue) && (microtime(true)>($this->lastqueuewrite+0.1)) && ($msg=array_shift($this->msgqueue)))\r
- { $this->lastqueuewrite = microtime(true); $this->stream->Write($msg); }\r
- foreach($this->dccs as $k=>&$dcc)\r
- {\r
- if(!$dcc->Process())\r
- {\r
- if($dcc->errorinfo)\r
- $this->SendNotice($dcc->errorinfo['nick'], $dcc->errorinfo['text']);\r
- unset($this->dccs[$k]);\r
- }\r
- }\r
- if(($now=microtime(1))>$this->nextping)\r
- {\r
- $this->stream->Write("PONG x\r\n");\r
- $this->nextping = $now + 150;\r
- }\r
- }\r
- }\r
- function ProcessMessage($message)\r
- {\r
- //echo $message['command']."\n";\r
- switch($message['command'])\r
- {\r
- case "PING":\r
- $this->stream->Write("PONG {$message['trailing']}\r\n");\r
- break;\r
- case "PRIVMSG":\r
- $this->ProcessPrivMsg($message);\r
- break;\r
- case "001":\r
- if($this->chans)\r
- foreach($this->chans as $chan)\r
- $this->stream->Write("JOIN ".str_replace(":", " ", $chan)."\r\n");\r
- break;\r
- case "443":\r
- $newnick = 'kiwi_user|'.rand(0,99999);\r
- $this->SendCmd("NICK ".$newnick);\r
- $this->nick = $newnick;\r
- break;\r
- case "MODE":\r
- $this->OnMODE($message);\r
- break;\r
- case "353":\r
- $this->On353($message);\r
- break;\r
- case "QUIT":\r
- $chan = $message['params'];\r
- foreach($this->chanlist as &$chan){\r
- if(isset($chan['userlist'][$message['nick']]))\r
- unset($chan['userlist'][$message['nick']]);\r
- }\r
- break;\r
- case "PART":\r
- $chan = $message['params'];\r
- //debug("Parting {$message['nick']} from $chan");\r
- if(isset($this->chanlist[ltrim($chan, "#")])){\r
- unset($this->chanlist[ltrim($chan, "#")]['userlist'][$message['nick']]);\r
- }\r
- break;\r
- case "JOIN":\r
- $chan = $message['trailing'];\r
- $nick = array($message['nick'] => '');\r
- $nicklist = is_array($this->chanlist[ltrim($chan, "#")]['userlist']) ? $this->chanlist[ltrim($chan, "#")]['userlist'] :\r
- array();\r
- \r
- $this->chanlist[ltrim($chan, "#")]['userlist'] = array_merge($nicklist, $nick);\r
- break;\r
- case "NICK":\r
- if($message['nick'] == $this->nick){\r
- $this->nick = $message['trailing'];\r
- }\r
- foreach($this->chanlist as $chan_name => $chan){\r
- foreach($chan['userlist'] as $nick => $status){\r
- if($nick == $message['nick']){\r
- $this->chanlist[$chan_name]['userlist'][$message['trailing']] = $this->chanlist[$chan_name]['userlist'][$message['nick']];\r
- unset($this->chanlist[$chan_name]['userlist'][$message['nick']]);\r
- break;\r
- }\r
- }\r
- }\r
- break;\r
- }\r
- }\r
- function OnMODE($message){\r
- if($message['params'] == $this->nick) {\r
- $modes = $message['trailing'];\r
- $size = strlen($modes);\r
- $add = 1;\r
- for($i=0;$i<$size;$i++){\r
- if($modes{$i} == '+'){\r
- $add = 1;\r
- continue;\r
- } elseif($modes{$i} == '-'){\r
- $add = 0;\r
- continue;\r
- }\r
- if($add && strpos($this->modes, $modes{$i}) === false)\r
- $this->modes.=$modes{$i};\r
- if(!$add && strpos($this->modes, $modes{$i}))\r
- $this->modes = str_replace($modes{$i}, "", $this->modes);\r
- }\r
- }\r
- $params = $message['params'];\r
- $chan = trim(strtok($params, ' '));\r
- if(in_array(trim($chan,'#'), $this->chans)){\r
- $modes = strtok(' ');\r
- $therest = explode(" ", trim(strtok('')));\r
- $size = strlen($modes);\r
- $add = 1;\r
- $offset = 0;\r
- for($i=0;$i<$size;$i++){\r
- if($modes{$i} == '+'){\r
- $add = 1;\r
- $offset--;\r
- continue;\r
- } elseif($modes{$i} == '-'){\r
- $add = 0;\r
- $offset--;\r
- continue;\r
- }\r
- if($modes[$i]=='v')\r
- {\r
- $user = $therest[$i+$offset];\r
- if($add)\r
- {\r
- if(stripos($this->chanlist[trim($chan,'#')]['userlist'][$user], '+')===false)\r
- $this->chanlist[trim($chan,'#')]['userlist'][$user] .= '+';\r
- }\r
- else\r
- $this->chanlist[trim($chan,'#')]['userlist'][$user] = str_replace('+','',$this->chanlist[trim($chan,'#')]['userlist'][$user]);\r
- continue;\r
- }\r
- if($modes[$i]=='o')\r
- {\r
- $user = $therest[$i+$offset];\r
- if($add)\r
- {\r
- if(stripos($this->chanlist[trim($chan,'#')]['userlist'][$user], '@')===false)\r
- $this->chanlist[trim($chan,'#')]['userlist'][$user] .= '@';\r
- }\r
- else\r
- $this->chanlist[trim($chan,'#')]['userlist'][$user] = str_replace('@','',$this->chanlist[trim($chan,'#')]['userlist'][$user]);\r
- continue;\r
- }\r
- if($modes[$i]=='h')\r
- {\r
- $user = $therest[$i+$offset];\r
- if($add)\r
- {\r
- if(stripos($this->chanlist[trim($chan,'#')]['userlist'][$user], '%')===false)\r
- $this->chanlist[trim($chan,'#')]['userlist'][$user] .= '%';\r
- }\r
- else\r
- $this->chanlist[trim($chan,'#')]['userlist'][$user] = str_replace('%','',$this->chanlist[trim($chan,'#')]['userlist'][$user]);\r
- continue;\r
- }\r
- if($modes[$i]=='q')\r
- {\r
- $user = $therest[$i+$offset];\r
- if($add)\r
- {\r
- if(stripos($this->chanlist[trim($chan,'#')]['userlist'][$user], '~')===false)\r
- $this->chanlist[trim($chan,'#')]['userlist'][$user] .= '~';\r
- }\r
- else\r
- $this->chanlist[trim($chan,'#')]['userlist'][$user] = str_replace('~','',$this->chanlist[trim($chan,'#')]['userlist'][$user]);\r
- continue;\r
- }\r
- }\r
- }\r
- \r
- }\r
- function On353($message){\r
- // Response to NAMES command\r
- list($nick,,$chan) = explode(" ", $message['params']);\r
- $nicks = explode(" ", $message['trailing']);\r
- $prefixes = array('~', '&', '@','%','+');\r
- $nicklist = array();\r
- foreach($nicks as $nick){\r
- if(in_array($nick{0}, $prefixes)){\r
- $prefix = $nick{0};\r
- $nick = substr($nick,1);\r
- }\r
- else\r
- $prefix = '';\r
- $nicklist[$nick] = $prefix;\r
- }\r
- if(sizeof($nicklist)){\r
- // If we havn't got a list of nicks for this channel yet, create it\r
- if(!isset($this->chanlist[ltrim($chan, "#")]['userlist'])){\r
- $this->chanlist[ltrim($chan, "#")]['userlist'] = array();\r
- }\r
- $this->chanlist[ltrim($chan, "#")]['userlist'] = array_merge($this->chanlist[ltrim($chan, "#")]['userlist'], $nicklist);\r
- }\r
- }\r
- function ProcessPrivMsg($message){\r
- //$cmd = strtok($message['trailing'], ' ');\r
- //switch($cmd){\r
- //}\r
- }\r
- function SendMessage($dest, $text){\r
- if(!$this->stream)\r
- return false;\r
- $this->stream->Write("PRIVMSG $dest :$text\r\n");\r
- }\r
- function Join($chan){\r
- $this->stream->Write("JOIN ".str_replace(":", " ", $chan)."\r\n");\r
- }\r
- function SendNotice($dest, $text)\r
- {\r
- $this->stream->Write("NOTICE $dest :$text\r\n");\r
- }\r
- function QueueMessage($dest, $text)\r
- {\r
- $this->msgqueue[] = "PRIVMSG $dest :$text\r\n";\r
- }\r
- function QueueNotice($dest, $text)\r
- {\r
- $this->msgqueue[] = "NOTICE $dest :$text\r\n"; \r
- }\r
- function GetMainChan()\r
- {\r
- return '#'.$this->chans[0]; \r
- }\r
-}
\ No newline at end of file
+++ /dev/null
-<?php\r
-\r
- class IRCConnection extends IRC {\r
- \r
- var $scrollback = array();\r
- var $server_options = array();\r
- \r
- function ProcessMessage($message){\r
- global $config;\r
- global $buffer;\r
- global $send_debug;\r
- \r
- //debug("Message: ".print_r($message, 1));\r
- deb(print_r($message, 1));\r
- \r
- if(strlen($message['trailing']) && ord($message['trailing'][0]) == 1){\r
- $message['trailing'] = trim($message['trailing'], chr(1));\r
- if(strtoupper(substr($message['trailing'], 1, 6)) == 'ACTION'){\r
- $message['command'] = 'ACTION';\r
- } else {\r
- $message['command'] = 'CTCP';\r
- }\r
- }\r
- \r
- switch(strtoupper($message['command'])){\r
- case '001':\r
- $buffer[] = json_encode(array(\r
- 'event'=>'connect',\r
- 'connected'=>true,\r
- 'host'=>$args['server']\r
- ));\r
- break;\r
- \r
- case '005':\r
- $opts = explode(' ', $message['params']);\r
- $to_client = array();\r
- foreach($opts as $pair){\r
- $opt = explode('=', $pair, 2);\r
- $name = strtoupper($opt[0]);\r
- $val = isset($opt[1]) ? $opt[1] : true;\r
- $this->server_options[$name] = $val;\r
- \r
- if(in_array($name, array('NETWORK', 'PREFIX', 'CHANTYPES'))){\r
- // Put the user prefixes (~&@ etc etc) into a more usable format\r
- if($name == 'PREFIX'){\r
- $matches = null;\r
- preg_match('/\(([^)]*)\)(.*)/', $val, $matches);\r
- \r
- $val = array();\r
- if(count($matches) == 3){\r
- for($i=0; $i<strlen($matches[1]); $i++){\r
- $val[$matches[2][$i]] = $matches[1][$i];\r
- }\r
- }\r
- }\r
- $to_client[$name] = $val;\r
- }\r
- }\r
- \r
- $data = array(\r
- 'event' => 'options',\r
- 'server' => '',\r
- 'options' => $to_client\r
- );\r
- $buffer[] = json_encode($data);\r
- break;\r
- \r
- case RPL_WHOISUSER:\r
- case RPL_WHOISSERVER:\r
- case RPL_WHOISOPERATOR:\r
- case RPL_WHOISIDLE:\r
- case RPL_ENDOFWHOIS:\r
- case RPL_WHOISCHANNELS:\r
- case RPL_WHOISMODES:\r
- $tmp = explode(' ', $message['params']);\r
- $tmp = $tmp[1];\r
- $data = array(\r
- 'event' => 'whois',\r
- 'server' => '',\r
- 'nick' => $tmp,\r
- 'msg' => $message['trailing']\r
- );\r
- $buffer[] = json_encode($data);\r
- break;\r
- \r
- case RPL_MOTD:\r
- $data = array(\r
- 'event' => 'motd',\r
- 'server' => '',\r
- 'msg' => $message['trailing']\r
- );\r
- $buffer[] = json_encode($data);\r
- break;\r
- \r
- case "353":\r
- // NAMES command reply\r
- list($nick,,$chan) = explode(" ", $message['params']);\r
- $nicks = explode(" ", $message['trailing']);\r
- \r
- $data = array(\r
- 'event' => 'userlist',\r
- 'server' => '',\r
- 'users' => array(),\r
- 'channel' => $chan\r
- );\r
- \r
- $prefixes = array('~', '&', '@','%','+');\r
- $nicklist = array();\r
- $i = 0;\r
- foreach($nicks as $nick){\r
- if(in_array($nick{0}, $prefixes)){\r
- $prefix = $nick{0};\r
- $nick = substr($nick,1);\r
- } else {\r
- $prefix = '';\r
- }\r
- $nicklist[$nick] = $prefix;\r
- \r
- if($i==50){\r
- $tmp = $data;\r
- $tmp['users'] = $nicklist;\r
- $buffer[] = json_encode($tmp);\r
- unset($tmp);\r
- $nicklist = array();\r
- }\r
- \r
- $i++;\r
- }\r
- \r
- if(count($nicklist)){\r
- $tmp = $data;\r
- $tmp['users'] = $nicklist;\r
- $buffer[] = json_encode($tmp);\r
- }\r
- //deb(print_r($data, 1));\r
- break;\r
- \r
- case '366':\r
- list(,$chan) = explode(' ', $message['params']);\r
- $data = array(\r
- 'event' => 'userlist_end',\r
- 'server' => '',\r
- 'channel' => $chan\r
- );\r
- $buffer[] = json_encode($data);\r
- break;\r
- \r
- case ERR_LINKCHANNEL:\r
- list($nick, $source_chan, $dest_chan) = explode(' ', $message['params']);\r
- $data = array(\r
- 'event' => 'channel_redirect',\r
- 'from' => $source_chan,\r
- 'to' => $dest_chan\r
- );\r
- $buffer[] = json_encode($data);\r
- break;\r
- \r
- case ERR_NOSUCHNICK:\r
- //TODO: shit\r
- break;\r
- \r
- case "JOIN":\r
- $data = array(\r
- 'event' => 'join',\r
- 'nick' => $message['nick'],\r
- 'ident' => $message['ident'],\r
- 'hostname' => $message['hostname'],\r
- 'channel' => $message['trailing'],\r
- );\r
- $buffer[] = json_encode($data);\r
- \r
- deb("JOIN: {$message['nick']} / {$this->nick}");\r
- if($message['nick'] == $this->nick){\r
- $this->stream->Write("NAMES {$message['trailing']}\r\n");\r
- }\r
- \r
- break;\r
- \r
- case "PART":\r
- $data = array(\r
- 'event' => 'part',\r
- 'nick' => $message['nick'],\r
- 'ident' => $message['ident'],\r
- 'hostname' => $message['hostname'],\r
- 'channel' => trim($message['params']),\r
- 'message' => $message['trailing'],\r
- );\r
- $buffer[] = json_encode($data);\r
- break;\r
- \r
- case "KICK":\r
- $tmp = explode(' ', $message['params']);\r
- \r
- $data = array(\r
- 'event' => 'kick',\r
- 'kicked' => $tmp[1],\r
- 'nick' => $message['nick'],\r
- 'ident' => $message['ident'],\r
- 'hostname' => $message['hostname'],\r
- 'channel' => trim($tmp[0]),\r
- 'message' => $message['trailing'],\r
- );\r
- $buffer[] = json_encode($data);\r
- break;\r
- \r
- case "QUIT":\r
- $data = array(\r
- 'event' => 'quit',\r
- 'nick' => $message['nick'],\r
- 'ident' => $message['ident'],\r
- 'hostname' => $message['hostname'],\r
- 'message' => $message['trailing'],\r
- );\r
- $buffer[] = json_encode($data);\r
- break;\r
- \r
- case "NOTICE":\r
- $data = array(\r
- 'event' => 'notice',\r
- 'nick' => $message['nick'],\r
- 'ident' => $message['ident'],\r
- 'hostname' => $message['hostname'],\r
- 'msg' => $message['trailing'],\r
- );\r
- $buffer[] = json_encode($data);\r
- break;\r
- \r
- case "NICK":\r
- $data = array(\r
- 'event' => 'nick',\r
- 'nick' => $message['nick'],\r
- 'ident' => $message['ident'],\r
- 'hostname' => $message['hostname'],\r
- 'newnick' => $message['trailing'],\r
- );\r
- $buffer[] = json_encode($data);\r
- break;\r
- \r
- case 'TOPIC':\r
- $data = array(\r
- 'event' => 'topic',\r
- 'nick' => $message['nick'],\r
- 'channel' => $message['params'],\r
- 'topic' => $message['trailing']\r
- );\r
- $buffer[] = json_encode($data);\r
- break;\r
- \r
- case '332':\r
- $tmp = explode(' ', $message['params']);\r
- $data = array(\r
- 'event' => 'topic',\r
- 'nick' => '',\r
- 'channel' => $tmp[1],\r
- 'topic' => $message['trailing']\r
- );\r
- $buffer[] = json_encode($data);\r
- break;\r
- \r
- case 'ACTION':\r
- $data = array(\r
- 'event' => 'action',\r
- 'nick' => $message['nick'],\r
- 'msg' => trim(substr($message['trailing'], 8), chr(1)),\r
- 'channel' => $message['params'],\r
- 'time' => time()\r
- );\r
- $buffer[] = json_encode($data);\r
- break;\r
- \r
- case 'CTCP':\r
- $data = array(\r
- 'event' => 'ctcp',\r
- 'nick' => $message['nick'],\r
- 'msg' => trim(substr($message['trailing'], 8), chr(1)),\r
- 'channel' => $message['params'],\r
- 'time' => time()\r
- );\r
- $buffer[] = json_encode($data);\r
- break;\r
- \r
- case 'MODE':\r
- $opts = explode(' ', $message['params']);\r
- if(count($opts) == 1){\r
- $effected_nick = $opts[0];\r
- $mode = $message['trailing'];\r
- } elseif(count($opts) == 2){\r
- $channel = $opts[0];\r
- $mode = $opts[1];\r
- } else {\r
- $channel = $opts[0];\r
- $mode = $opts[1];\r
- $effected_nick = $opts[2];\r
- }\r
- \r
- $data = array(\r
- 'event' => 'mode',\r
- 'nick' => $message['nick'],\r
- 'mode' => $mode\r
- );\r
- \r
- if(isset($effected_nick)) $data['effected_nick'] = $effected_nick;\r
- if(isset($channel)) $data['channel'] = $channel;\r
- $buffer[] = json_encode($data);\r
- \r
- break;\r
- }\r
- \r
- if($send_debug){\r
- $ret = str_replace('\n', ' ', print_r($message, 1));\r
- $data = array(\r
- 'event' => 'debug',\r
- 'msg' => $ret,\r
- 'time' => time()\r
- );\r
- $buffer[] = json_encode($data);\r
- }\r
- \r
- parent::ProcessMessage($message);\r
- }\r
- \r
- \r
- \r
- \r
- function ProcessPrivMsg($message){\r
- global $buffer;\r
- global $timeout;\r
- global $config;\r
- \r
- $msg = $message['trailing'];\r
- $cmd = strtok($msg, ' ');\r
- //debug(print_r($message));\r
- //deb(print_r($message, 1));\r
- $data = array(\r
- 'event' => 'msg',\r
- 'nick' => $message['nick'],\r
- 'msg' => $message['trailing'],\r
- 'channel' => $message['params'],\r
- 'time' => time()\r
- );\r
- \r
- // Save it into the scrollback\r
- if($config['scrollback_size']){\r
- deb('Size: '.count($this->scrollback));\r
- if(count($this->scrollback) >= $config['scrollback_size']){\r
- \r
- for($i=1; $i<count($this->scrollback); $i++){\r
- $this->scrollback[$i-1] = $this->scrollback[$i];\r
- }\r
- /*\r
- for($j=$i; $j<count($this->scrollback); $j++){\r
- unset($this->scrollback[$i]);\r
- }\r
- //unset($this->scrollback[$i]);\r
- */\r
- $pos = count($this->scrollback)-1;\r
- deb('Popped');\r
- } else {\r
- $pos = count($this->scrollback);\r
- }\r
- \r
- $this->scrollback[$pos] = $data;\r
- }\r
- \r
- $buffer[] = json_encode($data);\r
- parent::ProcessPrivMsg($message);\r
- \r
- return;\r
- }\r
- \r
- \r
- private function isChannel($name){\r
- return ($name[0] == "#");\r
- }\r
- \r
- \r
- private function formatMsgToHtml($inp){\r
- $tmp = $inp;\r
- \r
- // Bold\r
- if(strpos($tmp, chr(2))){\r
- $next = '<b>';\r
- while(strpos($tmp, chr(2)) !== false){\r
- $pos = strpos($tmp, chr(2));\r
- $tmp = str_replace($tmp, chr(2), $next);\r
- $next = ($next=='<b>') ? '</b>' : '<b>';\r
- }\r
- if($next == '</b>') $tmp = $tmp . '</b>';\r
- }\r
- \r
- return $tmp;\r
- }\r
- \r
- }
\ No newline at end of file
+++ /dev/null
-<?php\r
-\r
- class SESSIONS {\r
- static function exists($session_id){\r
- global $config;\r
- \r
- if($config['memcache_use']){\r
- $ret = GLOB::$mc->get('sid_'.$session_id) ? true : false;\r
- return $ret;\r
- } else {\r
- $session_sok = $config['sok_dir'].$config['sok_prefix'].$session_id;\r
- return file_exists($session_sok);\r
- }\r
- }\r
- \r
- \r
- \r
- static function create($client_key){\r
- global $config;\r
- \r
- $temp_id = md5(microtime().rand());\r
- \r
- if($config['memcache_use']){\r
- $host_key = 'hostcount_'.$client_key;\r
- $count = (int)GLOB::$mc->get($host_key);\r
- if($count > $config['connections_per_host']) return false;\r
- \r
- // Save the sid into memcached for the ircbot to pick up\r
- GLOB::$mc->add('sid_'.$temp_id, $temp_id);\r
- }\r
- \r
- $session_cmd = "{$config['php_path']} {$config['session_script_path']} $temp_id $host_key -h$client_key";\r
- //die($session_cmd);\r
- $session_status = `$session_cmd`;\r
- \r
- if($session_status != 'ok'){\r
- debug("Failed creating session socket with: $session_status");\r
- GLOB::$mc->delete('sid_'.$temp_id);\r
- return false;\r
- }\r
- \r
- if($config['memcache_use']){\r
- GLOB::$mc->add($host_key, 0);\r
- GLOB::$mc->increment($host_key);\r
- }\r
- \r
- return $temp_id;\r
- }\r
- \r
- \r
- \r
- static function open($session_id){\r
- global $config;\r
- \r
- if($config['memcache_use']){\r
- $session_sok = GLOB::$mc->get('sid_'.$session_id);\r
- if(!$session_sok) return false;\r
- } else {\r
- $session_sok = $session_id;\r
- }\r
- $session_sok = $config['sok_dir'].$config['sok_prefix'].$session_sok;\r
- \r
- $sok = @stream_socket_client('unix://'.$session_sok, $errno, $errstr);\r
- \r
- if(!$sok) return false;\r
- return $sok;\r
- }\r
- \r
- \r
- \r
- static function close($session){\r
- fclose($session);\r
- }\r
- \r
- \r
- static function read($session, $block=true){\r
- fwrite($session, json_encode(array('method'=>'read')));\r
- \r
- if(!$block){\r
- stream_set_timeout($session, 0, 100000);\r
- } else {\r
- stream_set_timeout($session, 120, 0);\r
- }\r
- $data = fgets($session);\r
- \r
- return $data;\r
- }\r
- \r
- \r
- \r
- \r
- \r
- static function clStart($session_id){\r
- global $config;\r
- \r
- if($config['memcache_use']){\r
- $session_sok = GLOB::$mc->get('sid_'.$session_id);\r
- if(!$session_sok) return false;\r
- } else {\r
- $session_sok = $session_id;\r
- }\r
- $session_sok = $config['sok_dir'].$config['sok_prefix'].$session_sok;\r
- \r
- $sok = stream_socket_server('unix://'.$session_sok, $errno, $errstr);\r
- if(!$sok) return false;\r
- \r
- return $sok;\r
- \r
- }\r
- \r
- \r
- static function clStop($session){\r
- fclose($session);\r
- }\r
- }\r
+++ /dev/null
-<?php\r
-\r
- // Class for storing global vars\r
- class GLOB {\r
- // Memcache connection\r
- static $mc;\r
- }\r
- \r
- \r
- if($config['memcache_use']){\r
- GLOB::$mc = new Memcache();\r
- GLOB::$mc->addServer('localhost', 11211, true, 1);\r
- }\r
- \r
- \r
- \r
- function deb($what){\r
- //if(DEBUG){\r
- // echo "$what\n";\r
- //} else {\r
- file_put_contents('/tmp/kiwi_err.log', "$what\n", FILE_APPEND);\r
- //}\r
- }\r
- function debug($what){ deb($what); }
\ No newline at end of file
+++ /dev/null
-<?php\r
-\r
-\r
- //deb("FROM IPC CLIENT:\n$data\n-----");\r
- $d = json_decode($data, 1);\r
- //deb('Processed data: '.print_r($d, 1));\r
- switch($d['method']){\r
- case 'addbuffer':\r
- $buffer[] = json_encode($d['args']);\r
- break;\r
- \r
- case 'read':\r
- // The 'read' command adds this web client to the read buffer queue\r
- if(!in_array($cl, $ipc_read)) $ipc_read[] = $cl;\r
- break;\r
- \r
- case 'quit':\r
- deb('Quitting');\r
- $bot = null;\r
- break;\r
- \r
- case 'connect':\r
- $args = $d['args'];\r
- deb('Connecting with: '.print_r($args, 1));\r
- if(!isset($args['server'], $args['port'], $args['ssl'], $args['nick'])){\r
- $buffer[] = json_encode(array('error'=>'invalid_args'));\r
- break;\r
- } else {\r
- $kiwi = null;\r
- /*if($config['memcache_use']){\r
- $conf_key = 'kiwi_conf_'.$args['server'];\r
- $conf = (int)GLOB::$mc->get($conf_key);\r
- if($conf){\r
- $c = @unserialize($conf);\r
- if($c){\r
- //$hostname = GET HOSTNAME HERE\r
- //$ip = GET IP HERE\r
- $kiwi = "WEBIRC {$c['password']} {$c['user']} $hostname $ip";\r
- }\r
- }\r
- }*/\r
- deb("ARGSLOL: ".print_r($app_args, 1));\r
- $opts = array();\r
- if(isset($app_args['remote_host'])) $opts['ident'] = md5($app_args['remote_host']);\r
- \r
- $bot = new IRCConnection("irc://{$args['nick']}@{$args['server']}:{$args['port']}", $kiwi, $opts);\r
- if(isset($args['channels'])) $bot->chans = explode(',', $args['channels']);\r
- if($bot->connected){\r
- // We're.. connected!\r
- } else {\r
- $buffer[] = json_encode(array('event'=>'server_connect', 'connected'=>false, 'host'=>$args['server']));\r
- unset($bot);\r
- }\r
- }\r
- break;\r
- \r
- case 'join':\r
- $args = $d['args'];\r
- if(!isset($args['channel'])){\r
- $buffer[] = json_encode(array('error'=>'invalid_args'));\r
- break;\r
- } else {\r
- $chans = explode(',', $args['channel']);\r
- foreach($chans as $c)\r
- $bot->Join($c);\r
- }\r
- break;\r
- \r
- case 'msg':\r
- $args = $d['args'];\r
- deb('msg with: '.print_r($args, 1));\r
- if(!isset($args['target'],$args['msg'])){\r
- $buffer[] = json_encode(array('error'=>'invalid_args'));\r
- break;\r
- } else {\r
- $bot->SendMessage($args['target'], $args['msg']);\r
- $buffer[] = json_encode($data);\r
- }\r
- break;\r
- \r
- case 'action':\r
- $args = $d['args'];\r
- deb('action with: '.print_r($args, 1));\r
- if(!isset($args['target'],$args['msg'])){\r
- $buffer[] = json_encode(array('error'=>'invalid_args'));\r
- break;\r
- } else {\r
- $bot->SendMessage($args['target'], chr(1)."ACTION {$args['msg']}".chr(1));\r
- $buffer[] = json_encode($data);\r
- }\r
- break;\r
- \r
- case 'raw':\r
- $args = $d['args'];\r
- if(!isset($args['data'])){\r
- $buffer[] = json_encode(array('error'=>'invalid_args'));\r
- break;\r
- } else {\r
- $bot->stream->Write("{$args['data']}\r\n");\r
- //$bot->SendMessage($args['target'], $args['msg']);\r
- }\r
- break;\r
- \r
- \r
- case 'debug':\r
- $send_debug = !$send_debug;\r
- $data = array(\r
- 'event' => 'debug',\r
- 'msg' => 'Debugging '.($send_debug)?'on':'off',\r
- 'time' => time()\r
- );\r
- $buffer[] = json_encode($data);\r
- break;\r
- \r
- \r
- case 'sync':\r
- // Clear the current buffer as we're gonna send only scrollback\r
- $buffer = array();\r
- \r
- // Send the settings and channels over\r
- if($bot){\r
- $data = array('event'=>'sync');\r
- $data['nick'] = $bot->nick;\r
- $data['tabviews'] = array();\r
- if($bot->chanlist){\r
- foreach($bot->chanlist as $chan_name => $chan){\r
- $data['tabviews'][] = array('name'=>$chan_name, 'userlist'=>$chan['userlist']);\r
- }\r
- $buffer[] = json_encode($data);\r
- }\r
- \r
- // Send the message scrollback\r
- foreach($bot->scrollback as $line) $buffer[] = json_encode($line);\r
- //$bot->scrollback = array();\r
- } else {\r
- $data = array('error'=>'no_data');\r
- }\r
- \r
- $buffer[] = json_encode($data);\r
- \r
- break;\r
- }
\ No newline at end of file
+++ /dev/null
-<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">\r
-<html xmlns="http://www.w3.org/1999/xhtml">\r
-<head>\r
-<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />\r
-<title>kiwi</title>\r
-<link rel="stylesheet" type="text/css" href="css/default.css">\r
-<link rel="stylesheet" type="text/css" href="css/ui.css">\r
-\r
-<?php\r
-\r
- switch(true){\r
- case stripos($_SERVER['HTTP_USER_AGENT'], 'android') > 0:\r
- case stripos($_SERVER['HTTP_USER_AGENT'], 'iphone') > 0:\r
- case stripos($_SERVER['HTTP_USER_AGENT'], 'ipod') > 0:\r
-?>\r
-<meta name="viewport" content="width=device-width,user-scalable=no" />\r
-\r
-<?php\r
- break;\r
- \r
- }\r
-?>\r
-\r
-<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.3/jquery.min.js"></script>\r
-<script type="text/javascript" src="js/jquery.json-2.2.min.js"></script>\r
-<script type="text/javascript" src="js/util.js"></script>\r
-<script type="text/javascript" src="js/gateway.js"></script>\r
-<script type="text/javascript" src="js/front.js"></script>\r
-<script type="text/javascript">\r
-\r
- var init_data = {};\r
-\r
- $(document).ready(function(){\r
- \r
- //#nick@irc.anonnet.org:6679+/#channel,##channel,&channel\r
- var chans = document.location.hash.match(/[#&]+[^ ,\007]+/g);\r
- if(chans != null && chans.length > 0) { init_data.channel = chans.join(','); }\r
- \r
- front.init();\r
- });\r
-</script>\r
-\r
-</head>\r
-\r
-<body>\r
-\r
-<div id="kiwi">\r
- <div class="connectwindow">\r
- <form class="formconnectwindow">\r
- <label for="nick">Nick</label>\r
- <input type="text" class="nick" value="<?php if(isset($_GET['nick'])) echo htmlentities($_GET['nick']); ?>" /><br />\r
- \r
- <span class="networkselection">\r
-<?php if(isset($_GET['server'])){ ?>\r
- <input type="hidden" class="network" value="<?php if(isset($_GET['server'])) echo htmlentities($_GET['server']); ?>" />\r
-<?php } else { ?>\r
- <label for="network">Network</label>\r
- <select class="network">\r
- <option value="irc.anonnet.org">AnonNet</option>\r
- <option value="irc.freenode.net">Freenode</option>\r
- <option value="irc.dal.net">DALnet</option>\r
- \r
- </select>\r
-<?php } ?>\r
- </span>\r
- <button type="submit">Connect</button>\r
- </form>\r
- </div>\r
- \r
- \r
- \r
- \r
- <div class="windowlist">\r
- <ul></ul>\r
- <div class="poweredby">Powered by kiwi</div>\r
- </div>\r
- \r
- <div class="userlist">\r
- <ul></ul>\r
- </div>\r
- \r
- \r
- <div class="control">\r
- <div class="msginput">\r
- <div class="nick"><a href="#"></a>:</div>\r
- <input type="text" name="kiwi_msginput" id="kiwi_msginput" />\r
- </div>\r
- <div class="plugins">\r
- <ul>\r
- <li><a class="load_plugin_file">Load plugin file</a></li>\r
- </ul>\r
- </div>\r
- </div>\r
-</div>\r
-\r
-</body>\r
-</html>\r
+++ /dev/null
-<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">\r
-<html xmlns="http://www.w3.org/1999/xhtml">\r
-<head>\r
-<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />\r
-<title>Welcome page</title>\r
-<style type="text/css" media="screen">\r
-body { background: #e7e7e7; font-family: Verdana, sans-serif; font-size: 11pt; }\r
-#page { background: #ffffff; margin: 50px; border: 2px solid #c0c0c0; padding: 10px; }\r
-#header { background: #4b6983; border: 2px solid #7590ae; text-align: center; padding: 10px; color: #ffffff; }\r
-#header h1 { color: #ffffff; }\r
-#body { padding: 10px; }\r
-span.tt { font-family: monospace; }\r
-span.bold { font-weight: bold; }\r
-a:link { text-decoration: none; font-weight: bold; color: #C00; background: #ffc; }\r
-a:visited { text-decoration: none; font-weight: bold; color: #999; background: #ffc; }\r
-a:active { text-decoration: none; font-weight: bold; color: #F00; background: #FC0; }\r
-a:hover { text-decoration: none; color: #C00; background: #FC0; }\r
-</style>\r
-</head>\r
-<body>\r
-<div id="page">\r
- <div id="header">\r
- <h1> Placeholder page </h1>\r
- The owner of this web site has not put up any web pages yet. Please come back later.\r
- </div>\r
- <div id="body">\r
- <h2>You should replace this page with your own web pages as soon as possible.</h2>\r
- Unless you changed its configuration, your new server is configured as follows:\r
- <ul>\r
- <li>Configuration files can be found in <span class="tt">/etc/lighttpd</span>. Please read <span class="tt">/etc/lighttpd/conf-available/README</span> file.</li>\r
- <li>The DocumentRoot, which is the directory under which all your HTML files should exist, is set to <span class="tt">/var/www</span>.</li>\r
- <li>CGI scripts are looked for in <span class="tt">/usr/lib/cgi-bin</span>, which is where Ubuntu packages will place their scripts. You can enable cgi module by using command <span class="bold tt">"lighty-enable-mod cgi"</span>.</li>\r
- <li>Log files are placed in <span class="tt">/var/log/lighttpd</span>, and will be rotated weekly. The frequency of rotation can be easily changed by editing <span class="tt">/etc/logrotate.d/lighttpd</span>.</li>\r
- <li>The default directory index is <span class="tt">index.html</span>, meaning that requests for a directory <span class="tt">/foo/bar/</span> will give the contents of the file /var/www/foo/bar/index.html if it exists (assuming that <span class="tt">/var/www</span> is your DocumentRoot).</li>\r
- <li>You can enable user directories by using command <span class="bold tt">"lighty-enable-mod userdir"</span></li>\r
- </ul>\r
- <h2>About this page</h2>\r
- <p>\r
- This is a placeholder page installed by the Ubuntu release of the <a href="http://packages.ubuntu.com/lighttpd">Lighttpd server package.</a>\r
- </p>\r
- <p>\r
- This computer has installed the Ubuntu operating system, but it has nothing to do with the Ubuntu Project. Please do not contact the Ubuntu Project about it.\r
- </p>\r
- <p>\r
- If you find a bug in this Lighttpd package, or in Lighttpd itself, please file a bug report on it. Instructions on doing this, and the list of known bugs of this package, can be found in the \r
- <a href="https://bugs.launchpad.net/ubuntu/+source/lighttpd/">Ubuntu Bug Tracking System.</a>\r
- </p>\r
- <p>\r
- <a href="http://validator.w3.org/check?uri=referer"><img\r
- src="http://www.w3.org/Icons/valid-xhtml10"\r
- alt="Valid XHTML 1.0 Transitional" height="31" width="88" border="0" /></a>\r
- </p> \r
- </div>\r
-</div>\r
-<!-- s:853e9a42efca88ae0dd1a83aeb215047 -->\r
-</body>\r
-</html>\r
+++ /dev/null
-<?php\r
-\r
- switch(true){\r
- case stripos($_SERVER['HTTP_USER_AGENT'], 'android') > 0:\r
- $agent = "android"; $touchscreen = true;\r
- break;\r
- \r
- case stripos($_SERVER['HTTP_USER_AGENT'], 'iphone') > 0:\r
- $agent = "iphone"; $touchscreen = true;\r
- break;\r
- \r
- case stripos($_SERVER['HTTP_USER_AGENT'], 'ipod') > 0:\r
- $agent = "ipod"; $touchscreen = true;\r
- break;\r
- \r
- case stripos($_SERVER['HTTP_USER_AGENT'], 'ipad') > 0:\r
- $agent = "ipad"; $touchscreen = true;\r
- break;\r
- \r
- default:\r
- $agent = "normal";\r
- $touchscreen = false;\r
- }\r
-?>\r
-<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">\r
-<html xmlns="http://www.w3.org/1999/xhtml">\r
-<head>\r
-<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />\r
-\r
-<?php if(in_array($agent, array("android", "ipad", "iphone", "ipad"))){ ?>\r
-<meta name="viewport" content="width=device-width,user-scalable=no" />\r
-<?php } ?>\r
-\r
-<title>kiwi</title>\r
-<link rel="stylesheet" type="text/css" href="css/default.css">\r
-<link rel="stylesheet" type="text/css" href="css/ui.css">\r
-\r
-<?php if($touchscreen){ ?>\r
-<link rel="stylesheet" type="text/css" href="css/touchscreen_tweaks.css">\r
-<?php } ?>\r
-\r
-\r
-<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.3/jquery.min.js"></script>\r
-<script type="text/javascript" src="js/jquery.json-2.2.min.js"></script>\r
-<script type="text/javascript" src="js/util.js"></script>\r
-<script type="text/javascript" src="js/gateway.js"></script>\r
-<script type="text/javascript" src="js/front.js"></script>\r
-\r
-<?php if(in_array($agent, array("android", "ipad", "iphone", "ipad"))){ ?>\r
-<script type="text/javascript" src="js/touchscreen_tweaks.js"></script>\r
-<?php } ?>\r
-\r
-<script type="text/javascript">\r
- var agent = '<?= $agent ?>';\r
- var touchscreen = <?= ($touchscreen) ? 'true' : 'false' ?>;\r
- var init_data = {};\r
- \r
- $(document).ready(function(){\r
- if(touchscreen) $('#kiwi').addClass('touchscreen');\r
- \r
- //#nick@irc.anonnet.org:6679+/#channel,##channel,&channel\r
- var chans = document.location.hash.match(/[#&]+[^ ,\007]+/g);\r
- if(chans != null && chans.length > 0) { init_data.channel = chans.join(','); }\r
- \r
- front.init();\r
- });\r
-</script>\r
-\r
-</head>\r
-\r
-<body>\r
-\r
-<div id="kiwi">\r
- <div class="box about">\r
- <h2>kiwi</h2>\r
- <p>An alternative to downloading an irc client. This web app is the best thing you'll use in the next couple years.</p>\r
- <button class="about_close">Close</button>\r
- </div>\r
- \r
- <div class="connectwindow">\r
- <form class="formconnectwindow">\r
- <label for="nick">Nick</label>\r
- <input type="text" class="nick" value="<?php if(isset($_GET['nick'])) echo htmlentities($_GET['nick']); ?>" /><br />\r
- \r
- <span class="networkselection">\r
-<?php if(isset($_GET['server'])){ ?>\r
- <input type="hidden" class="network" value="<?php if(isset($_GET['server'])) echo htmlentities($_GET['server']); ?>" />\r
-<?php } else { ?>\r
- <label for="network">Network</label>\r
- <select class="network">\r
- <?php if(1==1){ echo '<option value="irc.anonnet.org">AnonNet</option>'; } ?>\r
- <option value="irc.freenode.net">Freenode</option>\r
- <option value="irc.dal.net">DALnet</option>\r
- \r
- </select>\r
-<?php } ?>\r
- </span>\r
- <button type="submit">Connect</button>\r
- </form>\r
- </div>\r
- \r
- \r
- \r
- <div class="windowlist">\r
- <div class="poweredby">Powered by kiwi</div>\r
- <ul></ul>\r
- </div>\r
- \r
- <div class="userlist">\r
- <ul></ul>\r
- </div>\r
- \r
- <div class="cur_topic"></div>\r
- \r
- <div class="control">\r
- <div class="msginput">\r
- <div class="nick"><a href="#"></a>:</div>\r
- <input type="text" name="kiwi_msginput" id="kiwi_msginput" />\r
- </div>\r
- <div class="plugins">\r
- <ul>\r
- <li><a class="load_plugin_file">Load plugin file</a></li>\r
- <li><a class="reload_css">Reload CSS</a></li>\r
- </ul>\r
- </div>\r
- </div>\r
-</div>\r
-\r
-</body>\r
-</html>
\ No newline at end of file
+++ /dev/null
-<?php\r
- print_r($_SERVER);\r
- exit;\r
- echo `whoami`;\r
-phpinfo();\r
+++ /dev/null
-<?php\r
-\r
- /*\r
- * CASE: Page requested to start a session.\r
- * 1. Attempt connect to the server\r
- * Fail?\r
- * End session and send error to the client\r
- * Connected?\r
- * Create a listening UNIX socket and send OK to the client\r
- *\r
- * 2. Run the IRC client class as normal, while polling for connections\r
- * on the listening socket. Save any messages for the web client into\r
- * a buffer.\r
- * This is the normal running state.\r
- *\r
- * 3. Upon a connection on the UNIX socket, send the oldest message from\r
- * the buffer to the web client, FIFO style and close the connection.\r
- */\r
- \r
- // If -d has been sent to start this session, start in debug mode\r
- if(in_array('-d', $argv)){\r
- define('DEBUG', true);\r
- } else {\r
- define('DEBUG', false);\r
- }\r
- \r
- \r
- require(dirname(__FILE__).'/config.php');\r
- require(dirname(__FILE__).'/common.php');\r
- require(dirname(__FILE__).'/class_session.php');\r
- require(dirname(__FILE__).'/class_irc.php');\r
- require(dirname(__FILE__).'/class_ircconnection.php');\r
- require(dirname(__FILE__).'/ircd_profiles/hybrid.php');\r
- \r
- \r
- // Make sure a session id has been specified\r
- if(!isset($argv[1]) || empty($argv[1]))\r
- die('no_session');\r
- \r
- $session_id = $argv[1];\r
- $host_key = $argv[2]; // The remote host key in memcached\r
- \r
- // Process any arguments\r
- $app_args = array();\r
- foreach($argv as $a){\r
- $value = substr($a, 2);\r
- switch(substr($a, 0, 2)){\r
- case '-h':\r
- // Client host\r
- $app_args['remote_host'] = $value;\r
- break;\r
- }\r
- }\r
- \r
- \r
- // Start the unix session, and if it fails quit here\r
- $ipc_srv = SESSIONS::clStart($session_id);\r
- if($ipc_srv === false) die("fail '$session_id' '$host_key'");\r
- \r
- // Debug mode runs in terminal to see output\r
- if(!DEBUG){\r
- // See if we can fork our process..\r
- $pid = pcntl_fork();\r
- if($pid === -1){\r
- die('Forking error');\r
- }elseif($pid){\r
- // Parent process\r
- die('ok');\r
- }else{\r
- // Child process\r
- fclose(STDOUT);\r
- }\r
- }\r
- \r
- //posix_setsid();\r
-\r
- \r
- \r
- ############################################\r
- ## Main process\r
- ############################################\r
- \r
- $old_error_handler = set_error_handler("errorHandler");\r
- \r
- $bot = null; // The IRC connection\r
- $ipc = array(); // The IPC connections to the web clients\r
- $ipc_read = array(); // The IPC connections wanting to read the buffer\r
- $buffer = array(); // Messages to be sent to the web client\r
- $send_debug = false;\r
- \r
- deb("Starting $session_id");\r
- \r
- $timeout = time();\r
- $timeout_timer = 0;\r
- while(true){\r
- // If there are no webclients connected, start the timer to disconnect\r
- if(!count($ipc)){\r
- if($timeout == 0) $timeout = time();\r
- $timeout_timer = time() - $timeout;\r
- if($timeout_timer >= $config['timeout']) break;\r
- } else {\r
- $timeout = 0;\r
- }\r
- \r
- processClients();\r
- \r
- if($bot != null){\r
- // $bot handles the sleep time here\r
- $bot->Process();\r
- } else {\r
- usleep(5000);\r
- }\r
- }\r
- \r
- \r
- // We've quit, lower the counter for this host\r
- if($config['memcache_use']){\r
- @GLOB::$mc->decrement($host_key);\r
- }\r
- \r
- deb('Exiting client');\r
- \r
- \r
- ############################################\r
- ## Functions / Classes\r
- ############################################\r
- \r
- \r
- \r
- function processClients(){\r
- global $ipc_srv;\r
- global $ipc;\r
- global $ipc_read;\r
- global $buffer;\r
- global $timeout;\r
- \r
- // Check for any new web client connections...\r
- $read = array($ipc_srv);\r
- $write = $excep = array();\r
- $read_changed = stream_select($read, $write, $excep, 0);\r
- for($i=0; $i<$read_changed; $i++) {\r
- if($read[$i] === $ipc_srv){\r
- $ipc[] = stream_socket_accept($ipc_srv);\r
- deb("Connection...");\r
- }\r
- }\r
- \r
- \r
- // Check for any changed web clients..\r
- $read = $ipc;\r
- $read_changed = (count($read)) ? stream_select($read, $write, $excep, 0) : array();\r
- if($read_changed){\r
- foreach($read as $cl){\r
- $data = fread($cl, 1024);\r
- if(!$data){\r
- // Web client has disconnected\r
- deb("Removing closed socket..");\r
- $key = array_search($cl, $ipc);\r
- unset($ipc[$key]);\r
- \r
- $key = array_search($cl, $ipc_read);\r
- if($key !== false) unset($ipc_read[$key]);\r
- } else {\r
- //deb('Got data: '.$data);\r
- processClientMessage($data, $cl);\r
- }\r
- }\r
- }\r
- \r
- \r
- \r
- // Send the buffer messages to any connected web clients..\r
- // 1 message at a time...\r
- if(count($buffer) && count($ipc_read)){\r
- //deb(print_r($ipc_read, 1));\r
- $msg = array_shift($buffer);\r
- //deb("Sending '$msg' to ".count($ipc_read)." clients..");\r
- foreach($ipc_read as $cl){\r
- if($cl) fwrite($cl, $msg."\n");\r
- }\r
- }\r
- \r
- // The whole buffer at a time...\r
- /*\r
- while(count($buffer)){\r
- $msg = array_shift($buffer);\r
- foreach($ipc as $cl) frwite($cl, $msg);\r
- }\r
- */\r
- \r
- }\r
- \r
- \r
- function processClientMessage($data, $cl){\r
- global $config;\r
- global $buffer;\r
- global $bot, $ipc_read;\r
- global $timeout;\r
- global $send_debug;\r
- global $app_args;\r
- \r
- require('dev_processClientMessage.php');\r
- return true;\r
- }\r
- \r
- \r
- \r
- \r
- function errorHandler($errno, $errstr, $errfile, $errline){\r
- $ret = '';\r
- switch ($errno) {\r
- case E_USER_ERROR:\r
- $ret .= "USER [$errno] $errstr\n";\r
- $ret .= " Fatal error on line $errline in file $errfile";\r
- $ret .= ", PHP " . PHP_VERSION . " (" . PHP_OS . ")\n";\r
- $ret .= "Aborting...<br />\n";\r
- exit(1);\r
- break;\r
-\r
- case E_USER_WARNING:\r
- $ret .= "WARNING on line $errline in file $errfile: [$errno] $errstr\n";\r
- break;\r
-\r
- case E_USER_NOTICE:\r
- $ret .= "NOTICE on line $errline in file $errfile: [$errno] $errstr\n";\r
- break;\r
-\r
- default:\r
- $ret .= "UNKOWN ERR on line $errline in file $errfile: [$errno] $errstr\n";\r
- break;\r
- }\r
- \r
- if(!empty($ret)) deb($ret); \r
- \r
- \r
- /* Don't execute PHP internal error handler */\r
- return true;\r
- }
\ No newline at end of file
+++ /dev/null
-var front = {
- cur_channel: '',
- windows: {},
-
-
- init: function(){
- front.registerKeys();
-
- gateway.nick = 'kiwiclone';
- gateway.session_id = null;
- gateway.onMsg = front.onMsg;
- gateway.onNotice = front.onNotice;
- gateway.onMOTD = front.onMOTD;
- gateway.onConnect = front.onConnect;
- gateway.onUserList = front.onUserList;
-
- front.doLayout();
- front.windowAdd('server');
- gateway.poll();
- },
-
- doLayout: function(){
- $('#kiwi .msginput .nick a').text(gateway.nick);
- },
-
-
- onMsg: function(data){
- front.addMsg(null, data.nick,data.msg,data.channel);
- },
- onNotice: function(data){
- front.addMsg(null, data.nick, '--> '+data.msg);
- },
- onConnect: function(data){
- if(data.connected){
- front.addMsg(null, ' ', '--> Connected to '+data.host);
- } else {
- front.addMsg(null, ' ', '--> Failed to connect to '+data.host);
- }
- },
- onMOTD: function(data){
- front.addMsg(null, data.server, data.msg);
- },
- onUserList: function(data){
- $.each(data.users, function(i,item){
- $('<li>'+i+'</li>').appendTo('#kiwi .userlist ul');
- });
- },
-
- registerKeys: function(){
- $('input').keypress(function(e){
- if(e.which == 13){
- var msg = $('#kiwi_msginput').val();
- if(msg.substring(0,1) == '/'){
- var parts = msg.split(' ');
- switch(parts[0]){
- case '/join':
- if(front.windows[parts[1]] == undefined){
- gateway.join(parts[1].replace('#', ''));
- front.windowAdd(parts[1]);
- } else {
- front.windowShow(parts[1]);
- }
- break;
-
- case '/connect':
- if(parts[1] == undefined){
- alert('Usage: /connect servername [port]');
- break;
- }
-
- if(parts[2] == undefined) parts[2] = 6667;
- front.addMsg(null, ' ', '--> Connecting to '+parts[1]+'...');
- gateway.connect(parts[1], parts[2], 0);
- break;
-
- default:
- front.addMsg(null, ' ', '--> Invalid command: '+parts[0].substring(1));
- }
-
- } else {
- gateway.msg(front.cur_channel, msg);
- var d = new Date();
- var d = d.getHours() + ":" + d.getMinutes();
- front.addMsg(d, gateway.nick, msg);
- }
- $('#kiwi_msginput').val('');
- }
- });
- },
-
-
-
- addMsg: function(time, nick, msg, channel){
- var html_nick = $('<div/>').text(nick).html();
- var html_msg = $('<div/>').text(msg).html()+' '; // Add the space so the styling always has at least 1 character to go from
- if(time == null){
- var d = new Date();
- time = d.getHours() + ":" + d.getMinutes();
- }
-
- var msg = '<div class="msg"><div class="time">'+time+'</div><div class="nick">'+html_nick+'</div><div class="text">'+html_msg+'</div></div>';
- if(channel == undefined){
- var messages = $("#kiwi_window_server");
- } else {
- var messages = $("#kiwi_window_chan_"+channel.replace('#', ''));
- }
- messages.append(msg);
- messages.attr({ scrollTop: messages.attr("scrollHeight") });
- },
-
-
-
- windowExists: function(name){
- return !(front.windows[name] == undefined);
- },
- windowAdd: function(v_name){
- var tmp_divname = 'kiwi_window_'+v_name.replace('#', 'chan_');
- front.windows[v_name] = { name: v_name, div_id: tmp_divname };
- $('#kiwi').append('<div id="'+tmp_divname+'"class="messages"></div>');
- $('#kiwi .windowlist ul').append('<li class="window_'+v_name+'"><a onclick="front.windowShow(\''+v_name+'\');">'+v_name+'</a></li>');
- //$('#kiwi .windowlist ul .window_'+v_name).click(function(){ front.windowShow(v_name); });
- front.windowShow(v_name);
-
- /*
- var t = "";
- for (key in front.windows)
- t += "Element value is " + front.windows[key].div_id + "\n";
-
- alert(t);
- */
- },
- windowDiv: function(name){
- if(!front.windowExists(name)) return false;
- return $('#'+front.windows[name].div_id);
- },
- windowShow: function(name){
- if(!front.windowExists(name)) return false;
- $('#kiwi .messages').removeClass("active");
- var tmp = front.windowDiv(name);
- tmp.addClass('active');
- front.cur_channel = name;
- }
-}
\ No newline at end of file
+++ /dev/null
-<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">\r
-<html xmlns="http://www.w3.org/1999/xhtml">\r
-<head>\r
-<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />\r
-<title>Kiwi IRC</title>\r
-<style type="text/css">\r
-* { margin:0px; padding:0px; }\r
-body {\r
- background:#1b1b1b;\r
- font: 14px Tahoma, Geneva, sans-serif;\r
- color: #D4D4D4;\r
- height:100%;\r
-}\r
-\r
-a {\r
- color: #8D9713;\r
- text-decoration:none;\r
-}\r
-\r
-\r
-\r
-.logo { display:block; width:264px; height:90px; text-indent:-1000px; margin:70px auto 100px; background:url(img/logo.png) no-repeat; }\r
-#login { width:665px; margin:0px auto; }\r
-#login ul { list-style:none; }\r
-#login ul li { overflow:hidden; margin-bottom:10px; }\r
-#login ul li label { float:left; text-align:right; padding-right:.5em; }\r
-#login input { border:none; }\r
-#login .more { border-top: 1px dotted #888888; }\r
-#login .more_link {\r
- font-size:12px;\r
- position:relative;\r
- top:-16px;\r
- background: url(img/more.png) no-repeat right 5px;\r
- padding-right: 12px;\r
- color:#888;\r
-}\r
-\r
-#login .content.top {\r
- width:470px;\r
- margin:30px auto 60px;\r
-}\r
-#login .content.top ul { font-size:27px; }\r
-#login .content.top label { width:40%; }\r
-#login .content.top input {\r
- width:240px; padding:.2em .5em;\r
- font-size:.8em; text-align:center;\r
- background:#D4D4D4;\r
- border-radius:8px; -moz-border-radius:8px;\r
-}\r
-#login .content.top a { display:block; text-align:right; font-size:22px; margin-top:30px; }\r
-\r
-#login .content.bottom { width:350px; margin:30px auto; display:none; }\r
-#login .content.bottom ul { font-size:20px; }\r
-#login .content.bottom label { width:25%; }\r
-#login .content.bottom input { width:216px; font-size:.8em; no-repeat; padding:.2em .5em; background:#D4D4D4; border-radius:8px; -moz-border-radius:8px; }\r
-#login .content.bottom a { display:block; text-align:right; font-size:16px; margin-top:30px; }\r
-</style>\r
-\r
-<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.3/jquery.min.js"></script>\r
-<script type="text/javascript"> \r
- \r
- $(document).ready(function(){\r
- addEvents();\r
- $('.nick').focus();\r
- });\r
- \r
- \r
- function addEvents(){\r
- $('.more_link').click(function(){ $('.content.bottom').slideDown('fast'); $('.network').focus(); return false; });\r
- $('.formconnectwindow').submit(function(){ alert("logging in.."); return false; });\r
- $('a.connect').click(function(){ $('.formconnectwindow').submit(); return false; });\r
- }\r
-</script>\r
-</head>\r
-\r
-<body>\r
-\r
-<div class="connectwindow">\r
- <h1 class="logo">Kiwi IRC</h1>\r
- <div id="login">\r
- <form class="formconnectwindow">\r
- <div class="content top">\r
- <ul>\r
- <li><label for="nick">Your nickname:</label>\r
- <input type="text" id="nick" name="nick" class="nick" /></li>\r
- </ul>\r
- <a class="connect" href="">Connect »</a>\r
- </div>\r
- \r
- <div class="more">\r
- <a href="" class="more_link">More</a>\r
- <div class="content bottom">\r
- <ul>\r
- <li><label for="network">Server:</label>\r
- <input type="text" id="network" name="network" class="network" value="irc.anonnet.org" /></li>\r
- <li><label for="channel">Channel:</label>\r
- <input type="text" id="channel" name="channel" class="channel" value="#kiwi" /></li>\r
- </ul>\r
- <a class="connect" href="">Connect »</a>\r
- </div>\r
- </div>\r
- </form>\r
- </div>\r
-</div>\r
-\r
-</body>\r
-</html>\r
+++ /dev/null
-<?php\r
- \r
- require(dirname(__FILE__).'/config.php');\r
- require(dirname(__FILE__).'/common.php');\r
- require(dirname(__FILE__).'/class_session.php');\r
- \r
- $starttime = time();\r
- \r
- ############################################\r
- ## New sessions\r
- ############################################\r
- \r
- // If no session has been specified, start a new one\r
- if(empty($_POST)){\r
- $new_session = SESSIONS::create($_SERVER['REMOTE_ADDR']);\r
- \r
- // Session creation fail?\r
- if($new_session === false){\r
- die(gen_response(array('error'=>'session_error')));\r
- }\r
- \r
- // Session create OK, yay\r
- die(gen_response(array('session_id'=>$new_session)));\r
- }\r
- \r
- \r
- \r
- ############################################\r
- ## Existing sessions\r
- ############################################\r
- \r
- // Quit here if a session hasn't been specified\r
- if(!isset($_POST['sid']) || empty($_POST['sid'])){\r
- die(gen_response(array('error'=>'session_not_set')));\r
- }\r
- \r
- $session_id = $_POST['sid'];\r
- \r
- // Make sure the session exists\r
- if(!SESSIONS::exists($session_id)){\r
- die(gen_response(array('error'=>'no_session')));\r
- }\r
- \r
- // Connect to the IRC session\r
- $ses = SESSIONS::open($session_id);\r
- if(!$ses){\r
- die(gen_response(array('error'=>'session_error')));\r
- }\r
- \r
- if(!isset($_POST['data'])){\r
- // Read any commands to be sent to the web client\r
- $data = array();\r
- \r
- /* This was used for blocking the first call which caused a wait of timeout seconds if the user quits\r
- // Make this read block\r
- $tmp = json_decode(trim(SESSIONS::read($ses, true)),1);\r
- if($tmp != null) $data[] = $tmp;\r
- */\r
- \r
- // Unblocked reads just incase only 1 message is actually available\r
- $start_time = time();\r
- while(time() - $start_time < $config['max_time_per_poll'] && count($data) == 0 && !connection_aborted()){\r
- for($i=0; $i<$config['messages_per_poll']; $i++){\r
- if(connection_aborted()){\r
- deb("Connection aborted");\r
- break;\r
- }\r
- deb("Polling..");\r
- $tmp = json_decode(trim(SESSIONS::read($ses, false)),1);\r
- if($tmp != null){\r
- $data[] = $tmp;\r
- } else {\r
- break;\r
- }\r
- \r
- echo " ";\r
- flush();\r
- }\r
- \r
- if(count($data) == 0) sleep(1);\r
- }\r
- deb("Polled");\r
- \r
- if(!empty($data)){\r
- echo gen_response($data);\r
- } else {\r
- echo gen_response(array());\r
- }\r
- } else {\r
- fwrite($ses, $_POST['data']);\r
- }\r
- \r
- // We're done here, close the session connection\r
- SESSIONS::close($ses);\r
- \r
- \r
- \r
- \r
- \r
- \r
- \r
- \r
- \r
- ############################################\r
- ## Functions\r
- ############################################\r
- \r
- function gen_response($data){\r
- return json_encode($data);\r
- }\r
+++ /dev/null
-<html>\r
-\r
-<head>\r
-<script type="text/javascript">\r
-\r
- var init_data = {};\r
-\r
-\r
- //#nick@irc.anonnet.org:6679+/#channel,##channel,&channel\r
- var con_string = 'nick@irc.anonnet.org:6679+/#channel,##channel,&channel';\r
- var chans = con_string.match(/[#&]+[^ ,\007]+/g);\r
- var addr = con_string.match(/[A-Za-z0-9.-]+(:\d+\+?)?/);\r
-\r
- var parts = con_string.match(/^(([A-Za-z0-9-_\[\]<>]+)@)?([A-Za-z0-9.-]+(:\d+\+?)?)([#&]+[^ ,\007]+)/);\r
- //alert(parts);\r
- \r
- alert('nick="'+parts[2]+'"');\r
- alert('server="'+parts[3]+'"');\r
- alert('channels="'+parts[5]+'"');\r
-</script>\r
-\r
-</head>\r
-\r
-<body></body>\r
-</html>
\ No newline at end of file
+++ /dev/null
-<script>\r
-alert(typeof WebSocket);\r
-/*\r
-var conn = new WebSocket("ws://wuthost.net:7777/~wok/miblol/sessionname");\r
-conn.onopen = function(evt) { alert("Conn opened"); }\r
-conn.onread = function(evt) { alert("Read: " + evt.data); }\r
-conn.onclose = function(evt) { alert("Conn closed"); }\r
-\r
-conn.send("Hello World")\r
-*/\r
-</script>
\ No newline at end of file
+++ /dev/null
-<?php\r
- \r
- /*\r
- * This script takes a WebSocket connection from a web client, creates a\r
- * new session and simply proxies the data between the 2 connections. No\r
- * data processing is done here at all.\r
- * \r
- */\r
- \r
- \r
- $msg = <<<MSG\r
- \r
- \r
-######################################################\r
- Lol, Kiwi websocket support is starting.\r
-\r
- Support: support@kiwiirc.com\r
-######################################################\r
-\r
-MSG;\r
- echo $msg;\r
- \r
- \r
- $debug = true;\r
- \r
- // Stores the sockets in pairs, websocket=>ircsocket\r
- $pairs = array();\r
- \r
- // Stores all sockets\r
- $soks = array();\r
- \r
- // Handshaken sockets\r
- $handshakes = array();\r
-\r
- \r
- \r
- require(dirname(__FILE__).'/config.php');\r
- require(dirname(__FILE__).'/common.php');\r
- require(dirname(__FILE__).'/class_session.php');\r
- \r
- \r
- error_reporting(E_ALL);\r
- set_time_limit(0);\r
- ob_implicit_flush();\r
- \r
- $server = WebSocket($config['websocket']['bind_addr'], $config['websocket']['bind_port']);\r
- $soks[(int)$server] = $server;\r
- $last_dump = 0;\r
- while(1){\r
- echo time()." - $last_dump (".(time() - $last_dump).")\n";\r
- if(time() - $last_dump >= 3){\r
- $last_dump = time();\r
- echo "\nPairs: ";\r
- var_dump($pairs);\r
- \r
- echo "\nSoks: ";\r
- var_dump($soks);\r
- }\r
- \r
- $changed = $soks;\r
- stream_select($changed, $write=NULL, $except=NULL, NULL);\r
- \r
- foreach($changed as $socket){\r
- // New connection?\r
- if($socket == $server){\r
- $client = stream_socket_accept($server);\r
- if($client<0){\r
- console("socket_accept() failed"); continue;\r
- } else {\r
- connect($client);\r
- }\r
- } else {\r
- \r
- $buffer = fread($socket, 2048);\r
- if($buffer === false || $buffer == ''){\r
- // Disconnected\r
- disconnect($socket);\r
- } else {\r
- //$buffer = substr($buffer, 0, strlen($buffer));\r
- //console("INCOMING:\n".$buffer."########\n");\r
- if(isset($handshakes[(int)$socket])){\r
- // websocket upgrade\r
- dohandshake($socket, $buffer);\r
- } else {\r
- // Data transfering..\r
- transfer($socket, $buffer);\r
- }\r
- }\r
- \r
- }\r
- }\r
- }\r
- \r
- \r
- \r
- \r
- function WebSocket($address,$port){\r
- //$master=socket_create(AF_INET, SOCK_STREAM, SOL_TCP) or die("socket_create() failed");\r
- $master = stream_socket_server("tcp://$address:$port") or die("socket_create() failed");\r
- //socket_set_option($master, SOL_SOCKET, SO_REUSEADDR, 1) or die("socket_option() failed");\r
- //socket_bind($master, $address, $port) or die("socket_bind() failed");\r
- //socket_listen($master,20) or die("socket_listen() failed");\r
- echo "Server Started : ".date('Y-m-d H:i:s')."\n";\r
- echo "Master socket : ".$master."\n";\r
- echo "Listening on : ".$address." port ".$port."\n\n";\r
- return $master;\r
- }\r
- \r
- \r
- \r
- \r
- \r
- function connect($socket){\r
- global $soks, $pairs, $handshakes;\r
-\r
- //$session_id = SESSIONS::create();\r
- //if(!$session_id) return false;\r
- \r
- //$pairs[$socket]= SESSION::open($session_id);\r
-\r
- $soks[(int)$socket] = $socket;\r
- $handshakes[(int)$socket] = false;\r
- //array_push($soks, $pairs[$socket]);\r
- \r
- console($socket." connection..");\r
- }\r
-\r
- function disconnect($sok){\r
- global $soks, $pairs;\r
- console("disconnected?\n");\r
- \r
- $pair = findPair($sok);\r
- if($pair === false) return false;\r
- foreach($pair as $websocket => $local_con){ \r
- @fclose($soks[$websocket]);\r
- unset($soks[$websocket]);\r
- \r
- @fclose($soks[$local_con]);\r
- unset($soks[$local_con]);\r
- \r
- unset($pairs[$websocket]);\r
- }\r
- \r
- console($sok." DISCONNECTED!");\r
- }\r
- \r
- function transfer($sok, $buffer){\r
- global $soks, $pairs;\r
- console("Transfering data?\n");\r
- \r
- $pair = findPair($sok);\r
- if($pair === false) return false;\r
- \r
- console("Transfering ".strlen($buffer)." bytes.. '".$buffer."'");\r
- //$buffer = wrap($buffer);\r
- foreach($pair as $websocket => $local_con){\r
- if($sok == $soks[$websocket]){\r
- // From websocket..\r
- fwrite($soks[$local_con], unwrap($buffer));\r
- break;\r
- } elseif($sok == $soks[$local_con]){\r
- // From irc client\r
- fwrite($soks[$websocket], chr(0).$buffer.chr(255));\r
- break;\r
- }\r
- }\r
- }\r
- \r
- function findPair($socket){\r
- global $soks, $pairs;\r
- console("Finding pair: ".(int)$socket."\n");\r
- \r
- // If it's a websocket, then this will find it..\r
- if(isset($pairs[(int)$socket]))\r
- return array((int)$socket=>$pairs[(int)$socket]);\r
- \r
- // If it's an irc client socket, then we will find it when flipped..\r
- $flipped = array_flip($pairs);\r
- if(isset($flipped[(int)$socket]))\r
- return array($flipped[(int)$socket] => (int)$socket);\r
- \r
- return false;\r
- }\r
-\r
- function dohandshake($sok, $buffer){\r
- global $handshakes, $soks, $pairs;\r
- console("\nRequesting handshake...");\r
- \r
- console("Handshaking...");\r
- /*\r
- list($resource, $host, $origin) = getheaders($buffer);\r
- $upgrade = "HTTP/1.1 101 Web Socket Protocol Handshake\r\n" .\r
- "Upgrade: WebSocket\r\n" .\r
- "Connection: Upgrade\r\n" .\r
- "WebSocket-Origin: " . $origin . "\r\n" .\r
- "WebSocket-Location: ws://" . $host . $resource . "\r\n" .\r
- "\r\n";\r
- */\r
- if(!strpos($buffer, 'WebSocket-Key1:')){\r
- $upgrade = (string)new WebSocket75($buffer);\r
- } else {\r
- $upgrade = (string)new WebSocket76($buffer);\r
- }\r
- \r
- fwrite($sok, $upgrade.chr(0));\r
- \r
- // Done the handshake so remove it from the handshaking array\r
- unset($handshakes[(int)$sok]);\r
- \r
- console("Done handshaking...");\r
- \r
- //socket_getsockname($sok, $sok_name);\r
- $sok_name = stream_socket_get_name($sok, true);\r
- $session_id = SESSIONS::create($sok_name);\r
- if(!$session_id) return false;\r
- $irc_client_sok = SESSIONS::open($session_id);\r
- \r
- $soks[(int)$irc_client_sok] = $irc_client_sok;\r
- $pairs[(int)$sok] = (int)$irc_client_sok;\r
- \r
- fwrite($irc_client_sok, json_encode(array('method'=>'read')));\r
- \r
- console($sok." CONNECTED!");\r
- return true;\r
- }\r
- \r
- \r
- \r
- \r
- \r
- class WebSocket75 {\r
- private $__value__;\r
- \r
- public function __toString() {\r
- return $this->__value__;\r
- }\r
- \r
- public function __construct($buffer){\r
- list($resource, $host, $origin) = $this->getheaders($buffer);\r
- $upgrade = "HTTP/1.1 101 Web Socket Protocol Handshake\r\n" .\r
- "Upgrade: WebSocket\r\n" .\r
- "Connection: Upgrade\r\n" .\r
- "WebSocket-Origin: " . $origin . "\r\n" .\r
- "WebSocket-Location: ws://" . $host . $resource . "\r\n" .\r
- "\r\n";\r
- \r
- $this->__value__ = $upgrade;\r
- }\r
- \r
- private function getheaders($req){\r
- $r=$h=$o=null;\r
- if(preg_match("/GET (.*) HTTP/" ,$req,$match)){ $r=$match[1]; }\r
- if(preg_match("/Host: (.*)\r\n/" ,$req,$match)){ $h=$match[1]; }\r
- if(preg_match("/Origin: (.*)\r\n/",$req,$match)){ $o=$match[1]; }\r
- return array($r,$h,$o);\r
- }\r
- }\r
- \r
- \r
- class WebSocket76 {\r
-\r
- /*! Easy way to handshake a WebSocket via draft-ietf-hybi-thewebsocketprotocol-00\r
- * @link http://www.ietf.org/id/draft-ietf-hybi-thewebsocketprotocol-00.txt\r
- * @author Andrea Giammarchi\r
- * @blog webreflection.blogspot.com\r
- * @date 4th June 2010\r
- * @example\r
- * // via function call ...\r
- * $handshake = WebSocketHandshake($buffer);\r
- * // ... or via class\r
- * $handshake = (string)new WebSocketHandshake($buffer);\r
- *\r
- * socket_write($socket, $handshake, strlen($handshake));\r
- */\r
-\r
- private $__value__;\r
-\r
- public function __construct($buffer) {\r
- $resource = $host = $origin = $key1 = $key2 = $protocol = $code = $handshake = null;\r
- preg_match('#GET (.*?) HTTP#', $buffer, $match) && $resource = $match[1];\r
- preg_match("#Host: (.*?)\r\n#", $buffer, $match) && $host = $match[1];\r
- preg_match("#Sec-WebSocket-Key1: (.*?)\r\n#", $buffer, $match) && $key1 = $match[1];\r
- preg_match("#Sec-WebSocket-Key2: (.*?)\r\n#", $buffer, $match) && $key2 = $match[1];\r
- preg_match("#Sec-WebSocket-Protocol: (.*?)\r\n#", $buffer, $match) && $protocol = $match[1];\r
- preg_match("#Origin: (.*?)\r\n#", $buffer, $match) && $origin = $match[1];\r
- preg_match("#\r\n(.*?)\$#", $buffer, $match) && $code = $match[1];\r
- $this->__value__ =\r
- "HTTP/1.1 101 WebSocket Protocol Handshake\r\n".\r
- "Upgrade: WebSocket\r\n".\r
- "Connection: Upgrade\r\n".\r
- "Sec-WebSocket-Origin: {$origin}\r\n".\r
- "Sec-WebSocket-Location: ws://{$host}{$resource}\r\n".\r
- ($protocol ? "Sec-WebSocket-Protocol: {$protocol}\r\n" : "").\r
- "\r\n".\r
- $this->_createHandshakeThingy($key1, $key2, $code)\r
- ;\r
- }\r
-\r
- public function __toString() {\r
- return $this->__value__;\r
- }\r
- \r
- private function _doStuffToObtainAnInt32($key) {\r
- return preg_match_all('#[0-9]#', $key, $number) && preg_match_all('# #', $key, $space) ?\r
- implode('', $number[0]) / count($space[0]) :\r
- ''\r
- ;\r
- }\r
-\r
- private function _createHandshakeThingy($key1, $key2, $code) {\r
- return md5(\r
- pack('N', $this->_doStuffToObtainAnInt32($key1)).\r
- pack('N', $this->_doStuffToObtainAnInt32($key2)).\r
- $code,\r
- true\r
- );\r
- }\r
- }\r
- \r
- \r
-function say($msg=""){ echo $msg."\n"; }\r
-function wrap($msg=""){ return chr(0).$msg.chr(255); }\r
-function unwrap($msg=""){ return substr($msg,1,strlen($msg)-2); }\r
-function console($msg=""){ global $debug; if($debug){ echo time().' '.trim($msg)."\n"; } }\r