﻿<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
	<id>http://wiki.ucis.nl/index.php?action=history&amp;feed=atom&amp;title=IRCRelay%2FSourcecode</id>
	<title>IRCRelay/Sourcecode - Revision history</title>
	<link rel="self" type="application/atom+xml" href="http://wiki.ucis.nl/index.php?action=history&amp;feed=atom&amp;title=IRCRelay%2FSourcecode"/>
	<link rel="alternate" type="text/html" href="http://wiki.ucis.nl/index.php?title=IRCRelay/Sourcecode&amp;action=history"/>
	<updated>2026-05-29T22:38:45Z</updated>
	<subtitle>Revision history for this page on the wiki</subtitle>
	<generator>MediaWiki 1.38.4</generator>
	<entry>
		<id>http://wiki.ucis.nl/index.php?title=IRCRelay/Sourcecode&amp;diff=92&amp;oldid=prev</id>
		<title>Admin: 1 revision imported</title>
		<link rel="alternate" type="text/html" href="http://wiki.ucis.nl/index.php?title=IRCRelay/Sourcecode&amp;diff=92&amp;oldid=prev"/>
		<updated>2022-11-09T14:49:53Z</updated>

		<summary type="html">&lt;p&gt;1 revision imported&lt;/p&gt;
&lt;table style=&quot;background-color: #fff; color: #202122;&quot; data-mw=&quot;interface&quot;&gt;
				&lt;tr class=&quot;diff-title&quot; lang=&quot;en&quot;&gt;
				&lt;td colspan=&quot;1&quot; style=&quot;background-color: #fff; color: #202122; text-align: center;&quot;&gt;← Older revision&lt;/td&gt;
				&lt;td colspan=&quot;1&quot; style=&quot;background-color: #fff; color: #202122; text-align: center;&quot;&gt;Revision as of 16:49, 9 November 2022&lt;/td&gt;
				&lt;/tr&gt;&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-notice&quot; lang=&quot;en&quot;&gt;&lt;div class=&quot;mw-diff-empty&quot;&gt;(No difference)&lt;/div&gt;
&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;</summary>
		<author><name>Admin</name></author>
	</entry>
	<entry>
		<id>http://wiki.ucis.nl/index.php?title=IRCRelay/Sourcecode&amp;diff=91&amp;oldid=prev</id>
		<title>Admin at 22:45, 9 April 2010</title>
		<link rel="alternate" type="text/html" href="http://wiki.ucis.nl/index.php?title=IRCRelay/Sourcecode&amp;diff=91&amp;oldid=prev"/>
		<updated>2010-04-09T22:45:44Z</updated>

		<summary type="html">&lt;p&gt;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;New page&lt;/b&gt;&lt;/p&gt;&lt;div&gt;&amp;lt;pre&amp;gt;&amp;lt;nowiki&amp;gt;&lt;br /&gt;
#!/usr/bin/php&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
/* Copyright 2010 Ivo Smits &amp;lt;Ivo@UCIS.nl&amp;gt;. All rights reserved.&lt;br /&gt;
   Redistribution and use in source and binary forms, with or without modification, are&lt;br /&gt;
   permitted provided that the following conditions are met:&lt;br /&gt;
&lt;br /&gt;
   1. Redistributions of source code must retain the above copyright notice, this list of&lt;br /&gt;
      conditions and the following disclaimer.&lt;br /&gt;
&lt;br /&gt;
   2. Redistributions in binary form must reproduce the above copyright notice, this list&lt;br /&gt;
      of conditions and the following disclaimer in the documentation and/or other materials&lt;br /&gt;
      provided with the distribution.&lt;br /&gt;
&lt;br /&gt;
   THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED&lt;br /&gt;
   WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND&lt;br /&gt;
   FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR&lt;br /&gt;
   CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR&lt;br /&gt;
   CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR&lt;br /&gt;
   SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON&lt;br /&gt;
   ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING&lt;br /&gt;
   NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF&lt;br /&gt;
   ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.&lt;br /&gt;
&lt;br /&gt;
   The views and conclusions contained in the software and documentation are those of the&lt;br /&gt;
   authors and should not be interpreted as representing official policies, either expressed&lt;br /&gt;
   or implied, of Ivo Smits.*/&lt;br /&gt;
&lt;br /&gt;
print(&amp;quot;UCIS IRC Relay bot (c) 2010 Ivo Smits &amp;lt;Ivo@UCIS.nl&amp;gt;\n&amp;quot;);&lt;br /&gt;
print(&amp;quot;More information: http://wiki.qontrol.nl/IRCRelay\n&amp;quot;);&lt;br /&gt;
print(&amp;quot;\n&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
class Network {&lt;br /&gt;
	public $key = NULL;&lt;br /&gt;
	public $name = NULL;&lt;br /&gt;
	public $socket = NULL;&lt;br /&gt;
	public $server = NULL;&lt;br /&gt;
	public $port = 6667;&lt;br /&gt;
	public $nick = NULL;&lt;br /&gt;
	public $realnick = NULL;&lt;br /&gt;
	public $connected = FALSE;&lt;br /&gt;
	public $connecting = FALSE;&lt;br /&gt;
	public $timeout = 0;&lt;br /&gt;
	public $channels = array();&lt;br /&gt;
	public $addressfamily = AF_INET;&lt;br /&gt;
	public $active = FALSE;&lt;br /&gt;
	public $ident = 'none';&lt;br /&gt;
	public $realname = 'Not set - http://wiki.qontrol.nl/IRCRelay';&lt;br /&gt;
	public $debug = FALSE;&lt;br /&gt;
}&lt;br /&gt;
class NetworkChannel {&lt;br /&gt;
	public $network;&lt;br /&gt;
	public $channel;&lt;br /&gt;
	public $name;&lt;br /&gt;
	public $display;&lt;br /&gt;
}&lt;br /&gt;
class Channel {&lt;br /&gt;
	public $name = NULL;&lt;br /&gt;
	public $links = array();&lt;br /&gt;
	public function __construct($name) { $this-&amp;gt;name = $name; }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
$networks = array();&lt;br /&gt;
$channels = array();&lt;br /&gt;
$status = NULL;&lt;br /&gt;
$adminpass = NULL;&lt;br /&gt;
&lt;br /&gt;
prepare();&lt;br /&gt;
configure();&lt;br /&gt;
init();&lt;br /&gt;
readloop();&lt;br /&gt;
&lt;br /&gt;
function getchannel($name) {&lt;br /&gt;
	global $channels;&lt;br /&gt;
	if (array_key_exists($name, $channels)) return $channels[$name];&lt;br /&gt;
	$ch = new Channel($name);&lt;br /&gt;
	$channels[$name] = $ch;&lt;br /&gt;
	return $ch;&lt;br /&gt;
}&lt;br /&gt;
function configure() {&lt;br /&gt;
	global $networks;&lt;br /&gt;
	global $channels;&lt;br /&gt;
	global $adminpass;&lt;br /&gt;
&lt;br /&gt;
	print(&amp;quot;Loading configuration...\n&amp;quot;);&lt;br /&gt;
	require 'config.php';&lt;br /&gt;
&lt;br /&gt;
	if (isset($config['password'])) $adminpass = $config['password'];&lt;br /&gt;
	foreach ($config['networks'] as $key =&amp;gt; $nc) {&lt;br /&gt;
		$net = new Network();&lt;br /&gt;
		$net-&amp;gt;key = $key;&lt;br /&gt;
		$net-&amp;gt;server = $nc['server'];&lt;br /&gt;
		$net-&amp;gt;nick = $nc['nick'];&lt;br /&gt;
		$net-&amp;gt;name = isset($nc['name']) ? $nc['name'] : $key;&lt;br /&gt;
		if (isset($nc['port'])) $net-&amp;gt;port = $nc['port'];&lt;br /&gt;
		if (isset($nc['ident'])) $net-&amp;gt;ident = $nc['ident'];&lt;br /&gt;
		if (isset($nc['realname'])) $net-&amp;gt;realname = $nc['realname'];&lt;br /&gt;
		if (isset($nc['ipv6']) &amp;amp;&amp;amp; $nc['ipv6']) $net-&amp;gt;addressfamily = AF_INET6;&lt;br /&gt;
		if (isset($nc['debug']) &amp;amp;&amp;amp; $nc['debug']) $net-&amp;gt;debug = TRUE;&lt;br /&gt;
		foreach ($nc['channels'] as $chn =&amp;gt; $cf) {&lt;br /&gt;
			$ch = getchannel($cf['link']);&lt;br /&gt;
			$nch = new NetworkChannel();&lt;br /&gt;
			$nch-&amp;gt;name = $chn;&lt;br /&gt;
			$nch-&amp;gt;network = $net;&lt;br /&gt;
			$nch-&amp;gt;channel = $ch;&lt;br /&gt;
			$nch-&amp;gt;display = isset($cf['display']) ? $cf['display'] : $net-&amp;gt;key;&lt;br /&gt;
			$ch-&amp;gt;links[] = $nch;&lt;br /&gt;
			$net-&amp;gt;channels[$chn] = $nch;&lt;br /&gt;
		}&lt;br /&gt;
		$networks[$key] = $net;&lt;br /&gt;
		$net-&amp;gt;active = TRUE;&lt;br /&gt;
		print('NET '.$net-&amp;gt;key.' create'.&amp;quot;\n&amp;quot;);&lt;br /&gt;
	}&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
function prepare() {&lt;br /&gt;
	global $channels, $status;&lt;br /&gt;
	print(&amp;quot;Starting IRC Relay...\n&amp;quot;);&lt;br /&gt;
	$ch = new Channel('status');&lt;br /&gt;
	$channels[$ch-&amp;gt;name] = $ch;&lt;br /&gt;
	$status = $ch;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
function init() {&lt;br /&gt;
	global $networks;&lt;br /&gt;
	print(&amp;quot;Initializing...\n&amp;quot;);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
function readloop() {&lt;br /&gt;
	global $networks;&lt;br /&gt;
&lt;br /&gt;
	$ltime = 0;&lt;br /&gt;
&lt;br /&gt;
	print(&amp;quot;Running\n&amp;quot;);&lt;br /&gt;
	while (TRUE) {&lt;br /&gt;
		$selread = array();&lt;br /&gt;
		$selwrite = array();&lt;br /&gt;
		$selerror = array();&lt;br /&gt;
		$selcount = 0;&lt;br /&gt;
&lt;br /&gt;
		$ntime = time();&lt;br /&gt;
		$tdiff = $ntime - $ltime;&lt;br /&gt;
		$ltime = $ntime;&lt;br /&gt;
&lt;br /&gt;
		foreach ($networks as $net) {&lt;br /&gt;
			if ($net-&amp;gt;connected) {&lt;br /&gt;
				$selread[] = $net-&amp;gt;socket;&lt;br /&gt;
				$selerror[] = $net-&amp;gt;socket;&lt;br /&gt;
				$selcount++;&lt;br /&gt;
			} else if ($net-&amp;gt;connecting) {&lt;br /&gt;
				$selwrite[] = $net-&amp;gt;socket;&lt;br /&gt;
				$selerror[] = $net-&amp;gt;socket;&lt;br /&gt;
				$selcount++;&lt;br /&gt;
			} else if ($net-&amp;gt;active) {&lt;br /&gt;
				$net-&amp;gt;timeout -= $tdiff;&lt;br /&gt;
				if ($net-&amp;gt;timeout &amp;lt;= 0) {&lt;br /&gt;
					$net-&amp;gt;connecting = TRUE;&lt;br /&gt;
					print('NET '.$net-&amp;gt;key.' connect '.$net-&amp;gt;server.':'.$net-&amp;gt;port.&amp;quot;\n&amp;quot;);&lt;br /&gt;
					$net-&amp;gt;socket = socket_create($net-&amp;gt;addressfamily, SOCK_STREAM, SOL_TCP);&lt;br /&gt;
					socket_set_nonblock($net-&amp;gt;socket);&lt;br /&gt;
					socket_connect($net-&amp;gt;socket, $net-&amp;gt;server, $net-&amp;gt;port);&lt;br /&gt;
					$selwrite[] = $net-&amp;gt;socket;&lt;br /&gt;
					$selerror[] = $net-&amp;gt;socket;&lt;br /&gt;
				}&lt;br /&gt;
			}&lt;br /&gt;
		}&lt;br /&gt;
&lt;br /&gt;
		if (!$selcount) {&lt;br /&gt;
			sleep(1);&lt;br /&gt;
			continue;&lt;br /&gt;
		}&lt;br /&gt;
&lt;br /&gt;
		socket_select(&amp;amp;$selread, &amp;amp;$selwrite, &amp;amp;$selerror, 10);&lt;br /&gt;
&lt;br /&gt;
		foreach ($networks as $net) {&lt;br /&gt;
			if (in_array($net-&amp;gt;socket, $selerror)) {&lt;br /&gt;
				print('NET '.$net-&amp;gt;key.' socket error'.&amp;quot;\n&amp;quot;);&lt;br /&gt;
				network_reset($net);&lt;br /&gt;
			} else if ($net-&amp;gt;connected &amp;amp;&amp;amp; in_array($net-&amp;gt;socket, $selread)) {&lt;br /&gt;
				if (!network_read($net)) {&lt;br /&gt;
					print('NET '.$net-&amp;gt;key.' read error'.&amp;quot;\n&amp;quot;);&lt;br /&gt;
					network_reset($net);&lt;br /&gt;
				}&lt;br /&gt;
			} else if ($net-&amp;gt;connecting &amp;amp;&amp;amp; in_array($net-&amp;gt;socket, $selwrite)) {&lt;br /&gt;
				$net-&amp;gt;connected = TRUE;&lt;br /&gt;
				$net-&amp;gt;connecting = FALSE;&lt;br /&gt;
				print('NET '.$net-&amp;gt;key.' identify '.$net-&amp;gt;nick.&amp;quot;\n&amp;quot;);&lt;br /&gt;
				network_send($net, 'USER '.$net-&amp;gt;ident.' host server :'.$net-&amp;gt;realname);&lt;br /&gt;
				network_send($net, 'NICK '.$net-&amp;gt;nick);&lt;br /&gt;
			}&lt;br /&gt;
		}&lt;br /&gt;
	}&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
function network_reset($net) {&lt;br /&gt;
	print('NET '.$net-&amp;gt;key.' reset'.&amp;quot;\n&amp;quot;);&lt;br /&gt;
	socket_close($net-&amp;gt;socket);&lt;br /&gt;
	$net-&amp;gt;connected = FALSE;&lt;br /&gt;
	$net-&amp;gt;connecting = FALSE;&lt;br /&gt;
	$net-&amp;gt;readbuffer = '';&lt;br /&gt;
	$net-&amp;gt;timeout = 60;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
function network_read($net) {&lt;br /&gt;
	$newdata = socket_read($net-&amp;gt;socket, 1024);&lt;br /&gt;
	if ($newdata === FALSE || !strlen($newdata)) return FALSE;&lt;br /&gt;
	$net-&amp;gt;readbuffer .= $newdata;&lt;br /&gt;
	$offset = 0;&lt;br /&gt;
	$len = strlen($net-&amp;gt;readbuffer);&lt;br /&gt;
	while ($offset &amp;lt; $len) {&lt;br /&gt;
		$posa = strpos($net-&amp;gt;readbuffer, &amp;quot;\n&amp;quot;, $offset);&lt;br /&gt;
		$posb = strpos($net-&amp;gt;readbuffer, &amp;quot;\r&amp;quot;, $offset);&lt;br /&gt;
		if ($posa !== FALSE &amp;amp;&amp;amp; $posb !== FALSE) {&lt;br /&gt;
			$pos = min($posa, $posb);&lt;br /&gt;
		} else if ($posa !== FALSE) {&lt;br /&gt;
			$pos = $posa;&lt;br /&gt;
		} else if ($posb !== FALSE) {&lt;br /&gt;
			$pos = $posb;&lt;br /&gt;
		} else {&lt;br /&gt;
			break;&lt;br /&gt;
		}&lt;br /&gt;
		$line = substr($net-&amp;gt;readbuffer, $offset, $pos - $offset);&lt;br /&gt;
		if (strlen($line)) {&lt;br /&gt;
			if (!network_process($net, $line)) return FALSE;&lt;br /&gt;
		}&lt;br /&gt;
		$offset = $pos + 1;&lt;br /&gt;
	}&lt;br /&gt;
	if ($offset == $len) {&lt;br /&gt;
		$net-&amp;gt;readbuffer = '';&lt;br /&gt;
	} else if ($offset != 0) {&lt;br /&gt;
		$net-&amp;gt;readbuffer = substr($net-&amp;gt;readbuffer, $offset);&lt;br /&gt;
	}&lt;br /&gt;
	return TRUE;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
function network_process($net, $line) {&lt;br /&gt;
	global $adminpass;&lt;br /&gt;
	if ($net-&amp;gt;debug) print('NET '.$net-&amp;gt;key.' recv '.$line.&amp;quot;\n&amp;quot;);&lt;br /&gt;
	$partsa = explode(' :', $line, 2);&lt;br /&gt;
	$parts = explode(' ', $partsa[0]);&lt;br /&gt;
	if ($parts[0][0] == ':') {&lt;br /&gt;
		$sender = substr(array_shift(&amp;amp;$parts), 1);&lt;br /&gt;
	} else {&lt;br /&gt;
		$sender = NULL;&lt;br /&gt;
	}&lt;br /&gt;
	$command = array_shift(&amp;amp;$parts);&lt;br /&gt;
	if (count($partsa) &amp;gt; 1) array_push(&amp;amp;$parts, $partsa[1]);&lt;br /&gt;
	$partsa = explode('!', $sender);&lt;br /&gt;
	$sendernick = $partsa[0];&lt;br /&gt;
	switch (strtoupper($command)) {&lt;br /&gt;
		case '001': //Welcome&lt;br /&gt;
			$net-&amp;gt;realnick = $parts[0];&lt;br /&gt;
			print('NET '.$net-&amp;gt;key.' welcome '.$net-&amp;gt;realnick.&amp;quot;\n&amp;quot;);&lt;br /&gt;
			foreach ($net-&amp;gt;channels as $ch) network_send($net, &amp;quot;JOIN :&amp;quot;.$ch-&amp;gt;name);&lt;br /&gt;
			break;&lt;br /&gt;
		case '433': //Nickname in use&lt;br /&gt;
			print('NET '.$net-&amp;gt;key.' nickname_in_use'.&amp;quot;\n&amp;quot;);&lt;br /&gt;
			network_send($net, &amp;quot;NICK &amp;quot;.$net-&amp;gt;nick.rand(100,999));&lt;br /&gt;
			break;&lt;br /&gt;
		case 'NICK': //Nickname change&lt;br /&gt;
			if (strcasecmp($sendernick, $net-&amp;gt;realnick)) {&lt;br /&gt;
				$net-&amp;gt;realnick = $parts[0];&lt;br /&gt;
				print('NET '.$net-&amp;gt;key.' nickname '.$net-&amp;gt;realnick.&amp;quot;\n&amp;quot;);&lt;br /&gt;
			}&lt;br /&gt;
			break;&lt;br /&gt;
		case 'PING':&lt;br /&gt;
			network_send($net, 'PONG :'.$parts[0]);&lt;br /&gt;
			break;&lt;br /&gt;
		case 'PRIVMSG':&lt;br /&gt;
		case 'NOTICE':&lt;br /&gt;
			if ($parts[0][0] == '#') {&lt;br /&gt;
				$to = $parts[0];&lt;br /&gt;
			} else {&lt;br /&gt;
				$to = $sendernick;&lt;br /&gt;
				if (!is_null($adminpass) &amp;amp;&amp;amp; $parts[1][0] == '.' &amp;amp;&amp;amp; substr($parts[1], 1, strlen($adminpass)) === $adminpass) {&lt;br /&gt;
					$ret = admincmd(array_slice(explode(' ', $parts[1]), 1));&lt;br /&gt;
					network_send($net, 'PRIVMSG '.$to.' :'.$ret);&lt;br /&gt;
					break;&lt;br /&gt;
				} &lt;br /&gt;
			}&lt;br /&gt;
			if (!array_key_exists($to, $net-&amp;gt;channels)) {&lt;br /&gt;
				print('NET '.$net-&amp;gt;key.' privmsg '.$sendernick.' @ '.$to.' - '.$parts[1].&amp;quot;\n&amp;quot;);&lt;br /&gt;
				break;&lt;br /&gt;
			}&lt;br /&gt;
			$ch = $net-&amp;gt;channels[$to];&lt;br /&gt;
			$prefix = '['.$sendernick.(is_null($ch-&amp;gt;display) ? '' : ' @ '.$ch-&amp;gt;display).'] ';&lt;br /&gt;
			if (ord($parts[1][0]) == 1) { //CTCP&lt;br /&gt;
				if (substr($parts[1], 1, 6) != 'ACTION') break;&lt;br /&gt;
				$msg = chr(1).'ACTION '.$prefix.substr($parts[1], 8, -1).chr(1);&lt;br /&gt;
			} else {&lt;br /&gt;
				$msg = $prefix.$parts[1];&lt;br /&gt;
			}&lt;br /&gt;
			channel_send($ch-&amp;gt;channel, $msg, $ch, $command == 'NOTICE');&lt;br /&gt;
			break;&lt;br /&gt;
		case '372': //Motd&lt;br /&gt;
		case '376': //End of moth&lt;br /&gt;
		case '002': //Your host&lt;br /&gt;
		case '003': //This server&lt;br /&gt;
		case '004': //Version&lt;br /&gt;
		case '005': //Supported&lt;br /&gt;
		case '422': //Motd missing&lt;br /&gt;
		case '251': case '254': case '255': case '265': case '266': case '396': case '353': case '366':&lt;br /&gt;
		case '252': case '375':&lt;br /&gt;
		case 'MODE':&lt;br /&gt;
		case 'JOIN':&lt;br /&gt;
		case 'PART':&lt;br /&gt;
		case 'QUIT':&lt;br /&gt;
			break;&lt;br /&gt;
		default:&lt;br /&gt;
			print('NET '.$net-&amp;gt;key.' unknown '.$line.&amp;quot;\n&amp;quot;);&lt;br /&gt;
	}&lt;br /&gt;
	return TRUE;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
function network_send($net, $line) {&lt;br /&gt;
	if ($net-&amp;gt;debug) print('NET '.$net-&amp;gt;key.' send '.$line.&amp;quot;\n&amp;quot;);&lt;br /&gt;
	$line .= &amp;quot;\r\n&amp;quot;;&lt;br /&gt;
	socket_send($net-&amp;gt;socket, $line, strlen($line), 0);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
function channel_send($ch, $message, $source = NULL, $notice = FALSE) {&lt;br /&gt;
	foreach ($ch-&amp;gt;links as $link) {&lt;br /&gt;
		if ($link-&amp;gt;network-&amp;gt;connected &amp;amp;&amp;amp; $link !== $source) {&lt;br /&gt;
			network_send($link-&amp;gt;network, ($notice ? 'NOTICE ' : 'PRIVMSG ').$link-&amp;gt;name.' :'.$message);&lt;br /&gt;
		}&lt;br /&gt;
	}&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
function admincmd($parts) {&lt;br /&gt;
	global $channels, $networks;&lt;br /&gt;
	switch (strtolower($parts[0])) {&lt;br /&gt;
		case 'die': exit(0);&lt;br /&gt;
		case 'c': case 'chn': case 'chan': case 'channel':&lt;br /&gt;
			switch (strtolower($parts[1])) {&lt;br /&gt;
				case 'join': case 'part': case 'rejoin': case 'msg': case 'links':&lt;br /&gt;
					if (!isset($channels[$parts[2]])) return 'ERR Channel does not exist';&lt;br /&gt;
					return admincmd_channel($parts[1], $channels[$parts[2]], array_slice($parts, 3));&lt;br /&gt;
				case 'list': return 'OK '.implode('; ', array_keys($channels));&lt;br /&gt;
				case 'help':&lt;br /&gt;
					return 'OK list; links [ch]; join [ch]; part [ch]; rejoin [ch]; msg [ch] [msg]; help';&lt;br /&gt;
			}&lt;br /&gt;
			break;&lt;br /&gt;
		case 'n': case 'net': case 'network':&lt;br /&gt;
			switch (strtolower($parts[1])) {&lt;br /&gt;
				case 'disconnect': case 'raw': case 'join': case 'part': case 'rejoin': case 'msg': case 'delete': case 'info': case 'status': case 'channels': case 'set': case 'active': case 'ipv6': case 'link': case 'unlink': case 'linkinfo':&lt;br /&gt;
					if (!isset($networks[$parts[2]])) return 'ERR Network does not exist';&lt;br /&gt;
					return admincmd_network($parts[1], $networks[$parts[2]], array_slice($parts, 3));&lt;br /&gt;
				case 'list': return 'OK '.implode('; ', array_keys($networks));&lt;br /&gt;
				case 'help':&lt;br /&gt;
					return 'OK list; disconnect [net]; raw [net] [text]; join [net] [ch]; part [net] [ch]; rejoin [net] [ch]; msg [net] [ch] [msg]; help; delete; info; status; channels; set [name] [server] [port] [nick]; active [enable]; ipv6 [enable]; link [name] [channel] [display]; unlink [name]; linkinfo [name]';&lt;br /&gt;
			}&lt;br /&gt;
			break;&lt;br /&gt;
		case 'help':&lt;br /&gt;
			return 'OK die; channel help; network help';&lt;br /&gt;
	}&lt;br /&gt;
	return 'ERR Unknown command';&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
function admincmd_channel($cmd, $chn, $parts) {&lt;br /&gt;
	switch (strtolower($cmd)) {&lt;br /&gt;
		case 'links':&lt;br /&gt;
			$arr = array();&lt;br /&gt;
			foreach ($chn-&amp;gt;links as $link) $arr[] = $link-&amp;gt;network-&amp;gt;key.'/'.$link-&amp;gt;name;&lt;br /&gt;
			return 'OK '.implode('; ', $arr);&lt;br /&gt;
		case 'join':&lt;br /&gt;
			foreach ($chn-&amp;gt;links as $link) if ($link-&amp;gt;network-&amp;gt;connected) network_send($link-&amp;gt;network, 'JOIN '.$link-&amp;gt;name);&lt;br /&gt;
			return 'OK';&lt;br /&gt;
		case 'part':&lt;br /&gt;
			foreach ($chn-&amp;gt;links as $link) if ($link-&amp;gt;network-&amp;gt;connected) network_send($link-&amp;gt;network, 'PART '.$link-&amp;gt;name);&lt;br /&gt;
			return 'OK';&lt;br /&gt;
		case 'rejoin':&lt;br /&gt;
			foreach ($chn-&amp;gt;links as $link) if ($link-&amp;gt;network-&amp;gt;connected) network_send($link-&amp;gt;network, 'PART '.$link-&amp;gt;name);&lt;br /&gt;
			foreach ($chn-&amp;gt;links as $link) if ($link-&amp;gt;network-&amp;gt;connected) network_send($link-&amp;gt;network, 'JOIN '.$link-&amp;gt;name);&lt;br /&gt;
			return 'OK';&lt;br /&gt;
		case 'msg':&lt;br /&gt;
			foreach ($chn-&amp;gt;links as $link) if ($link-&amp;gt;network-&amp;gt;connected) network_send($link-&amp;gt;network, 'PRIVMSG '.$link-&amp;gt;name.' :'.implode(' ', array_slice($parts, 0)));&lt;br /&gt;
			return 'OK';&lt;br /&gt;
	}&lt;br /&gt;
	return 'ERR Unknown command';&lt;br /&gt;
}&lt;br /&gt;
function admincmd_network($cmd, $net, $parts) {&lt;br /&gt;
	global $channels;&lt;br /&gt;
	switch (strtolower($cmd)) {&lt;br /&gt;
		case 'disconnect':&lt;br /&gt;
			network_reset($net);&lt;br /&gt;
			return 'OK';&lt;br /&gt;
		case 'raw':&lt;br /&gt;
			network_send($net, implode(' ', array_slice($parts, 0)));&lt;br /&gt;
			return 'OK';&lt;br /&gt;
		case 'join':&lt;br /&gt;
			network_send($net, 'JOIN '.$parts[0]);&lt;br /&gt;
			return 'OK';&lt;br /&gt;
		case 'part':&lt;br /&gt;
			network_send($net, 'PART '.$parts[0]);&lt;br /&gt;
			return 'OK';&lt;br /&gt;
		case 'rejoin':&lt;br /&gt;
			network_send($net, 'JOIN '.$parts[0]);&lt;br /&gt;
			network_send($net, 'PART '.$parts[0]);&lt;br /&gt;
			return 'OK';&lt;br /&gt;
		case 'msg':&lt;br /&gt;
			network_send($net, 'PRIVMSG '.$parts[0].' :'.implode(' ', array_slice($parts, 1)));&lt;br /&gt;
			return 'OK';&lt;br /&gt;
		case 'delete':&lt;br /&gt;
			network_Reset($net);&lt;br /&gt;
			unset($networks[$net-&amp;gt;key]);&lt;br /&gt;
			return 'OK';&lt;br /&gt;
		case 'info':&lt;br /&gt;
			return 'OK key='.$net-&amp;gt;key.'; name='.$net-&amp;gt;name.'; server='.$net-&amp;gt;server.'; port='.$net-&amp;gt;port.'; nick='.$net-&amp;gt;nick.'; active='.$net-&amp;gt;active.'; af='.$net-&amp;gt;addressfamily;&lt;br /&gt;
		case 'status':&lt;br /&gt;
			return 'OK connected='.$net-&amp;gt;connected.'; connecting='.$net-&amp;gt;connecting.'; timeout='.$net-&amp;gt;timeout.'; nick='.$net-&amp;gt;realnick;&lt;br /&gt;
		case 'channels':&lt;br /&gt;
			return 'OK '.implode('; ', array_keys($net-&amp;gt;channels));&lt;br /&gt;
		case 'set':&lt;br /&gt;
			$net-&amp;gt;name = $parts[0];&lt;br /&gt;
			$net-&amp;gt;server = $parts[1];&lt;br /&gt;
			$net-&amp;gt;port = (int)$parts[2];&lt;br /&gt;
			$net-&amp;gt;nick = $parts[3];&lt;br /&gt;
			return 'OK';&lt;br /&gt;
		case 'active':&lt;br /&gt;
			$net-&amp;gt;active = $parts[0];&lt;br /&gt;
			return 'OK';&lt;br /&gt;
		case 'ipv6':&lt;br /&gt;
			$net-&amp;gt;addressfamily = $parts[0] ? AF_INET6 : AF_INET;&lt;br /&gt;
			return 'OK';&lt;br /&gt;
		case 'link':&lt;br /&gt;
			if (isset($net-&amp;gt;channels[$parts[0]])) return 'ERR Channel already linked';&lt;br /&gt;
			$link = new NetworkChannel();&lt;br /&gt;
			$link-&amp;gt;name = $parts[0];&lt;br /&gt;
			$link-&amp;gt;network = $net;&lt;br /&gt;
			$link-&amp;gt;channel = getchannel($parts[1]);&lt;br /&gt;
			$link-&amp;gt;display = implode(' ', array_slice($parts, 2));&lt;br /&gt;
			$link-&amp;gt;channel-&amp;gt;links[] = $link;&lt;br /&gt;
			$net-&amp;gt;channels[$link-&amp;gt;name] = $link;&lt;br /&gt;
			if ($net-&amp;gt;connected &amp;amp;&amp;amp; $link-&amp;gt;name[0] == '#') network_send($net, 'JOIN '.$link-&amp;gt;name);&lt;br /&gt;
			return 'OK';&lt;br /&gt;
		case 'unlink':&lt;br /&gt;
			if (!isset($net-&amp;gt;channels[$parts[0]])) return 'ERR Channel not linked';&lt;br /&gt;
			$link = $net-&amp;gt;channels[$parts[0]];&lt;br /&gt;
			unset($net-&amp;gt;channels[$link-&amp;gt;name]);&lt;br /&gt;
			foreach ($link-&amp;gt;channel-&amp;gt;links as $k =&amp;gt; $l) if ($l === $link) unset($link-&amp;gt;channel-&amp;gt;links[$k]);&lt;br /&gt;
			if (!count($link-&amp;gt;channel-&amp;gt;links)) unset($channels[$link-&amp;gt;channel-&amp;gt;name]);&lt;br /&gt;
			if ($net-&amp;gt;connected &amp;amp;&amp;amp; $link-&amp;gt;name[0] == '#') network_send($net, 'PART '.$link-&amp;gt;name);&lt;br /&gt;
			return 'OK';&lt;br /&gt;
		case 'linkinfo':&lt;br /&gt;
			if (!isset($net-&amp;gt;channels[$parts[0]])) return 'ERR Channel not linked';&lt;br /&gt;
			$link = $net-&amp;gt;channels[$parts[0]];&lt;br /&gt;
			return 'OK channel='.$link-&amp;gt;channel-&amp;gt;name.'; display='.$link-&amp;gt;display;&lt;br /&gt;
	}&lt;br /&gt;
	return 'ERR Unknown command';&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&amp;lt;/pre&amp;gt;&lt;/div&gt;</summary>
		<author><name>Admin</name></author>
	</entry>
</feed>