send_packet($xml);
			sleep($this->iq_sleep_timer);
			$this->listen();
			return (preg_match('#^(get|set)$#', $type)) ? $this->get_from_queue_by_id('iq', $id) : true;
		}
		else
		{
			return false;
		}
	}
	// ======================================================================
	// private methods
	// ======================================================================
	function _sendauth_ok($zerok_token, $zerok_sequence)
	{
		// initial hash of password
		$zerok_hash = @mhash(MHASH_SHA1, $this->password);
		$zerok_hash = bin2hex($zerok_hash);
		// sequence 0: hash of hashed-password and token
		$zerok_hash = @mhash(MHASH_SHA1, $zerok_hash . $zerok_token);
		$zerok_hash = bin2hex($zerok_hash);
		// repeat as often as needed
		for ($a = 0; $a < $zerok_sequence; $a++)
		{
			$zerok_hash = @mhash(MHASH_SHA1, $zerok_hash);
			$zerok_hash = bin2hex($zerok_hash);
		}
		$payload = "{$this->username}
					$zerok_hash
					{$this->resource}";
		$packet = $this->send_iq(NULL, 'set', $this->auth_id, 'jabber:iq:auth', $payload);
		// was a result returned?
		return ($this->get_info_from_iq_type($packet) == 'result' && $this->get_info_from_iq_id($packet) == $this->auth_id) ? true : false;
	}
	function _sendauth_digest()
	{
		$payload = "{$this->username}
					{$this->resource}
					" . bin2hex(mhash(MHASH_SHA1, $this->stream_id . $this->password)) . "";
		$packet = $this->send_iq(NULL, 'set', $this->auth_id, 'jabber:iq:auth', $payload);
		// was a result returned?
		return ($this->get_info_from_iq_type($packet) == 'result' && $this->get_info_from_iq_id($packet) == $this->auth_id) ? true : false;
	}
	function _sendauth_plaintext()
	{
		$payload = "{$this->username}
					{$this->password}
					{$this->resource}";
		$packet = $this->send_iq(NULL, 'set', $this->auth_id, 'jabber:iq:auth', $payload);
		// was a result returned?
		return ($this->get_info_from_iq_type($packet) == 'result' && $this->get_info_from_iq_id($packet) == $this->auth_id) ? true : false;
	}
	function _listen_incoming()
	{
		$incoming = '';
		
		while ($line = $this->connector->read_from_socket(4096))
		{
			$incoming .= $line;
		}
		$incoming = trim($incoming);
		return $this->xmlize($incoming);
	}
	function _check_connected()
	{
		$incoming_array = $this->_listen_incoming();
		if (is_array($incoming_array))
		{
			if ($incoming_array['stream:stream']['@']['from'] == $this->server
				&& $incoming_array['stream:stream']['@']['xmlns'] == 'jabber:client'
				&& $incoming_array['stream:stream']['@']['xmlns:stream'] == 'http://etherx.jabber.org/streams')
			{
				$this->stream_id = $incoming_array['stream:stream']['@']['id'];
				return true;
			}
			else
			{
				return false;
			}
		}
		else
		{
			return false;
		}
	}
	function _split_incoming($incoming)
	{
		$temp = preg_split('#<(message|iq|presence|stream)#', $incoming, -1, PREG_SPLIT_DELIM_CAPTURE);
		$array = array();
		for ($a = 1; $a < sizeof($temp); $a = $a + 2)
		{
			$array[] = '<' . $temp[$a] . $temp[($a + 1)];
		}
		return $array;
	}
	function _get_packet_type($packet = NULL)
	{
		if (is_array($packet))
		{
			reset($packet);
			$packet_type = key($packet);
		}
		return ($packet_type) ? $packet_type : false;
	}
	// _array_htmlspecialchars()
	// applies htmlspecialchars() to all values in an array
	function _array_htmlspecialchars(&$array)
	{
		if (is_array($array))
		{
			foreach ($array as $k => $v)
			{
				$v = (is_array($v)) ? $this->_array_htmlspecialchars($v) : htmlspecialchars($v);
			}
		}
		return $array;
	}
	// ======================================================================
	//  parsers
	// ======================================================================
	function get_info_from_message_from($packet = NULL)
	{
		return (is_array($packet)) ? $packet['message']['@']['from'] : false;
	}
	function get_info_from_message_type($packet = NULL)
	{
		return (is_array($packet)) ? $packet['message']['@']['type'] : false;
	}
	function get_info_from_message_id($packet = NULL)
	{
		return (is_array($packet)) ? $packet['message']['@']['id'] : false;
	}
	function get_info_from_message_thread($packet = NULL)
	{
		return (is_array($packet)) ? $packet['message']['#']['thread'][0]['#'] : false;
	}
	function get_info_from_message_subject($packet = NULL)
	{
		return (is_array($packet)) ? $packet['message']['#']['subject'][0]['#'] : false;
	}
	function get_info_from_message_body($packet = NULL)
	{
		return (is_array($packet)) ? $packet['message']['#']['body'][0]['#'] : false;
	}
	function get_info_from_message_error($packet = NULL)
	{
		$error = preg_replace('#^\/$#', '', ($packet['message']['#']['error'][0]['@']['code'] . '/' . $packet['message']['#']['error'][0]['#']));
		return (is_array($packet)) ? $error : false;
	}
	// ======================================================================
	//  parsers
	// ======================================================================
	function get_info_from_iq_from($packet = NULL)
	{
		return (is_array($packet)) ? $packet['iq']['@']['from'] : false;
	}
	function get_info_from_iq_type($packet = NULL)
	{
		return (is_array($packet)) ? $packet['iq']['@']['type'] : false;
	}
	function get_info_from_iq_id($packet = NULL)
	{
		return (is_array($packet)) ? $packet['iq']['@']['id'] : false;
	}
	function get_info_from_iq_key($packet = NULL)
	{
		return (is_array($packet)) ? $packet['iq']['#']['query'][0]['#']['key'][0]['#'] : false;
	}
	function get_info_from_iq_error($packet = NULL)
	{
		$error = preg_replace('#^\/$#', '', ($packet['iq']['#']['error'][0]['@']['code'] . '/' . $packet['iq']['#']['error'][0]['#']));
		return (is_array($packet)) ? $error : false;
	}
	// ======================================================================
	//  handlers
	// ======================================================================
	function handler_message_normal($packet)
	{
		$from = $packet['message']['@']['from'];
	}
	function handler_message_error($packet)
	{
		$from = $packet['message']['@']['from'];
	}
	// ======================================================================
	//  handlers
	// ======================================================================
	// simple client authentication
	function handler_iq_jabber_iq_auth($packet)
	{
		$from	= $this->get_info_from_iq_from($packet);
		$id		= $this->get_info_from_iq_id($packet);
		$this->send_error($from, $id, 501);
	}
	// method for interactive registration
	function handler_iq_jabber_iq_register($packet)
	{
		$from	= $this->get_info_from_iq_from($packet);
		$id		= $this->get_info_from_iq_id($packet);
		$this->send_error($from, $id, 501);
	}
	// keepalive method, added by Nathan Fritz
	function handler_iq_($packet)
	{
		if ($this->keep_alive_id == $this->get_info_from_iq_id($packet))
		{
			$this->returned_keep_alive = true;
		}
	}
	
	// ======================================================================
	// Generic handlers
	// ======================================================================
	// Generic handler for unsupported requests
	function handler_not_implemented($packet)
	{
		$packet_type	= $this->_get_packet_type($packet);
		$from			= call_user_func(array(&$this, 'get_info_from_' . strtolower($packet_type) . '_from'), $packet);
		$id				= call_user_func(array(&$this, 'get_info_from_' . strtolower($packet_type) . '_id'), $packet);
		$this->send_error($from, $id, 501);
	}
	// Third party code
	// m@d pr0ps to the coders ;)
	// xmlize()
	// (c) Hans Anderson / http://www.hansanderson.com/php/xml/
	function xmlize($data)
	{
		$vals = $index = $array = array();
		$parser = @xml_parser_create();
		@xml_parser_set_option($parser, XML_OPTION_CASE_FOLDING, 0);
		@xml_parser_set_option($parser, XML_OPTION_SKIP_WHITE, 1);
		@xml_parse_into_struct($parser, $data, $vals, $index);
		@xml_parser_free($parser);
		$i = 0;
		$tagname = $vals[$i]['tag'];
		$array[$tagname]['@'] = $vals[$i]['attributes'];
		$array[$tagname]['#'] = $this->_xml_depth($vals, $i);
		return $array;
	}
	// _xml_depth()
	// (c) Hans Anderson / http://www.hansanderson.com/php/xml/
	function _xml_depth($vals, &$i)
	{
		$children = array();
		if (isset($vals[$i]['value']) && $vals[$i]['value'])
		{
			array_push($children, trim($vals[$i]['value']));
		}
		while (++$i < sizeof($vals))
		{
			switch ($vals[$i]['type'])
			{
				case 'cdata':
					array_push($children, trim($vals[$i]['value']));
	 				break;
				case 'complete':
					$tagname = $vals[$i]['tag'];
					$size = (isset($children[$tagname])) ? sizeof($children[$tagname]) : 0;
					$children[$tagname][$size]['#'] = (isset($vals[$i]['value'])) ? trim($vals[$i]['value']) : '';
					if (isset($vals[$i]['attributes']) && $vals[$i]['attributes'])
					{
						$children[$tagname][$size]['@'] = $vals[$i]['attributes'];
					}
					break;
				case 'open':
					$tagname = $vals[$i]['tag'];
					$size = (isset($children[$tagname])) ? sizeof($children[$tagname]) : 0;
					if ($vals[$i]['attributes'])
					{
						$children[$tagname][$size]['@'] = $vals[$i]['attributes'];
						$children[$tagname][$size]['#'] = $this->_xml_depth($vals, $i);
					}
					else
					{
						$children[$tagname][$size]['#'] = $this->_xml_depth($vals, $i);
					}
					break;
				case 'close':
					return $children;
					break;
			}
		}
		return $children;
	}
	// traverse_xmlize()
	// (c) acebone@f2s.com, a HUGE help!
	function traverse_xmlize($array, $arr_name = 'array', $level = 0)
	{
		if ($level == 0)
		{
			echo '';
		}
		while (list($key, $val) = @each($array))
		{
			if (is_array($val))
			{
				$this->traverse_xmlize($val, $arr_name . '[' . $key . ']', $level + 1);
			}
			else
			{
				echo '$' . $arr_name . '[' . $key . '] = "' . $val . "\"\n";
			}
		}
		if ($level == 0)
		{
			echo '';
		}
	}
}
/**
* @package phpBB3
* make_xml
* Currently not in use
*/
class make_xml extends jabber
{
	var $nodes;
	function make_xml()
	{
		$nodes = array();
	}
	function add_packet_details($string, $value = NULL)
	{
		if (preg_match('#\(([0-9]*)\)$#i', $string))
		{
			$string .= '/["#"]';
		}
		$temp = @explode('/', $string);
		for ($a = 0, $size = sizeof($temp); $a < $size; $a++)
		{
			$temp[$a] = preg_replace('#^[@]{1}([a-z0-9_]*)$#i', '["@"]["\1"]', $temp[$a]);
			$temp[$a] = preg_replace('#^([a-z0-9_]*)\(([0-9]*)\)$/i', '["\1"][\2]', $temp[$a]);
			$temp[$a] = preg_replace('#^([a-z0-9_]*)$#i', '["\1"]', $temp[$a]);
		}
		$node = implode('', $temp);
		// Yeahyeahyeah, I know it's ugly... get over it. ;)
		echo '$this->nodes' . $node . ' = "' . htmlspecialchars($value) . '";
';
		eval('$this->nodes' . $node . ' = "' . htmlspecialchars($value) . '";');
	}
	function build_packet($array = NULL)
	{
		if (!$array)
		{
			$array = $this->nodes;
		}
		if (is_array($array))
		{
			array_multisort($array, SORT_ASC, SORT_STRING);
			foreach ($array as $key => $value)
			{
				if (is_array($value) && $key == '@')
				{
					foreach ($value as $subkey => $subvalue)
					{
						$subvalue = htmlspecialchars($subvalue);
						$text .= " $subkey='$subvalue'";
					}
					$text .= ">\n";
				}
				elseif ($key == '#')
				{
					$text .= htmlspecialchars($value);
				}
				elseif (is_array($value))
				{
					for ($a = 0, $size = sizeof($value); $a < $size; $a++)
					{
						$text .= "<$key";
						if (!$this->_preg_grep_keys('#^@#', $value[$a]))
						{
							$text .= '>';
						}
						$text .= $this->build_packet($value[$a]);
						$text .= "$key>\n";
					}
				}
				else
				{
					$value = htmlspecialchars($value);
					$text .= "<$key>$value$key>\n";
				}
			}
			return $text;
		}
	}
	function _preg_grep_keys($pattern, $array)
	{
		foreach ($array as $key => $val)
		{
			if (preg_match($pattern, $key))
			{
				$newarray[$key] = $val;
			}
		}
		return (is_array($newarray)) ? $newarray : false;
	}
}
/**
* @package phpBB3
* connector
*/
class cjp_standard_connector
{
	var $active_socket;
	function open_socket($server, $port)
	{
		if ($this->active_socket = @fsockopen($server, $port, $err, $err2, 5))
		{
			@socket_set_blocking($this->active_socket, 0);
			@socket_set_timeout($this->active_socket, 31536000);
			return true;
		}
		else
		{
			return false;
		}
	}
	function close_socket()
	{
		return @fclose($this->active_socket);
	}
	function write_to_socket($data)
	{
		return @fwrite($this->active_socket, $data);
	}
	function read_from_socket($chunksize)
	{
		$buffer = stripslashes(@fread($this->active_socket, $chunksize));
		//@set_magic_quotes_runtime(get_magic_quotes_gpc());
		return $buffer;
	}
}
?>