function irc_do($p) { if ($p === FALSE || $p === NULL) { return $p; } if (!is_a($p, 'irc_packet')) { $p = irc_packet::parse($p); } if ($p === FALSE || $p === NULL) { return $p; } switch ($p->cmd) { case 'PRIVMSG': if (!isset($p->args[0]) || !isset($p->args[1])) { return FALSE; } $to = $this->ircchannel2channel($p->args[0]); $fromnick = $this->fullnick2nick($p->prefix); $from = $this->ircchannel2channel($fromnick); if ($to[0] === '/') { // return $this->write_client_irc_from_client('PRIVMSG',array($fromnick,"PMs not supported still")); if (preg_match('/^!complain (.*)$/', $p->args[1], $m)) { $p->args[1] = $this->config['admin'] . ': ' . $m[1]; } $parts = explode(': ', $p->args[1], 2); if (!isset($parts[1]) || !preg_match('#^[ @.]*(.*)$#', $parts[0], $m) || preg_match('/\\s/', $parts[0])) { return $this->write_client_irc_from_client('NOTICE', array($fromnick, "You can chat to cloud users through me. The format is '/path/to/destination: message' :-)")); } $p = $this->udpmsg4_client->send_message($this->unmap_nick($m[1]), $parts[1], $this->unmap_nick($from)); if ($p !== FALSE && !$this->write_hub($p->framed())) { return $this->write_client_irc_from_client('PRIVMSG', array($fromnick, "Your PM to {$parts['0']} failed. Usually this is because that you typed the destination wrong or because that the destination not supports end-to-end encrypted PMs.")); } return TRUE; } $p2 = $this->udpmsg4_client->send_message($this->unmap_nick($to), $p->args[1], $this->unmap_nick($from)); $r = $this->write_hub($p2->framed()); if (!$r) { return $r; } if (preg_match('/^' . $this->config['nick'] . ': kick (.*)/', $p->args[1], $m)) { if (isset($this->config['kickers'][$this->unmap_nick($to)]) && in_array($fromnick, $this->config['kickers'][$this->unmap_nick($to)])) { $this->config['kicked'][$this->unmap_nick($to)][$this->unmap_nick($m[1])] = array('time' => time(), 'kicker' => $p->prefix); return $this->write_client_irc_from_client('PRIVMSG', array($this->channel2ircchannel($to), "kicked")); } else { return $this->write_client_irc_from_client('PRIVMSG', array($this->channel2ircchannel($to), "not a kicker")); } } else { if (preg_match('/^' . $this->config['nick'] . ': kicks( -a)?$/', $p->args[1], $m)) { if (strlen(@$m[1])) { foreach ($this->config['kicked'] as $chan => $kicks) { if (!$this->write_client_irc_from_client('PRIVMSG', array($this->channel2ircchannel($to), "kicks in {$chan}"))) { return FALSE; } foreach ($kicks as $nick => $infos) { if (!$this->write_client_irc_from_client('PRIVMSG', array($this->channel2ircchannel($to), "{$nick} {$infos['kicker']} {$infos['time']}"))) { return FALSE; } } } } else { foreach ($this->config['kicked'][$this->unmap_nick($to)] as $nick => $infos) { if (!$this->write_client_irc_from_client('PRIVMSG', array($this->channel2ircchannel($to), "{$nick} {$infos['kicker']} {$infos['time']}"))) { return FALSE; } } } return TRUE; } } return $r; case 'JOIN': $from = $this->ircchannel2channel($this->fullnick2nick($p->prefix)); foreach (explode(',', $p->args[0]) as $channel) { $p = $this->udpmsg4_client->send_join($this->ircchannel2channel($channel), $this->unmap_nick($from)); if (!$this->write_hub($p->framed())) { return FALSE; } } return TRUE; case 'PART': $from = $this->ircchannel2channel($this->fullnick2nick($p->prefix)); foreach (explode(',', $p->args[0]) as $channel) { $p = $this->udpmsg4_client->send_part($this->ircchannel2channel($channel), @$p->args[1], $this->unmap_nick($from)); if (!$this->write_hub($p->framed())) { return FALSE; } } return TRUE; case 'KICK': $kicker = $this->ircchannel2channel($this->fullnick2nick($p->prefix)); $kicked = $this->ircchannel2channel($this->fullnick2nick($p->args[1])); foreach (explode(',', $p->args[0]) as $channel) { $p2 = $this->udpmsg4_client->send_part($this->ircchannel2channel($channel), 'kicked by ' . $this->unmap_nick($kicker) . ': ' . @$p->args[2], $this->unmap_nick($kicked)); if (!$this->write_hub($p2->framed())) { return FALSE; } } if ($p->args[1] === $this->config['nick']) { $p2 = $this->udpmsg4_client->send_quit('kicked from ' . $this->ircchannel2channel($channel) . ' by ' . $this->unmap_nick($kicker), $this->nick()); $this->write_hub($p2->framed()); $this->write_client_irc_from_client('QUIT', array($p)); sleep(1); exit(2); } return TRUE; case 'QUIT': $from = $this->ircchannel2channel($this->fullnick2nick($p->prefix)); $p = $this->udpmsg4_client->send_quit(@$p->args[0], $this->unmap_nick($from)); return $this->write_hub($p->framed()); case 'ERROR': $p = $this->udpmsg4_client->send_quit('ERROR ' . preg_replace('/(?:\\(|\\[)[^ ]*?(?:\\(|\\])/', '', @$p->args[0]), $this->nick()); $this->write_hub($p->framed()); exit(1); /* case 'NICK': $from=$this->ircchannel2channel($this->fullnick2nick($p->prefix)); $to=$this->ircchannel2channel($this->fullnick2nick($p->args[0])); $p=$this->udpmsg4_client->send_nick($this->unmap_nick($to),$this->unmap_nick($from)); return $this->write_hub($p->framed()); */ /* case 'NICK': $from=$this->ircchannel2channel($this->fullnick2nick($p->prefix)); $to=$this->ircchannel2channel($this->fullnick2nick($p->args[0])); $p=$this->udpmsg4_client->send_nick($this->unmap_nick($to),$this->unmap_nick($from)); return $this->write_hub($p->framed()); */ case 'PING': return $this->write_client_irc_from_client('PONG', array($p->args[0])); case 'PONG': $this->last_pong = time(); if ($this->config['nick'] !== $this->config['nicks'][0]) { if ($this->last_relay_alive_time + 10 < $this->last_pong) { if (preg_match('/^nickserv/', @$this->config['authtype'])) { $this->write_client("PRIVMSG NickServ :GHOST " . $this->config['nicks'][0] . " " . $this->config['pass'] . "\r\n"); sleep(1); $this->write_client("NICK :" . $this->config['nicks'][0] . "\r\n"); $this->config['nick'] = $this->config['nicks'][0]; $this->irc_auth(); } else { die("try again"); } } } else { $this->last_relay_alive_time = $this->last_pong; } return TRUE; case '433': if ($this->config['nick'] === $p->args[1]) { $this->config['nick'] = $p->args[0]; } return TRUE; default: debug('irc', 1, 'received: ' . $p); return FALSE; case '404': case '405': case '474': if (!isset($this->config['channels'][$this->channel2ircchannel($p->args[1])])) { return TRUE; } $p2 = $this->udpmsg4_client->send_quit($p, $this->nick()); $this->write_hub($p2->framed()); $this->write_client_irc_from_client('QUIT', array($p)); sleep(1); exit(2); } }
function irc_do($p) { if ($p === FALSE || $p === NULL) { return $p; } if (!is_a($p, 'irc_packet')) { $p = irc_packet::parse($p); } if ($p === FALSE || $p === NULL) { return $p; } switch ($p->CMD) { case 'PRIVMSG': case 'NOTICE': if (!isset($p->args[0]) || !isset($p->args[1])) { return FALSE; } $to = $this->ircwire2chan($p->args[0]); if ($p->CMD === 'PRIVMSG') { $tp = $this->udpmsg4_client->send_message($to, $p->args[1]); } else { $tp = $this->udpmsg4_client->send_notice($to, $p->args[1]); } if ($tp === FALSE) { if ($this->is_channel($to)) { return $this->write_client_irc($p->args[0], 'NOTICE', array($this->nick(), 'Failed to send ' . ($p->CMD === 'PRIVMSG' ? 'message' : 'notice') . ' to ' . $p->args[0])); } else { return $this->write_client_irc($p->args[0], 'NOTICE', array($this->nick(), 'Failed to send PM to ' . $p->args[0])); } } return $this->write_hub($tp->framed()); case 'JOIN': foreach (explode(',', $p->args[0]) as $channel) { if (!$this->join_channel($channel)) { return FALSE; } } return TRUE; case 'PART': foreach (explode(',', $p->args[0]) as $channel) { if (!$this->part_channel($channel, @$p->args[1])) { return FALSE; } } return TRUE; case 'QUIT': exit(0); case 'NICK': return $this->irc_set_ircnick($p->args[0]); case 'PING': return $this->write_client_irc_from_server('PONG', array($this->hostname, @$p->args[0])); case 'MODE': if (!isset($p->args[0])) { return FALSE; } $target = $this->ircchannel2channel($p->args[0]); if ($this->is_channel($target)) { if (!isset($p->args[1])) { return $this->write_client_numeric('324', array($p->args[0], '+nt')) && $this->write_client_numeric('329', array($p->args[0], time())); } else { return $this->write_client_numeric('368', array($p->args[0], 'End of channel ban list')); return FALSE; } } else { return FALSE; } case 'WHO': if (!isset($p->args[0])) { return FALSE; } $target = $this->ircchannel2channel($p->args[0]); if ($this->is_channel($target)) { foreach ($this->users_in_channel($target) as $nick => $user) { if (!$this->write_client_numeric('352', array($p->args[0], $user['user'], $user['host'], $user['server'], $this->chan2ircwire($user['nick']), $user['hg'] . $user['flag'], $user['distance'] . ' ' . $user['realname']))) { return FALSE; } } return $this->write_client_numeric('315', array($p->args[0], 'End of /WHO list.')); } else { return FALSE; } case 'LIST': if (!$this->write_client_numeric('321', array('Channel', 'Users Name'))) { return FALSE; } foreach ($this->channels() as $channel) { $ircchannel = $this->channel2ircchannel($channel); $count = count($this->users_in_channel($channel)); if (!$this->write_client_numeric('322', array($ircchannel, $count, '[+nt]'))) { return FALSE; } } if (!$this->write_client_numeric('323', array('End of channel list.'))) { return FALSE; } return TRUE; case 'USER': return TRUE; case 'USERHOST': if (!isset($p->args[0])) { return $this->write_client_numeric_notenoughparams($p->cmd); } $user = $this->get_user($this->ircwire2chan($p->args[0])); $this->write_client_numeric('302', $this->chan2ircwire($user['nick']) . "=+" . $user['user'] . '@' . $user['host']); return TRUE; case 'TOPIC': if (!isset($p->args[0])) { return FALSE; } $channel = $this->ircwire2chan($p->args[0]); if (!isset($p->args[1])) { $topic = $this->channel_topic($channel); if ($topic === NULL) { return $this->write_client_numeric('331', array($p->args[0], 'No topic is set.')); } return $this->write_client_numeric('332', array($p->args[0], $topic)) && $this->write_client_numeric('333', array($p->args[0], $this->channel_topic_from($channel), $this->channel_topic_timestamp($channel))); } $this->set_channel_topic($channel, $p->args[1]); $tp = $this->udpmsg4_client->send_topic($channel, $p->args[1]); return $this->write_hub($tp->framed()) && $this->write_client_irc_topic($this->chan2ircwire($this->nick()), $channel, $p->args[1]); case 'AWAY': if (!isset($p->args[0])) { return $this->write_client_numeric('305', array('You are no longer marked as being away')); } return $this->write_client_numeric('306', array('You have been marked as being away but not matters')); default: debug('irc', 1, 'received: ' . $p); return FALSE; } }