MDL-16500 Removed the old Jabber class from the module and moved to a new one called...
authormoodler <moodler>
Mon, 15 Sep 2008 05:55:58 +0000 (05:55 +0000)
committermoodler <moodler>
Mon, 15 Sep 2008 05:55:58 +0000 (05:55 +0000)
           Also cleaned up some notices in message/edit.php

17 files changed:
lib/jabber/XMPP/Exception.php [new file with mode: 0755]
lib/jabber/XMPP/Log.php [new file with mode: 0644]
lib/jabber/XMPP/XMLObj.php [new file with mode: 0644]
lib/jabber/XMPP/XMLStream.php [new file with mode: 0644]
lib/jabber/XMPP/XMPP.php [new file with mode: 0644]
lib/jabber/XMPP/XMPP_Old.php [new file with mode: 0644]
message/edit.php
message/output/jabber/jabberclass/LICENSE [deleted file]
message/output/jabber/jabberclass/README [deleted file]
message/output/jabber/jabberclass/class_ConnectionSocket.php [deleted file]
message/output/jabber/jabberclass/class_Jabber.php [deleted file]
message/output/jabber/jabberclass/class_SHA1Library.php [deleted file]
message/output/jabber/jabberclass/class_XMLParser.php [deleted file]
message/output/jabber/jabberclass/jabber_example.php [deleted file]
message/output/jabber/message_output_jabber.php
message/output/jabber/version.php
version.php

diff --git a/lib/jabber/XMPP/Exception.php b/lib/jabber/XMPP/Exception.php
new file mode 100755 (executable)
index 0000000..32b2e09
--- /dev/null
@@ -0,0 +1,39 @@
+<?php
+/**
+ * XMPPHP: The PHP XMPP Library
+ * Copyright (C) 2008  Nathanael C. Fritz
+ * This file is part of SleekXMPP.
+ * 
+ * XMPPHP is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ * 
+ * XMPPHP is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License
+ * along with XMPPHP; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ *
+ * @category   xmpphp 
+ * @package    XMPPHP
+ * @author     Nathanael C. Fritz <JID: fritzy@netflint.net>
+ * @author     Stephan Wentz <JID: stephan@jabber.wentz.it>
+ * @copyright  2008 Nathanael C. Fritz
+ */
+
+/**
+ * XMPPHP Exception
+ *
+ * @category   xmpphp 
+ * @package    XMPPHP
+ * @author     Nathanael C. Fritz <JID: fritzy@netflint.net>
+ * @author     Stephan Wentz <JID: stephan@jabber.wentz.it>
+ * @copyright  2008 Nathanael C. Fritz
+ * @version    $Id$
+ */
+class XMPPHP_Exception extends Exception {
+}
diff --git a/lib/jabber/XMPP/Log.php b/lib/jabber/XMPP/Log.php
new file mode 100644 (file)
index 0000000..635e68d
--- /dev/null
@@ -0,0 +1,116 @@
+<?php
+/**
+ * XMPPHP: The PHP XMPP Library
+ * Copyright (C) 2008  Nathanael C. Fritz
+ * This file is part of SleekXMPP.
+ * 
+ * XMPPHP is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ * 
+ * XMPPHP is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License
+ * along with XMPPHP; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ *
+ * @category   xmpphp 
+ * @package    XMPPHP
+ * @author      Nathanael C. Fritz <JID: fritzy@netflint.net>
+ * @author      Stephan Wentz <JID: stephan@jabber.wentz.it>
+ * @copyright  2008 Nathanael C. Fritz
+ */
+
+/**
+ * XMPPHP Log
+ * 
+ * @package    XMPPHP
+ * @author      Nathanael C. Fritz <JID: fritzy@netflint.net>
+ * @author      Stephan Wentz <JID: stephan@jabber.wentz.it>
+ * @copyright  2008 Nathanael C. Fritz
+ * @version    $Id$
+ */
+class XMPPHP_Log {
+       
+       const LEVEL_ERROR   = 0;
+       const LEVEL_WARNING = 1;
+       const LEVEL_INFO        = 2;
+       const LEVEL_DEBUG   = 3;
+       const LEVEL_VERBOSE = 4;
+       
+       /**
+        * @var array
+        */
+       protected $data = array();
+
+       /**
+        * @var array
+        */
+       protected $names = array('ERROR', 'WARNING', 'INFO', 'DEBUG', 'VERBOSE');
+
+       /**
+        * @var integer
+        */
+       protected $runlevel;
+
+       /**
+        * @var boolean
+        */
+       protected $printout;
+
+       /**
+        * Constructor
+        *
+        * @param boolean $printout
+        * @param string  $runlevel
+        */
+       public function __construct($printout = false, $runlevel = self::LEVEL_INFO) {
+               $this->printout = (boolean)$printout;
+               $this->runlevel = (int)$runlevel;
+       }
+
+       /**
+        * Add a message to the log data array
+        * If printout in this instance is set to true, directly output the message
+        *
+        * @param string  $msg
+        * @param integer $runlevel
+        */
+       public function log($msg, $runlevel = self::LEVEL_INFO) {
+               $time = time();
+               $this->data[] = array($this->runlevel, $msg, $time);
+               if($this->printout and $runlevel <= $this->runlevel) {
+                       $this->writeLine($msg, $runlevel, $time);
+               }
+       }
+
+       /**
+        * Output the complete log.
+        * Log will be cleared if $clear = true
+        *
+        * @param boolean $clear
+        * @param integer $runlevel
+        */
+       public function printout($clear = true, $runlevel = null) {
+               if($runlevel === null) {
+                       $runlevel = $this->runlevel;
+               }
+               foreach($this->data as $data) {
+                       if($runlevel <= $data[0]) {
+                               $this->writeLine($data[1], $runlevel, $data[2]);
+                       }
+               }
+               if($clear) {
+                       $this->data = array();
+               }
+       }
+       
+       protected function writeLine($msg, $runlevel, $time) {
+               //echo date('Y-m-d H:i:s', $time)." [".$this->names[$runlevel]."]: ".$msg."\n";
+               echo $time." [".$this->names[$runlevel]."]: ".$msg."\n";
+       }
+}
diff --git a/lib/jabber/XMPP/XMLObj.php b/lib/jabber/XMPP/XMLObj.php
new file mode 100644 (file)
index 0000000..79fef9b
--- /dev/null
@@ -0,0 +1,155 @@
+<?php 
+/**
+ * XMPPHP: The PHP XMPP Library
+ * Copyright (C) 2008  Nathanael C. Fritz
+ * This file is part of SleekXMPP.
+ * 
+ * XMPPHP is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ * 
+ * XMPPHP is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License
+ * along with XMPPHP; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ *
+ * @category   xmpphp 
+ * @package    XMPPHP
+ * @author      Nathanael C. Fritz <JID: fritzy@netflint.net>
+ * @author      Stephan Wentz <JID: stephan@jabber.wentz.it>
+ * @copyright  2008 Nathanael C. Fritz
+ */
+
+/**
+ * XMPPHP XML Object
+ * 
+ * @category   xmpphp 
+ * @package    XMPPHP
+ * @author      Nathanael C. Fritz <JID: fritzy@netflint.net>
+ * @author      Stephan Wentz <JID: stephan@jabber.wentz.it>
+ * @copyright  2008 Nathanael C. Fritz
+ * @version    $Id$
+ */
+class XMPPHP_XMLObj {
+       /**
+        * Tag name
+        *
+        * @var string
+        */
+       public $name;
+       
+       /**
+        * Namespace
+        *
+        * @var string
+        */
+       public $ns;
+       
+       /**
+        * Attributes
+        *
+        * @var array
+        */
+       public $attrs = array();
+       
+       /**
+        * Subs?
+        *
+        * @var array
+        */
+       public $subs = array();
+       
+       /**
+        * Node data
+        * 
+        * @var string
+        */
+       public $data = '';
+
+       /**
+        * Constructor
+        *
+        * @param string $name
+        * @param string $ns
+        * @param array  $attrs
+        * @param string $data
+        */
+       public function __construct($name, $ns = '', $attrs = array(), $data = '') {
+               $this->name = strtolower($name);
+               $this->ns   = $ns;
+               if(is_array($attrs) && count($attrs)) {
+                       foreach($attrs as $key => $value) {
+                               $this->attrs[strtolower($key)] = $value;
+                       }
+               }
+               $this->data = $data;
+       }
+
+       /**
+        * Dump this XML Object to output.
+        *
+        * @param integer $depth
+        */
+       public function printObj($depth = 0) {
+               print str_repeat("\t", $depth) . $this->name . " " . $this->ns . ' ' . $this->data;
+               print "\n";
+               foreach($this->subs as $sub) {
+                       $sub->printObj($depth + 1);
+               }
+       }
+
+       /**
+        * Return this XML Object in xml notation
+        *
+        * @param string $str
+        */
+       public function toString($str = '') {
+               $str .= "<{$this->name} xmlns='{$this->ns}' ";
+               foreach($this->attrs as $key => $value) {
+                       if($key != 'xmlns') {
+                               $value = htmlspecialchars($value);
+                               $str .= "$key='$value' ";
+                       }
+               }
+               $str .= ">";
+               foreach($this->subs as $sub) {
+                       $str .= $sub->toString();
+               }
+               $body = htmlspecialchars($this->data);
+               $str .= "$body</{$this->name}>";
+               return $str;
+       }
+
+       /**
+        * Has this XML Object the given sub?
+        * 
+        * @param string $name
+        * @return boolean
+        */
+       public function hasSub($name) {
+               foreach($this->subs as $sub) {
+                       if($sub->name == $name) return true;
+               }
+               return false;
+       }
+
+       /**
+        * Return a sub
+        *
+        * @param string $name
+        * @param string $attrs
+        * @param string $ns
+        */
+       public function sub($name, $attrs = null, $ns = null) {
+               foreach($this->subs as $sub) {
+                       if($sub->name == $name) {
+                               return $sub;
+                       }
+               }
+       }
+}
diff --git a/lib/jabber/XMPP/XMLStream.php b/lib/jabber/XMPP/XMLStream.php
new file mode 100644 (file)
index 0000000..d3c59de
--- /dev/null
@@ -0,0 +1,604 @@
+<?php
+/**
+ * XMPPHP: The PHP XMPP Library
+ * Copyright (C) 2008  Nathanael C. Fritz
+ * This file is part of SleekXMPP.
+ * 
+ * XMPPHP is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ * 
+ * XMPPHP is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License
+ * along with XMPPHP; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ *
+ * @category   xmpphp 
+ * @package    XMPPHP
+ * @author      Nathanael C. Fritz <JID: fritzy@netflint.net>
+ * @author      Stephan Wentz <JID: stephan@jabber.wentz.it>
+ * @copyright  2008 Nathanael C. Fritz
+ */
+
+/** XMPPHP_Exception */
+require_once 'Exception.php';
+
+/** XMPPHP_XMLObj */
+require_once 'XMLObj.php';
+
+/** XMPPHP_Log */
+require_once 'Log.php';
+
+/**
+ * XMPPHP XML Stream
+ * 
+ * @category   xmpphp 
+ * @package    XMPPHP
+ * @author      Nathanael C. Fritz <JID: fritzy@netflint.net>
+ * @author      Stephan Wentz <JID: stephan@jabber.wentz.it>
+ * @copyright  2008 Nathanael C. Fritz
+ * @version    $Id$
+ */
+class XMPPHP_XMLStream {
+       /**
+        * @var resource
+        */
+       protected $socket;
+       /**
+        * @var resource
+        */
+       protected $parser;
+       /**
+        * @var string
+        */
+       protected $buffer;
+       /**
+        * @var integer
+        */
+       protected $xml_depth = 0;
+       /**
+        * @var string
+        */
+       protected $host;
+       /**
+        * @var integer
+        */
+       protected $port;
+       /**
+        * @var string
+        */
+       protected $stream_start = '<stream>';
+       /**
+        * @var string
+        */
+       protected $stream_end = '</stream>';
+       /**
+        * @var boolean
+        */
+       protected $disconnected = false;
+       /**
+        * @var boolean
+        */
+       protected $sent_disconnect = false;
+       /**
+        * @var array
+        */
+       protected $ns_map = array();
+       /**
+        * @var array
+        */
+       protected $current_ns = array();
+       /**
+        * @var array
+        */
+       protected $xmlobj = null;
+       /**
+        * @var array
+        */
+       protected $nshandlers = array();
+       /**
+        * @var array
+        */
+       protected $idhandlers = array();
+       /**
+        * @var array
+        */
+       protected $eventhandlers = array();
+       /**
+        * @var integer
+        */
+       protected $lastid = 0;
+       /**
+        * @var string
+        */
+       protected $default_ns;
+       /**
+        * @var string
+        */
+       protected $until = '';
+       /**
+        * @var array
+        */
+       protected $until_happened = false;
+       /**
+        * @var array
+        */
+       protected $until_payload = array();
+       /**
+        * @var XMPPHP_Log
+        */
+       protected $log;
+       /**
+        * @var boolean
+        */
+       protected $reconnect = true;
+       /**
+        * @var boolean
+        */
+       protected $been_reset = false;
+       /**
+        * @var boolean
+        */
+       protected $is_server;
+       /**
+        * @var float
+        */
+       protected $last_send = 0;
+
+       /**
+        * Constructor
+        *
+        * @param string  $host
+        * @param string  $port
+        * @param boolean $printlog
+        * @param string  $loglevel
+        * @param boolean $is_server
+        */
+       public function __construct($host = null, $port = null, $printlog = false, $loglevel = null, $is_server = false) {
+               $this->reconnect = !$is_server;
+               $this->is_server = $is_server;
+               $this->host = $host;
+               $this->port = $port;
+               $this->setupParser();
+               $this->log = new XMPPHP_Log($printlog, $loglevel);
+       }
+
+       /**
+        * Destructor
+        * Cleanup connection
+        */
+       public function __destruct() {
+               if(!$this->disconnected && $this->socket) {
+                       $this->disconnect();
+               }
+       }
+       
+       /**
+        * Return the log instance
+        *
+        * @return XMPPHP_Log
+        */
+       public function getLog() {
+               return $this->log;
+       }
+       
+       /**
+        * Get next ID
+        *
+        * @return integer
+        */
+       public function getId() {
+               $this->lastid++;
+               return $this->lastid;
+       }
+
+       /**
+        * Add ID Handler
+        *
+        * @param integer $id
+        * @param string  $pointer
+        * @param string  $obj
+        */
+       public function addIdHandler($id, $pointer, $obj = null) {
+               $this->idhandlers[$id] = array($pointer, $obj);
+       }
+
+       /**
+        * Add Handler
+        *
+        * @param integer $id
+        * @param string  $ns
+        * @param string  $pointer
+        * @param string  $obj
+        * @param integer $depth
+        */
+       public function addHandler($name, $ns, $pointer, $obj = null, $depth = 1) {
+               $this->nshandlers[] = array($name,$ns,$pointer,$obj, $depth);
+       }
+
+       /**
+        * Add Evemt Handler
+        *
+        * @param integer $id
+        * @param string  $pointer
+        * @param string  $obj
+        */
+       public function addEventHandler($name, $pointer, $obj) {
+               $this->eventhanders[] = array($name, $pointer, $obj);
+       }
+
+       /**
+        * Connect to XMPP Host
+        *
+        * @param integer $timeout
+        * @param boolean $persistent
+        * @param boolean $sendinit
+        */
+       public function connect($timeout = 30, $persistent = false, $sendinit = true) {
+               $this->disconnected = false;
+               $this->sent_disconnect = false;
+               if($persistent) {
+                       $conflag = STREAM_CLIENT_CONNECT | STREAM_CLIENT_PERSISTENT;
+               } else {
+                       $conflag = STREAM_CLIENT_CONNECT;
+               }
+               $this->log->log("Connecting to tcp://{$this->host}:{$this->port}");
+               try {
+                       $this->socket = @stream_socket_client("tcp://{$this->host}:{$this->port}", $errno, $errstr, $timeout, $conflag);
+               } catch (Exception $e) {
+                       throw new XMPPHP_Exception($e->getMessage());
+               }
+               if(!$this->socket) {
+                       $this->log->log("Could not connect.",  XMPPHP_Log::LEVEL_ERROR);
+                       $this->disconnected = true;
+                       
+                       throw new XMPPHP_Exception('Could not connect.');
+               }
+               stream_set_blocking($this->socket, 1);
+               if($sendinit) $this->send($this->stream_start);
+       }
+
+       /**
+        * Reconnect XMPP Host
+        */
+       public function doReconnect() {
+               if(!$this->is_server) {
+                       $this->log->log("Reconnecting...",  XMPPHP_Log::LEVEL_WARNING);
+                       $this->connect(30, false, false);
+                       $this->reset();
+               }
+       }
+
+       /**
+        * Disconnect from XMPP Host
+        */
+       public function disconnect() {
+               $this->log->log("Disconnecting...",  XMPPHP_Log::LEVEL_VERBOSE);
+               $this->reconnect = false;
+               $this->send($this->stream_end);
+               $this->sent_disconnect = true;
+               $this->processUntil('end_stream', 5);
+               $this->disconnected = true;
+       }
+
+       /**
+        * Are we are disconnected?
+        *
+        * @return boolean
+        */
+       public function isDisconnected() {
+               return $this->disconnected;
+       }
+
+       private function __process() {
+               $read = array($this->socket);
+               $write = null;
+               $except = null;
+               $updated = @stream_select($read, $write, $except, 1);
+               if ($updated > 0) {
+                       $buff = @fread($this->socket, 1024);
+                       if(!$buff) { 
+                               if($this->reconnect) {
+                                       $this->doReconnect();
+                               } else {
+                                       fclose($this->socket);
+                                       return false;
+                               }
+                       }
+                       $this->log->log("RECV: $buff",  XMPPHP_Log::LEVEL_VERBOSE);
+                       xml_parse($this->parser, $buff, false);
+               }
+       }
+       
+       /**
+        * Process
+        *
+        * @return string
+        */
+       public function process() {
+               $updated = '';
+               while(!$this->disconnect) {
+                       $this->__process();
+               }
+       }
+
+       /**
+        * Process until a timeout occurs
+        *
+        * @param integer $timeout
+        * @return string
+        */
+       public function processTime($timeout = -1) {
+               $start = time();
+               $updated = '';
+               while(!$this->disconnected and ($timeout == -1 or time() - $start < $timeout)) {
+                       $this->__process();
+               }
+       }
+
+       /**
+        * Process until a specified event or a timeout occurs
+        *
+        * @param string|array $event
+        * @param integer $timeout
+        * @return string
+        */
+       public function processUntil($event, $timeout=-1) {
+               $start = time();
+               if(!is_array($event)) $event = array($event);
+               $this->until[] = $event;
+               end($this->until);
+               $event_key = key($this->until);
+               reset($this->until);
+               $updated = '';
+               while(!$this->disconnected and $this->until[$event_key] and (time() - $start < $timeout or $timeout == -1)) {
+                       $this->__process();
+               }
+               if(array_key_exists($event_key, $this->until_payload)) {
+                       $payload = $this->until_payload[$event_key];
+               } else {
+                       $payload = array();
+               }
+               unset($this->until_payload[$event_key]);
+               return $payload;
+       }
+
+       /**
+        * Obsolete?
+        */
+       public function Xapply_socket($socket) {
+               $this->socket = $socket;
+       }
+
+       /**
+        * XML start callback
+        * 
+        * @see xml_set_element_handler
+        *
+        * @param resource $parser
+        * @param string   $name
+        */
+       public function startXML($parser, $name, $attr) {
+               if($this->been_reset) {
+                       $this->been_reset = false;
+                       $this->xml_depth = 0;
+               }
+               $this->xml_depth++;
+               if(array_key_exists('XMLNS', $attr)) {
+                       $this->current_ns[$this->xml_depth] = $attr['XMLNS'];
+               } else {
+                       $this->current_ns[$this->xml_depth] = $this->current_ns[$this->xml_depth - 1];
+                       if(!$this->current_ns[$this->xml_depth]) $this->current_ns[$this->xml_depth] = $this->default_ns;
+               }
+               $ns = $this->current_ns[$this->xml_depth];
+               foreach($attr as $key => $value) {
+                       if(strstr($key, ":")) {
+                               $key = explode(':', $key);
+                               $key = $key[1];
+                               $this->ns_map[$key] = $value;
+                       }
+               }
+               if(!strstr($name, ":") === false)
+               {
+                       $name = explode(':', $name);
+                       $ns = $this->ns_map[$name[0]];
+                       $name = $name[1];
+               }
+               $obj = new XMPPHP_XMLObj($name, $ns, $attr);
+               if($this->xml_depth > 1) {
+                       $this->xmlobj[$this->xml_depth - 1]->subs[] = $obj;
+               }
+               $this->xmlobj[$this->xml_depth] = $obj;
+       }
+
+       /**
+        * XML end callback
+        * 
+        * @see xml_set_element_handler
+        *
+        * @param resource $parser
+        * @param string   $name
+        */
+       public function endXML($parser, $name) {
+               #$this->log->log("Ending $name",  XMPPHP_Log::LEVEL_DEBUG);
+               #print "$name\n";
+               if($this->been_reset) {
+                       $this->been_reset = false;
+                       $this->xml_depth = 0;
+               }
+               $this->xml_depth--;
+               if($this->xml_depth == 1) {
+                       #clean-up old objects
+                       $found = false;
+                       foreach($this->nshandlers as $handler) {
+                               if($handler[4] != 1 and $this->xmlobj[2]->hasSub($handler[0])) {
+                                       $searchxml = $this->xmlobj[2]->sub($handler[0]);
+                               } elseif(is_array($this->xmlobj) and array_key_exists(2, $this->xmlobj)) {
+                                       $searchxml = $this->xmlobj[2];
+                               }
+                               if($searchxml !== null and $searchxml->name == $handler[0] and ($searchxml->ns == $handler[1] or (!$handler[1] and $searchxml->ns == $this->default_ns))) {
+                                       if($handler[3] === null) $handler[3] = $this;
+                                       $this->log->log("Calling {$handler[2]}",  XMPPHP_Log::LEVEL_DEBUG);
+                                       $handler[3]->$handler[2]($this->xmlobj[2]);
+                               }
+                       }
+                       foreach($this->idhandlers as $id => $handler) {
+                               if(array_key_exists('id', $this->xmlobj[2]->attrs) and $this->xmlobj[2]->attrs['id'] == $id) {
+                                       if($handler[1] === null) $handler[1] = $this;
+                                       $handler[1]->$handler[0]($this->xmlobj[2]);
+                                       #id handlers are only used once
+                                       unset($this->idhandlers[$id]);
+                                       break;
+                               }
+                       }
+                       if(is_array($this->xmlobj)) {
+                               $this->xmlobj = array_slice($this->xmlobj, 0, 1);
+                               if(isset($this->xmlobj[0]) && $this->xmlobj[0] instanceof XMPPHP_XMLObj) {
+                                       $this->xmlobj[0]->subs = null;
+                               }
+                       }
+                       unset($this->xmlobj[2]);
+               }
+               if($this->xml_depth == 0 and !$this->been_reset) {
+                       if(!$this->disconnected) {
+                               if(!$this->sent_disconnect) {
+                                       $this->send($this->stream_end);
+                               }
+                               $this->disconnected = true;
+                               $this->sent_disconnect = true;
+                               fclose($this->socket);
+                               if($this->reconnect) {
+                                       $this->doReconnect();
+                               }
+                       }
+                       $this->event('end_stream');
+               }
+       }
+
+       /**
+        * XML character callback
+        * @see xml_set_character_data_handler
+        *
+        * @param resource $parser
+        * @param string   $data
+        */
+       public function charXML($parser, $data) {
+               if(array_key_exists($this->xml_depth, $this->xmlobj)) {
+                       $this->xmlobj[$this->xml_depth]->data .= $data;
+               }
+       }
+
+       /**
+        * Event?
+        *
+        * @param string $name
+        * @param string $payload
+        */
+       public function event($name, $payload = null) {
+               $this->log->log("EVENT: $name",  XMPPHP_Log::LEVEL_DEBUG);
+               foreach($this->eventhandlers as $handler) {
+                       if($name == $handler[0]) {
+                               if($handler[2] === null) {
+                                       $handler[2] = $this;
+                               }
+                               $handler[2]->$handler[1]($payload);
+                       }
+               }
+               foreach($this->until as $key => $until) {
+                       if(is_array($until)) {
+                               if(in_array($name, $until)) {
+                                       $this->until_payload[$key][] = array($name, $payload);
+                                       $this->until[$key] = false;
+                               }
+                       }
+               }
+       }
+
+       /**
+        * Read from socket
+        */
+       public function read() {
+               $buff = @fread($this->socket, 1024);
+               if(!$buff) { 
+                       if($this->reconnect) {
+                               $this->doReconnect();
+                       } else {
+                               fclose($this->socket);
+                               return false;
+                       }
+               }
+               $this->log->log("RECV: $buff",  XMPPHP_Log::LEVEL_VERBOSE);
+               xml_parse($this->parser, $buff, false);
+       }
+
+       /**
+        * Send to socket
+        *
+        * @param string $msg
+        */
+       public function send($msg, $rec=false) {
+               if($this->time() - $this->last_send < .1) {
+                       usleep(100000);
+               }
+               $wait = true;
+               while($wait) {
+                       $read = null;
+                       $write = array($this->socket);
+                       $except = null;
+                       $select = @stream_select($read, $write, $except, 0, 0);
+                       if($select === False) {
+                               $this->doReconnect();
+                               return false;
+                       } elseif ($select > 0) {
+                               $wait = false;
+                       } else {
+                               usleep(100000);
+                               //$this->processTime(.25);
+                       }
+               }
+               $sentbytes = @fwrite($this->socket, $msg, 1024);
+               $this->last_send = $this->time();
+               $this->log->log("SENT: " . mb_substr($msg, 0, $sentbytes, '8bit'),  XMPPHP_Log::LEVEL_VERBOSE);
+               if($sentbytes === FALSE) {
+                       $this->doReconnect();
+               } elseif ($sentbytes != mb_strlen($msg, '8bit')) {
+                       $this->send(mb_substr($msg, $sentbytes, mb_strlen($msg, '8bit'), '8bit'), true);
+               }
+       }
+
+       public function time() {
+               list($usec, $sec) = explode(" ", microtime());
+               return (float)$sec + (float)$usec;
+       }
+
+       /**
+        * Reset connection
+        */
+       public function reset() {
+               $this->xml_depth = 0;
+               unset($this->xmlobj);
+               $this->xmlobj = array();
+               $this->setupParser();
+               if(!$this->is_server) {
+                       $this->send($this->stream_start);
+               }
+               $this->been_reset = true;
+       }
+
+       /**
+        * Setup the XML parser
+        */
+       public function setupParser() {
+               $this->parser = xml_parser_create('UTF-8');
+               xml_parser_set_option($this->parser, XML_OPTION_SKIP_WHITE, 1);
+               xml_parser_set_option($this->parser, XML_OPTION_TARGET_ENCODING, 'UTF-8');
+               xml_set_object($this->parser, $this);
+               xml_set_element_handler($this->parser, 'startXML', 'endXML');
+               xml_set_character_data_handler($this->parser, 'charXML');
+       }
+}
diff --git a/lib/jabber/XMPP/XMPP.php b/lib/jabber/XMPP/XMPP.php
new file mode 100644 (file)
index 0000000..5ba4095
--- /dev/null
@@ -0,0 +1,321 @@
+<?php
+/**
+ * XMPPHP: The PHP XMPP Library
+ * Copyright (C) 2008  Nathanael C. Fritz
+ * This file is part of SleekXMPP.
+ * 
+ * XMPPHP is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ * 
+ * XMPPHP is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License
+ * along with XMPPHP; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ *
+ * @category   xmpphp 
+ * @package    XMPPHP
+ * @author      Nathanael C. Fritz <JID: fritzy@netflint.net>
+ * @author      Stephan Wentz <JID: stephan@jabber.wentz.it>
+ * @copyright  2008 Nathanael C. Fritz
+ */
+
+/** XMPPHP_XMLStream */
+require_once "XMLStream.php";
+
+/**
+ * XMPPHP Main Class
+ * 
+ * @category   xmpphp 
+ * @package    XMPPHP
+ * @author      Nathanael C. Fritz <JID: fritzy@netflint.net>
+ * @author      Stephan Wentz <JID: stephan@jabber.wentz.it>
+ * @copyright  2008 Nathanael C. Fritz
+ * @version    $Id$
+ */
+class XMPPHP_XMPP extends XMPPHP_XMLStream {
+       /**
+        * @var string
+        */
+       protected $server;
+
+       /**
+        * @var string
+        */
+       protected $user;
+       
+       /**
+        * @var string
+        */
+       protected $password;
+       
+       /**
+        * @var string
+        */
+       protected $resource;
+       
+       /**
+        * @var string
+        */
+       protected $fulljid;
+       
+       /**
+        * @var string
+        */
+       protected $basejid;
+       
+       /**
+        * @var boolean
+        */
+       protected $authed = false;
+       
+       /**
+        * @var boolean
+        */
+       protected $auto_subscribe = false;
+       
+       /**
+        * @var boolean
+        */
+       protected $use_encryption = true;
+       
+       /**
+        * Constructor
+        *
+        * @param string  $host
+        * @param integer $port
+        * @param string  $user
+        * @param string  $password
+        * @param string  $resource
+        * @param string  $server
+        * @param boolean $printlog
+        * @param string  $loglevel
+        */
+       public function __construct($host, $port, $user, $password, $resource, $server = null, $printlog = false, $loglevel = null) {
+               parent::__construct($host, $port, $printlog, $loglevel);
+               
+               $this->user      = $user;
+               $this->password = $password;
+               $this->resource = $resource;
+               if(!$server) $server = $host;
+               $this->basejid = $this->user . '@' . $this->host;
+
+               $this->stream_start = '<stream:stream to="' . $server . '" xmlns:stream="http://etherx.jabber.org/streams" xmlns="jabber:client" version="1.0">';
+               $this->stream_end   = '</stream:stream>';
+               $this->default_ns   = 'jabber:client';
+               
+               $this->addHandler('features', 'http://etherx.jabber.org/streams', 'features_handler');
+               $this->addHandler('success', 'urn:ietf:params:xml:ns:xmpp-sasl', 'sasl_success_handler');
+               $this->addHandler('failure', 'urn:ietf:params:xml:ns:xmpp-sasl', 'sasl_failure_handler');
+               $this->addHandler('proceed', 'urn:ietf:params:xml:ns:xmpp-tls', 'tls_proceed_handler');
+               $this->addHandler('message', 'jabber:client', 'message_handler');
+               $this->addHandler('presence', 'jabber:client', 'presence_handler');
+       }
+
+       /**
+        * Turn encryption on/ff
+        *
+        * @param boolean $useEncryption
+        */
+       public function useEncryption($useEncryption = true) {
+               $this->use_encryption = $useEncryption;
+       }
+       
+       /**
+        * Turn on auto-authorization of subscription requests.
+        *
+        * @param boolean $autoSubscribe
+        */
+       public function autoSubscribe($autoSubscribe = true) {
+               $this->auto_subscribe = $autoSubscribe;
+       }
+
+       /**
+        * Send XMPP Message
+        *
+        * @param string $to
+        * @param string $body
+        * @param string $type
+        * @param string $subject
+        */
+       public function message($to, $body, $type = 'chat', $subject = null, $payload = null) {
+               $to       = htmlspecialchars($to);
+               $body   = htmlspecialchars($body);
+               $subject = htmlspecialchars($subject);
+               
+               $out = "<message from='{$this->fulljid}' to='$to' type='$type'>";
+               if($subject) $out .= "<subject>$subject</subject>";
+               $out .= "<body>$body</body>";
+               if($payload) $out .= $payload;
+               $out .= "</message>";
+               
+               $this->send($out);
+       }
+
+       /**
+        * Set Presence
+        *
+        * @param string $status
+        * @param string $show
+        * @param string $to
+        */
+       public function presence($status = null, $show = 'available', $to = null, $type='available') {
+               if($type == 'available') $type = '';
+               $to      = htmlspecialchars($to);
+               $status = htmlspecialchars($status);
+               if($show == 'unavailable') $type = 'unavailable';
+               
+               $out = "<presence";
+               if($to) $out .= " to='$to'";
+               if($type) $out .= " type='$type'";
+               if($show == 'available' and !$status) {
+                       $out .= "/>";
+               } else {
+                       $out .= ">";
+                       if($show != 'available') $out .= "<show>$show</show>";
+                       if($status) $out .= "<status>$status</status>";
+                       $out .= "</presence>";
+               }
+               
+               $this->send($out);
+       }
+
+       /**
+        * Message handler
+        *
+        * @param string $xml
+        */
+       public function message_handler($xml) {
+               if(isset($xml->attrs['type'])) {
+                       $payload['type'] = $xml->attrs['type'];
+               } else {
+                       $payload['type'] = 'chat';
+               }
+               $payload['from'] = $xml->attrs['from'];
+               $payload['body'] = $xml->sub('body')->data;
+               $this->log->log("Message: {$xml->sub('body')->data}", XMPPHP_Log::LEVEL_DEBUG);
+               $this->event('message', $payload);
+       }
+
+       /**
+        * Presence handler
+        *
+        * @param string $xml
+        */
+       public function presence_handler($xml) {
+               $payload['type'] = (isset($xml->attrs['type'])) ? $xml->attrs['type'] : 'available';
+               $payload['show'] = (isset($xml->sub('show')->data)) ? $xml->sub('show')->data : $payload['type'];
+               $payload['from'] = $xml->attrs['from'];
+               $payload['status'] = (isset($xml->sub('status')->data)) ? $xml->sub('status')->data : '';
+               $this->log->log("Presence: {$payload['from']} [{$payload['show']}] {$payload['status']}",  XMPPHP_Log::LEVEL_DEBUG);
+               if($xml->attrs['type'] == 'subscribe') {
+                       if($this->auto_subscribe) $this->send("<presence type='subscribed' to='{$xml->attrs['from']}' from='{$this->fulljid}' /><presence type='subscribe' to='{$xml->attrs['from']}' from='{$this->fulljid}' />");
+                       $this->event('subscription_requested', $payload);
+               } elseif($xml->attrs['type'] == 'subscribed') {
+                       $this->event('subscription_accepted', $payload);
+               } else {
+                       $this->event('presence', $payload);
+               }
+       }
+
+       /**
+        * Features handler
+        *
+        * @param string $xml
+        */
+       protected function features_handler($xml) {
+               if($xml->hasSub('starttls') and $this->use_encryption) {
+                       $this->send("<starttls xmlns='urn:ietf:params:xml:ns:xmpp-tls'><required /></starttls>");
+               } elseif($xml->hasSub('bind')) {
+                       $id = $this->getId();
+                       $this->addIdHandler($id, 'resource_bind_handler');
+                       $this->send("<iq xmlns=\"jabber:client\" type=\"set\" id=\"$id\"><bind xmlns=\"urn:ietf:params:xml:ns:xmpp-bind\"><resource>{$this->resource}</resource></bind></iq>");
+               } else {
+                       $this->log->log("Attempting Auth...");
+                       $this->send("<auth xmlns='urn:ietf:params:xml:ns:xmpp-sasl' mechanism='PLAIN'>" . base64_encode("\x00" . $this->user . "\x00" . $this->password) . "</auth>");
+               }
+       }
+
+       /**
+        * SASL success handler
+        *
+        * @param string $xml
+        */
+       protected function sasl_success_handler($xml) {
+               $this->log->log("Auth success!");
+               $this->authed = true;
+               $this->reset();
+       }
+       
+       /**
+        * SASL feature handler
+        *
+        * @param string $xml
+        */
+       protected function sasl_failure_handler($xml) {
+               $this->log->log("Auth failed!",  XMPPHP_Log::LEVEL_ERROR);
+               $this->disconnect();
+               
+               throw new XMPPHP_Exception('Auth failed!');
+       }
+
+       /**
+        * Resource bind handler
+        *
+        * @param string $xml
+        */
+       protected function resource_bind_handler($xml) {
+               if($xml->attrs['type'] == 'result') {
+                       $this->log->log("Bound to " . $xml->sub('bind')->sub('jid')->data);
+                       $this->fulljid = $xml->sub('bind')->sub('jid')->data;
+               }
+               $id = $this->getId();
+               $this->addIdHandler($id, 'session_start_handler');
+               $this->send("<iq xmlns='jabber:client' type='set' id='$id'><session xmlns='urn:ietf:params:xml:ns:xmpp-session' /></iq>");
+       }
+
+       /**
+       * Retrieves the roster
+       *
+       */
+       public function getRoster() {
+               $id = $this->getID();
+               $this->addIdHandler($id, 'roster_get_handler');
+               $this->send("<iq xmlns='jabber:client' type='get' id='$id'><query xmlns='jabber:iq:roster' /></iq>");
+       }
+
+       /**
+       * Roster retrieval handler
+       *
+       * @param string $xml
+       */
+       protected function roster_get_handler($xml) {
+               // TODO: make this work
+       }
+
+       /**
+        * Session start handler
+        *
+        * @param string $xml
+        */
+       protected function session_start_handler($xml) {
+               $this->log->log("Session started");
+               $this->event('session_start');
+       }
+
+       /**
+        * TLS proceed handler
+        *
+        * @param string $xml
+        */
+       protected function tls_proceed_handler($xml) {
+               $this->log->log("Starting TLS encryption");
+               stream_socket_enable_crypto($this->socket, true, STREAM_CRYPTO_METHOD_SSLv23_CLIENT);
+               $this->reset();
+       }
+}
diff --git a/lib/jabber/XMPP/XMPP_Old.php b/lib/jabber/XMPP/XMPP_Old.php
new file mode 100644 (file)
index 0000000..ab0466e
--- /dev/null
@@ -0,0 +1,111 @@
+<?php
+/**
+ * XMPPHP: The PHP XMPP Library
+ * Copyright (C) 2008  Nathanael C. Fritz
+ * This file is part of SleekXMPP.
+ * 
+ * XMPPHP is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ * 
+ * XMPPHP is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License
+ * along with XMPPHP; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ *
+ * @category   xmpphp 
+ * @package    XMPPHP
+ * @author      Nathanael C. Fritz <JID: fritzy@netflint.net>
+ * @author      Stephan Wentz <JID: stephan@jabber.wentz.it>
+ * @copyright  2008 Nathanael C. Fritz
+ */
+
+/** XMPPHP_XMPP 
+ *
+ * This file is unnecessary unless you need to connect to older, non-XMPP-compliant servers like Dreamhost's.
+ * In this case, use instead of XMPPHP_XMPP, otherwise feel free to delete it.
+ * The old Jabber protocol wasn't standardized, so use at your own risk.
+ *
+ */
+require_once "XMPP.php";
+
+       class XMPPHP_XMPPOld extends XMPPHP_XMPP {
+               /**
+                *
+                * @var string
+                */
+               protected $session_id;
+
+               public function __construct($host, $port, $user, $password, $resource, $server = null, $printlog = false, $loglevel = null) {
+                       parent::__construct($host, $port, $user, $password, $resource, $server, $printlog, $loglevel);
+
+               }
+       
+               /**
+                * Override XMLStream's startXML
+                *
+                * @param parser $parser
+                * @param string $name
+                * @param array $attr
+                */
+               protected function startXML($parser, $name, $attr) {
+                       if($this->xml_depth == 0 and $attr['version'] != '1.0') {
+                               $this->session_id = $attr['ID'];
+                               $this->authenticate();
+                       }
+                       parent::startXML($parser, $name, $attr);
+               }
+
+               /**
+                * Send Authenticate Info Request
+                *
+                */
+               public function authenticate() {
+                       $id = $this->getId();
+                       $this->addidhandler($id, 'authfieldshandler');
+                       $this->send("<iq type='get' id='$id'><query xmlns='jabber:iq:auth'><username>{$this->user}</username></query></iq>");
+               }
+
+               /**
+                * Retrieve auth fields and send auth attempt
+                *
+                * @param XMLObj $xml
+                */
+               public function authFieldsHandler($xml) {
+                       $id = $this->getId();
+                       $this->addidhandler($id, 'oldAuthResultHandler');
+                       if($xml->sub('query')->hasSub('digest')) {
+                               $hash = sha1($this->session_id . $this->password);
+                               print "{$this->session_id} {$this->password}\n";
+                               $out = "<iq type='set' id='$id'><query xmlns='jabber:iq:auth'><username>{$this->user}</username><digest>{$hash}</digest><resource>{$this->resource}</resource></query></iq>";
+                       } else {
+                               $out = "<iq type='set' id='$id'><query xmlns='jabber:iq:auth'><username>{$this->user}</username><digest>{$this->password}</digest><resource>{$this->resource}</resource></query></iq>";
+                       }
+                       $this->send($out);
+
+               }
+               
+               /**
+                * Determine authenticated or failure
+                *
+                * @param XMLObj $xml
+                */
+               public function oldAuthResultHandler($xml) {
+                       if($xml->attrs['type'] != 'result') {
+                               $this->log->log("Auth failed!",  XMPPHP_Log::LEVEL_ERROR);
+                               $this->disconnect();
+                               throw new XMPPHP_Exception('Auth failed!');
+                       } else {
+                               $this->log->log("Session started");
+                               $this->event('session_start');
+                       }
+               }
+       }
+
+
+?>
index 34b7f87..4d012bc 100644 (file)
@@ -230,8 +230,14 @@ foreach ( $providers as $providerid => $provider){
     foreach (array('loggedin', 'loggedoff') as $state){
         $state_res = get_string($state, 'message');
         echo '<tr><td align="right">'.$state_res.'</td>'."\n";
-        foreach ( $processors as $processorid => $processor){
-            $checked = $preferences->{$provider->component.'_'.$provider->name.'_'.$state}[$processor->name]==1?" checked=\"checked\"":"";            
+        foreach ( $processors as $processorid => $processor) {
+            if (!isset($preferences->{$provider->component.'_'.$provider->name.'_'.$state})) {
+                $checked = '';
+            } else if (!isset($preferences->{$provider->component.'_'.$provider->name.'_'.$state}[$processor->name])) {
+                $checked = '';
+            } else {
+                $checked = $preferences->{$provider->component.'_'.$provider->name.'_'.$state}[$processor->name]==1?" checked=\"checked\"":"";            
+            }
             echo '<td align="center"><input type="checkbox" name="'.$provider->component.'_'.$provider->name.'_'.$state.'['.$processor->name.']" '.$checked.' /></td>'."\n";
         }
         echo '</tr>'."\n";
diff --git a/message/output/jabber/jabberclass/LICENSE b/message/output/jabber/jabberclass/LICENSE
deleted file mode 100644 (file)
index cbee875..0000000
+++ /dev/null
@@ -1,504 +0,0 @@
-                 GNU LESSER GENERAL PUBLIC LICENSE\r
-                      Version 2.1, February 1999\r
-\r
- Copyright (C) 1991, 1999 Free Software Foundation, Inc.\r
-     59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\r
- Everyone is permitted to copy and distribute verbatim copies\r
- of this license document, but changing it is not allowed.\r
-\r
-[This is the first released version of the Lesser GPL.  It also counts\r
- as the successor of the GNU Library Public License, version 2, hence\r
- the version number 2.1.]\r
-\r
-                           Preamble\r
-\r
-  The licenses for most software are designed to take away your\r
-freedom to share and change it.  By contrast, the GNU General Public\r
-Licenses are intended to guarantee your freedom to share and change\r
-free software--to make sure the software is free for all its users.\r
-\r
-  This license, the Lesser General Public License, applies to some\r
-specially designated software packages--typically libraries--of the\r
-Free Software Foundation and other authors who decide to use it.  You\r
-can use it too, but we suggest you first think carefully about whether\r
-this license or the ordinary General Public License is the better\r
-strategy to use in any particular case, based on the explanations below.\r
-\r
-  When we speak of free software, we are referring to freedom of use,\r
-not price.  Our General Public Licenses are designed to make sure that\r
-you have the freedom to distribute copies of free software (and charge\r
-for this service if you wish); that you receive source code or can get\r
-it if you want it; that you can change the software and use pieces of\r
-it in new free programs; and that you are informed that you can do\r
-these things.\r
-\r
-  To protect your rights, we need to make restrictions that forbid\r
-distributors to deny you these rights or to ask you to surrender these\r
-rights.  These restrictions translate to certain responsibilities for\r
-you if you distribute copies of the library or if you modify it.\r
-\r
-  For example, if you distribute copies of the library, whether gratis\r
-or for a fee, you must give the recipients all the rights that we gave\r
-you.  You must make sure that they, too, receive or can get the source\r
-code.  If you link other code with the library, you must provide\r
-complete object files to the recipients, so that they can relink them\r
-with the library after making changes to the library and recompiling\r
-it.  And you must show them these terms so they know their rights.\r
-\r
-  We protect your rights with a two-step method: (1) we copyright the\r
-library, and (2) we offer you this license, which gives you legal\r
-permission to copy, distribute and/or modify the library.\r
-\r
-  To protect each distributor, we want to make it very clear that\r
-there is no warranty for the free library.  Also, if the library is\r
-modified by someone else and passed on, the recipients should know\r
-that what they have is not the original version, so that the original\r
-author's reputation will not be affected by problems that might be\r
-introduced by others.\r
-\f\r
-  Finally, software patents pose a constant threat to the existence of\r
-any free program.  We wish to make sure that a company cannot\r
-effectively restrict the users of a free program by obtaining a\r
-restrictive license from a patent holder.  Therefore, we insist that\r
-any patent license obtained for a version of the library must be\r
-consistent with the full freedom of use specified in this license.\r
-\r
-  Most GNU software, including some libraries, is covered by the\r
-ordinary GNU General Public License.  This license, the GNU Lesser\r
-General Public License, applies to certain designated libraries, and\r
-is quite different from the ordinary General Public License.  We use\r
-this license for certain libraries in order to permit linking those\r
-libraries into non-free programs.\r
-\r
-  When a program is linked with a library, whether statically or using\r
-a shared library, the combination of the two is legally speaking a\r
-combined work, a derivative of the original library.  The ordinary\r
-General Public License therefore permits such linking only if the\r
-entire combination fits its criteria of freedom.  The Lesser General\r
-Public License permits more lax criteria for linking other code with\r
-the library.\r
-\r
-  We call this license the "Lesser" General Public License because it\r
-does Less to protect the user's freedom than the ordinary General\r
-Public License.  It also provides other free software developers Less\r
-of an advantage over competing non-free programs.  These disadvantages\r
-are the reason we use the ordinary General Public License for many\r
-libraries.  However, the Lesser license provides advantages in certain\r
-special circumstances.\r
-\r
-  For example, on rare occasions, there may be a special need to\r
-encourage the widest possible use of a certain library, so that it becomes\r
-a de-facto standard.  To achieve this, non-free programs must be\r
-allowed to use the library.  A more frequent case is that a free\r
-library does the same job as widely used non-free libraries.  In this\r
-case, there is little to gain by limiting the free library to free\r
-software only, so we use the Lesser General Public License.\r
-\r
-  In other cases, permission to use a particular library in non-free\r
-programs enables a greater number of people to use a large body of\r
-free software.  For example, permission to use the GNU C Library in\r
-non-free programs enables many more people to use the whole GNU\r
-operating system, as well as its variant, the GNU/Linux operating\r
-system.\r
-\r
-  Although the Lesser General Public License is Less protective of the\r
-users' freedom, it does ensure that the user of a program that is\r
-linked with the Library has the freedom and the wherewithal to run\r
-that program using a modified version of the Library.\r
-\r
-  The precise terms and conditions for copying, distribution and\r
-modification follow.  Pay close attention to the difference between a\r
-"work based on the library" and a "work that uses the library".  The\r
-former contains code derived from the library, whereas the latter must\r
-be combined with the library in order to run.\r
-\f\r
-                 GNU LESSER GENERAL PUBLIC LICENSE\r
-   TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION\r
-\r
-  0. This License Agreement applies to any software library or other\r
-program which contains a notice placed by the copyright holder or\r
-other authorized party saying it may be distributed under the terms of\r
-this Lesser General Public License (also called "this License").\r
-Each licensee is addressed as "you".\r
-\r
-  A "library" means a collection of software functions and/or data\r
-prepared so as to be conveniently linked with application programs\r
-(which use some of those functions and data) to form executables.\r
-\r
-  The "Library", below, refers to any such software library or work\r
-which has been distributed under these terms.  A "work based on the\r
-Library" means either the Library or any derivative work under\r
-copyright law: that is to say, a work containing the Library or a\r
-portion of it, either verbatim or with modifications and/or translated\r
-straightforwardly into another language.  (Hereinafter, translation is\r
-included without limitation in the term "modification".)\r
-\r
-  "Source code" for a work means the preferred form of the work for\r
-making modifications to it.  For a library, complete source code means\r
-all the source code for all modules it contains, plus any associated\r
-interface definition files, plus the scripts used to control compilation\r
-and installation of the library.\r
-\r
-  Activities other than copying, distribution and modification are not\r
-covered by this License; they are outside its scope.  The act of\r
-running a program using the Library is not restricted, and output from\r
-such a program is covered only if its contents constitute a work based\r
-on the Library (independent of the use of the Library in a tool for\r
-writing it).  Whether that is true depends on what the Library does\r
-and what the program that uses the Library does.\r
-  \r
-  1. You may copy and distribute verbatim copies of the Library's\r
-complete source code as you receive it, in any medium, provided that\r
-you conspicuously and appropriately publish on each copy an\r
-appropriate copyright notice and disclaimer of warranty; keep intact\r
-all the notices that refer to this License and to the absence of any\r
-warranty; and distribute a copy of this License along with the\r
-Library.\r
-\r
-  You may charge a fee for the physical act of transferring a copy,\r
-and you may at your option offer warranty protection in exchange for a\r
-fee.\r
-\f\r
-  2. You may modify your copy or copies of the Library or any portion\r
-of it, thus forming a work based on the Library, and copy and\r
-distribute such modifications or work under the terms of Section 1\r
-above, provided that you also meet all of these conditions:\r
-\r
-    a) The modified work must itself be a software library.\r
-\r
-    b) You must cause the files modified to carry prominent notices\r
-    stating that you changed the files and the date of any change.\r
-\r
-    c) You must cause the whole of the work to be licensed at no\r
-    charge to all third parties under the terms of this License.\r
-\r
-    d) If a facility in the modified Library refers to a function or a\r
-    table of data to be supplied by an application program that uses\r
-    the facility, other than as an argument passed when the facility\r
-    is invoked, then you must make a good faith effort to ensure that,\r
-    in the event an application does not supply such function or\r
-    table, the facility still operates, and performs whatever part of\r
-    its purpose remains meaningful.\r
-\r
-    (For example, a function in a library to compute square roots has\r
-    a purpose that is entirely well-defined independent of the\r
-    application.  Therefore, Subsection 2d requires that any\r
-    application-supplied function or table used by this function must\r
-    be optional: if the application does not supply it, the square\r
-    root function must still compute square roots.)\r
-\r
-These requirements apply to the modified work as a whole.  If\r
-identifiable sections of that work are not derived from the Library,\r
-and can be reasonably considered independent and separate works in\r
-themselves, then this License, and its terms, do not apply to those\r
-sections when you distribute them as separate works.  But when you\r
-distribute the same sections as part of a whole which is a work based\r
-on the Library, the distribution of the whole must be on the terms of\r
-this License, whose permissions for other licensees extend to the\r
-entire whole, and thus to each and every part regardless of who wrote\r
-it.\r
-\r
-Thus, it is not the intent of this section to claim rights or contest\r
-your rights to work written entirely by you; rather, the intent is to\r
-exercise the right to control the distribution of derivative or\r
-collective works based on the Library.\r
-\r
-In addition, mere aggregation of another work not based on the Library\r
-with the Library (or with a work based on the Library) on a volume of\r
-a storage or distribution medium does not bring the other work under\r
-the scope of this License.\r
-\r
-  3. You may opt to apply the terms of the ordinary GNU General Public\r
-License instead of this License to a given copy of the Library.  To do\r
-this, you must alter all the notices that refer to this License, so\r
-that they refer to the ordinary GNU General Public License, version 2,\r
-instead of to this License.  (If a newer version than version 2 of the\r
-ordinary GNU General Public License has appeared, then you can specify\r
-that version instead if you wish.)  Do not make any other change in\r
-these notices.\r
-\f\r
-  Once this change is made in a given copy, it is irreversible for\r
-that copy, so the ordinary GNU General Public License applies to all\r
-subsequent copies and derivative works made from that copy.\r
-\r
-  This option is useful when you wish to copy part of the code of\r
-the Library into a program that is not a library.\r
-\r
-  4. You may copy and distribute the Library (or a portion or\r
-derivative of it, under Section 2) in object code or executable form\r
-under the terms of Sections 1 and 2 above provided that you accompany\r
-it with the complete corresponding machine-readable source code, which\r
-must be distributed under the terms of Sections 1 and 2 above on a\r
-medium customarily used for software interchange.\r
-\r
-  If distribution of object code is made by offering access to copy\r
-from a designated place, then offering equivalent access to copy the\r
-source code from the same place satisfies the requirement to\r
-distribute the source code, even though third parties are not\r
-compelled to copy the source along with the object code.\r
-\r
-  5. A program that contains no derivative of any portion of the\r
-Library, but is designed to work with the Library by being compiled or\r
-linked with it, is called a "work that uses the Library".  Such a\r
-work, in isolation, is not a derivative work of the Library, and\r
-therefore falls outside the scope of this License.\r
-\r
-  However, linking a "work that uses the Library" with the Library\r
-creates an executable that is a derivative of the Library (because it\r
-contains portions of the Library), rather than a "work that uses the\r
-library".  The executable is therefore covered by this License.\r
-Section 6 states terms for distribution of such executables.\r
-\r
-  When a "work that uses the Library" uses material from a header file\r
-that is part of the Library, the object code for the work may be a\r
-derivative work of the Library even though the source code is not.\r
-Whether this is true is especially significant if the work can be\r
-linked without the Library, or if the work is itself a library.  The\r
-threshold for this to be true is not precisely defined by law.\r
-\r
-  If such an object file uses only numerical parameters, data\r
-structure layouts and accessors, and small macros and small inline\r
-functions (ten lines or less in length), then the use of the object\r
-file is unrestricted, regardless of whether it is legally a derivative\r
-work.  (Executables containing this object code plus portions of the\r
-Library will still fall under Section 6.)\r
-\r
-  Otherwise, if the work is a derivative of the Library, you may\r
-distribute the object code for the work under the terms of Section 6.\r
-Any executables containing that work also fall under Section 6,\r
-whether or not they are linked directly with the Library itself.\r
-\f\r
-  6. As an exception to the Sections above, you may also combine or\r
-link a "work that uses the Library" with the Library to produce a\r
-work containing portions of the Library, and distribute that work\r
-under terms of your choice, provided that the terms permit\r
-modification of the work for the customer's own use and reverse\r
-engineering for debugging such modifications.\r
-\r
-  You must give prominent notice with each copy of the work that the\r
-Library is used in it and that the Library and its use are covered by\r
-this License.  You must supply a copy of this License.  If the work\r
-during execution displays copyright notices, you must include the\r
-copyright notice for the Library among them, as well as a reference\r
-directing the user to the copy of this License.  Also, you must do one\r
-of these things:\r
-\r
-    a) Accompany the work with the complete corresponding\r
-    machine-readable source code for the Library including whatever\r
-    changes were used in the work (which must be distributed under\r
-    Sections 1 and 2 above); and, if the work is an executable linked\r
-    with the Library, with the complete machine-readable "work that\r
-    uses the Library", as object code and/or source code, so that the\r
-    user can modify the Library and then relink to produce a modified\r
-    executable containing the modified Library.  (It is understood\r
-    that the user who changes the contents of definitions files in the\r
-    Library will not necessarily be able to recompile the application\r
-    to use the modified definitions.)\r
-\r
-    b) Use a suitable shared library mechanism for linking with the\r
-    Library.  A suitable mechanism is one that (1) uses at run time a\r
-    copy of the library already present on the user's computer system,\r
-    rather than copying library functions into the executable, and (2)\r
-    will operate properly with a modified version of the library, if\r
-    the user installs one, as long as the modified version is\r
-    interface-compatible with the version that the work was made with.\r
-\r
-    c) Accompany the work with a written offer, valid for at\r
-    least three years, to give the same user the materials\r
-    specified in Subsection 6a, above, for a charge no more\r
-    than the cost of performing this distribution.\r
-\r
-    d) If distribution of the work is made by offering access to copy\r
-    from a designated place, offer equivalent access to copy the above\r
-    specified materials from the same place.\r
-\r
-    e) Verify that the user has already received a copy of these\r
-    materials or that you have already sent this user a copy.\r
-\r
-  For an executable, the required form of the "work that uses the\r
-Library" must include any data and utility programs needed for\r
-reproducing the executable from it.  However, as a special exception,\r
-the materials to be distributed need not include anything that is\r
-normally distributed (in either source or binary form) with the major\r
-components (compiler, kernel, and so on) of the operating system on\r
-which the executable runs, unless that component itself accompanies\r
-the executable.\r
-\r
-  It may happen that this requirement contradicts the license\r
-restrictions of other proprietary libraries that do not normally\r
-accompany the operating system.  Such a contradiction means you cannot\r
-use both them and the Library together in an executable that you\r
-distribute.\r
-\f\r
-  7. You may place library facilities that are a work based on the\r
-Library side-by-side in a single library together with other library\r
-facilities not covered by this License, and distribute such a combined\r
-library, provided that the separate distribution of the work based on\r
-the Library and of the other library facilities is otherwise\r
-permitted, and provided that you do these two things:\r
-\r
-    a) Accompany the combined library with a copy of the same work\r
-    based on the Library, uncombined with any other library\r
-    facilities.  This must be distributed under the terms of the\r
-    Sections above.\r
-\r
-    b) Give prominent notice with the combined library of the fact\r
-    that part of it is a work based on the Library, and explaining\r
-    where to find the accompanying uncombined form of the same work.\r
-\r
-  8. You may not copy, modify, sublicense, link with, or distribute\r
-the Library except as expressly provided under this License.  Any\r
-attempt otherwise to copy, modify, sublicense, link with, or\r
-distribute the Library is void, and will automatically terminate your\r
-rights under this License.  However, parties who have received copies,\r
-or rights, from you under this License will not have their licenses\r
-terminated so long as such parties remain in full compliance.\r
-\r
-  9. You are not required to accept this License, since you have not\r
-signed it.  However, nothing else grants you permission to modify or\r
-distribute the Library or its derivative works.  These actions are\r
-prohibited by law if you do not accept this License.  Therefore, by\r
-modifying or distributing the Library (or any work based on the\r
-Library), you indicate your acceptance of this License to do so, and\r
-all its terms and conditions for copying, distributing or modifying\r
-the Library or works based on it.\r
-\r
-  10. Each time you redistribute the Library (or any work based on the\r
-Library), the recipient automatically receives a license from the\r
-original licensor to copy, distribute, link with or modify the Library\r
-subject to these terms and conditions.  You may not impose any further\r
-restrictions on the recipients' exercise of the rights granted herein.\r
-You are not responsible for enforcing compliance by third parties with\r
-this License.\r
-\f\r
-  11. If, as a consequence of a court judgment or allegation of patent\r
-infringement or for any other reason (not limited to patent issues),\r
-conditions are imposed on you (whether by court order, agreement or\r
-otherwise) that contradict the conditions of this License, they do not\r
-excuse you from the conditions of this License.  If you cannot\r
-distribute so as to satisfy simultaneously your obligations under this\r
-License and any other pertinent obligations, then as a consequence you\r
-may not distribute the Library at all.  For example, if a patent\r
-license would not permit royalty-free redistribution of the Library by\r
-all those who receive copies directly or indirectly through you, then\r
-the only way you could satisfy both it and this License would be to\r
-refrain entirely from distribution of the Library.\r
-\r
-If any portion of this section is held invalid or unenforceable under any\r
-particular circumstance, the balance of the section is intended to apply,\r
-and the section as a whole is intended to apply in other circumstances.\r
-\r
-It is not the purpose of this section to induce you to infringe any\r
-patents or other property right claims or to contest validity of any\r
-such claims; this section has the sole purpose of protecting the\r
-integrity of the free software distribution system which is\r
-implemented by public license practices.  Many people have made\r
-generous contributions to the wide range of software distributed\r
-through that system in reliance on consistent application of that\r
-system; it is up to the author/donor to decide if he or she is willing\r
-to distribute software through any other system and a licensee cannot\r
-impose that choice.\r
-\r
-This section is intended to make thoroughly clear what is believed to\r
-be a consequence of the rest of this License.\r
-\r
-  12. If the distribution and/or use of the Library is restricted in\r
-certain countries either by patents or by copyrighted interfaces, the\r
-original copyright holder who places the Library under this License may add\r
-an explicit geographical distribution limitation excluding those countries,\r
-so that distribution is permitted only in or among countries not thus\r
-excluded.  In such case, this License incorporates the limitation as if\r
-written in the body of this License.\r
-\r
-  13. The Free Software Foundation may publish revised and/or new\r
-versions of the Lesser General Public License from time to time.\r
-Such new versions will be similar in spirit to the present version,\r
-but may differ in detail to address new problems or concerns.\r
-\r
-Each version is given a distinguishing version number.  If the Library\r
-specifies a version number of this License which applies to it and\r
-"any later version", you have the option of following the terms and\r
-conditions either of that version or of any later version published by\r
-the Free Software Foundation.  If the Library does not specify a\r
-license version number, you may choose any version ever published by\r
-the Free Software Foundation.\r
-\f\r
-  14. If you wish to incorporate parts of the Library into other free\r
-programs whose distribution conditions are incompatible with these,\r
-write to the author to ask for permission.  For software which is\r
-copyrighted by the Free Software Foundation, write to the Free\r
-Software Foundation; we sometimes make exceptions for this.  Our\r
-decision will be guided by the two goals of preserving the free status\r
-of all derivatives of our free software and of promoting the sharing\r
-and reuse of software generally.\r
-\r
-                           NO WARRANTY\r
-\r
-  15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO\r
-WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.\r
-EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR\r
-OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY\r
-KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE\r
-IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR\r
-PURPOSE.  THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE\r
-LIBRARY IS WITH YOU.  SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME\r
-THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.\r
-\r
-  16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN\r
-WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY\r
-AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU\r
-FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR\r
-CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE\r
-LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING\r
-RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A\r
-FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF\r
-SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH\r
-DAMAGES.\r
-\r
-                    END OF TERMS AND CONDITIONS\r
-\f\r
-           How to Apply These Terms to Your New Libraries\r
-\r
-  If you develop a new library, and you want it to be of the greatest\r
-possible use to the public, we recommend making it free software that\r
-everyone can redistribute and change.  You can do so by permitting\r
-redistribution under these terms (or, alternatively, under the terms of the\r
-ordinary General Public License).\r
-\r
-  To apply these terms, attach the following notices to the library.  It is\r
-safest to attach them to the start of each source file to most effectively\r
-convey the exclusion of warranty; and each file should have at least the\r
-"copyright" line and a pointer to where the full notice is found.\r
-\r
-    <one line to give the library's name and a brief idea of what it does.>\r
-    Copyright (C) <year>  <name of author>\r
-\r
-    This library is free software; you can redistribute it and/or\r
-    modify it under the terms of the GNU Lesser General Public\r
-    License as published by the Free Software Foundation; either\r
-    version 2.1 of the License, or (at your option) any later version.\r
-\r
-    This library is distributed in the hope that it will be useful,\r
-    but WITHOUT ANY WARRANTY; without even the implied warranty of\r
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\r
-    Lesser General Public License for more details.\r
-\r
-    You should have received a copy of the GNU Lesser General Public\r
-    License along with this library; if not, write to the Free Software\r
-    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\r
-\r
-Also add information on how to contact you by electronic and paper mail.\r
-\r
-You should also get your employer (if you work as a programmer) or your\r
-school, if any, to sign a "copyright disclaimer" for the library, if\r
-necessary.  Here is a sample; alter the names:\r
-\r
-  Yoyodyne, Inc., hereby disclaims all copyright interest in the\r
-  library `Frob' (a library for tweaking knobs) written by James Random Hacker.\r
-\r
-  <signature of Ty Coon>, 1 April 1990\r
-  Ty Coon, President of Vice\r
-\r
-That's all there is to it!\r
-\r
-\r
diff --git a/message/output/jabber/jabberclass/README b/message/output/jabber/jabberclass/README
deleted file mode 100644 (file)
index 91d2caa..0000000
+++ /dev/null
@@ -1,59 +0,0 @@
-Jabber Client Library
-Version 0.9rc1
-Copyright 2002-2007, Centova Technologies Inc.
-http://www.centova.com
-
-Portions Copyright 2002, Carlo Zottmann
-============================================================================
-
-This file was contributed (in part or whole) by a third party, and is
-released under the GNU LGPL.  Please see the CREDITS and LICENSE sections
-below for details.
-
-****************************************************************************
-
-DETAILS
-
-This is an event-driven Jabber client class implementation.  This library
-allows PHP scripts to connect to and communicate with Jabber servers.
-
-
-CREDITS & COPYRIGHTS
-
-This class was originally based on Class.Jabber.PHP v0.4 (Copyright 2002,
-Carlo "Gossip" Zottmann).
-
-The code for this class has since been nearly completely rewritten by Steve
-Blinch for Centova Technologies Inc.  All such modified code is Copyright
-2002-2007, Centova Technologies Inc.
-
-The original Class.Jabber.PHP was released under the GNU General Public
-License (GPL); however, we have received written permission from the
-original author and copyright holder, Carlo Zottmann, to relicense our
-version of this class and release it under the GNU Lesser General Public
-License (LGPL).
-
-LICENSE
-
-class_Jabber.php - Jabber Client Library
-Copyright (C) 2002-2007, Centova Technologies Inc.
-Copyright (C) 2002, Carlo Zottmann
-
-
-This library is free software; you can redistribute it and/or modify it
-under the terms of the GNU Lesser General Public License as published by the
-Free Software Foundation; either version 2.1 of the License, or (at your
-option) any later version.
-
-This library is distributed in the hope that it will be useful, but WITHOUT
-ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
-FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License
-for more details.
-
-You should have received a copy of the GNU Lesser General Public License
-along with this library; if not, write to the Free Software Foundation,
-Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
-
-
-JABBER is a registered trademark of Jabber Inc.
-
diff --git a/message/output/jabber/jabberclass/class_ConnectionSocket.php b/message/output/jabber/jabberclass/class_ConnectionSocket.php
deleted file mode 100644 (file)
index 1213478..0000000
+++ /dev/null
@@ -1,86 +0,0 @@
-<?php
-/*
- * This file was contributed (in part or whole) by a third party, and is
- * released under the GNU LGPL.  Please see the CREDITS and LICENSE sections
- * below for details.
- * 
- *****************************************************************************
- *
- * DETAILS
- *
- * Connection handling class used by class_Jabber.php.  Used as a generic
- * socket interface to connect to Jabber servers.
- *
- *
- * CREDITS & COPYRIGHTS
- *
- * This class was originally based on Class.Jabber.PHP v0.4 (Copyright 2002,
- * Carlo "Gossip" Zottmann).
- *
- * The code for this class has since been nearly completely rewritten by Steve
- * Blinch and Centova Technologies Inc.  All such modified code is Copyright 2003-2006, 
- * Centova Technologies Inc.
- *
- * The original Class.Jabber.PHP was released under the GNU General Public
- * License (GPL); however, we have received written permission from the
- * original author and copyright holder, Carlo Zottmann, to relicense our
- * version of this class and release it under the GNU Lesser General Public
- * License (LGPL).
- *
- *
- * LICENSE
- *
- * class_ConnectionSocket.php - Connection Socket Library
- * Part of class_Jabber.php - Jabber Client Library
- * Copyright (C) 2003-2007, Centova Technologies Inc.
- * Copyright (C) 2002, Carlo Zottmann
- *
- * This library is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as published by the
- * Free Software Foundation; either version 2.1 of the License, or (at your
- * option) any later version.
- * 
- * This library is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License
- * for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this library; if not, write to the Free Software Foundation,
- * Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- *
- */
-class ConnectionSocket {
-       var $socket = null;
-       
-       function socket_open($hostname,$port,$timeout) {
-               if ($this->socket = @fsockopen($hostname, $port, $errno, $errstr, $timeout)) {
-                       socket_set_blocking($this->socket, 0);
-                       socket_set_timeout($this->socket, 31536000);
-                       
-                       return true;
-               } else {
-                       $this->error = "{$errstr} (#{$errno})";
-                       return false;
-               }
-       }
-       
-       function socket_close() {
-               return fclose($this->socket);
-       }
-       
-       function socket_write($data) {
-               return fwrite($this->socket, $data);
-       }
-       
-       function socket_read($byte_count)
-       {
-               set_magic_quotes_runtime(0);
-               $buffer = fread($this->socket, $byte_count);
-               set_magic_quotes_runtime(get_magic_quotes_runtime());
-
-               return $buffer;
-       }       
-       
-}
-?>
\ No newline at end of file
diff --git a/message/output/jabber/jabberclass/class_Jabber.php b/message/output/jabber/jabberclass/class_Jabber.php
deleted file mode 100644 (file)
index bf4d7bd..0000000
+++ /dev/null
@@ -1,2062 +0,0 @@
-<?php
-/* Jabber Client Library
- * Version 0.9rc1
- * Copyright 2002-2007, Centova Technologies Inc.
- * http://www.centova.com
- *
- * Portions Copyright 2002, Carlo Zottmann
- * ============================================================================
- *
- * This file was contributed (in part or whole) by a third party, and is
- * released under the GNU LGPL.  Please see the CREDITS and LICENSE sections
- * below for details.
- * 
- *****************************************************************************
- *
- * DETAILS
- *
- * This is an event-driven Jabber client class implementation.  This library
- * allows PHP scripts to connect to and communicate with Jabber servers.
- *
- *
- * HISTORY
- *
- *     v0.9rc1 (Unreleased)
- *          - Fixed problem with _split_incoming() method that would incorrectly
- *                parse packets starting with reserved element names
- *              - Added support for obtaining nicknames from vCard updates
- *              - Added default value to constructor's debug argument
- *              - Various minor code cleanups and typo fixes
- *              - Added support for PHP 5
- *
- *     v0.8 - Internal release
- *     v0.7 - Internal release
- *     v0.6 - Internal release
- *     v0.5 - Initial port from class.jabber.php
- *
- *
- * CREDITS & COPYRIGHTS
- *
- * This class was originally based on Class.Jabber.PHP v0.4 (Copyright 2002,
- * Carlo "Gossip" Zottmann).
- *
- * The code for this class has since been nearly completely rewritten by Steve
- * Blinch for Centova Technologies Inc.  All such modified code is Copyright
- * 2002-2007, Centova Technologies Inc.
- *
- * The original Class.Jabber.PHP was released under the GNU General Public
- * License (GPL); however, we have received written permission from the
- * original author and copyright holder, Carlo Zottmann, to relicense our
- * version of this class and release it under the GNU Lesser General Public
- * License (LGPL).
- *
- *
- * LICENSE
- *
- * class_Jabber.php - Jabber Client Library
- * Copyright (C) 2002-2007, Centova Technologies Inc.
- * Copyright (C) 2002, Carlo Zottmann
- *
- * This library is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as published by the
- * Free Software Foundation; either version 2.1 of the License, or (at your
- * option) any later version.
- * 
- * This library is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License
- * for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this library; if not, write to the Free Software Foundation,
- * Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- *
- *
- * JABBER is a registered trademark of Jabber Inc.
- *
- */
-
-/*
-
-The following events are available to be handled by user applications
-(use ::set_handler($handler_name...) to assign a handler method to an event).
-
-$this->_call_handler("authenticated");
-$this->_call_handler("authfailure",-1,"No authentication method available","");
-$this->_call_handler("deregistered",$this->jid);
-$this->_call_handler("deregfailure",-2,"Unrecognized response from server");
-$this->_call_handler("error",$code,$msg,$xmlns,$packet);
-$this->_call_handler("heartbeat");
-$this->_call_handler("message_chat",$from,$to,$body,$subject,$thread,$id,$extended,$packet);
-$this->_call_handler("message_groupchat",$packet);
-$this->_call_handler("message_headline",$from,$to,$body,$subject,$extended,$packet);
-$this->_call_handler("message_normal",$from,$to,$body,$subject,$thread,$id,$extended,$packet);
-$this->_call_handler("msgevent_composing_start",$from);
-$this->_call_handler("msgevent_composing_stop",$from);
-$this->_call_handler("msgevent_delivered",$from);
-$this->_call_handler("msgevent_displayed",$from);
-$this->_call_handler("msgevent_offline",$from);
-$this->_call_handler("passwordchanged");
-$this->_call_handler("passwordfailure",-2,"Unrecognized response from server");
-$this->_call_handler("regfailure",-1,"Username already registered","");
-$this->_call_handler("registered",$this->jid);
-$this->_call_handler("rosteradded");
-$this->_call_handler("rosteraddfailure",-2,"Unrecognized response from server");
-$this->_call_handler("rosterremoved");
-$this->_call_handler("rosterremovefailure",-2,"Unrecognized response from server");
-$this->_call_handler("rosterupdate",$jid,$is_new);
-$this->_call_handler("servicefields",&$fields,$packet_id,$reg_key,$reg_instructions,&$reg_x);
-$this->_call_handler("servicefieldsfailure",-2,"Unrecognized response from server");
-$this->_call_handler("serviceregfailure",-2,"Unrecognized response from server");
-$this->_call_handler("serviceregistered",$jid);
-$this->_call_handler('servicederegfailure",-2,"Unrecognized response from server");
-$this->_call_handler('servicederegistered");
-$this->_call_handler("serviceupdate",$jid,$is_new);
-$this->_call_handler("terminated");
-$this->_call_handler('connected');
-$this->_call_handler('disconnected'); // called when the connection to the Jabber server is lost unexpectedly
-$this->_call_handler('probe',$packet);
-$this->_call_handler('stream_error',$packet);
-$this->_call_handler('subscribe',$packet);
-$this->_call_handler('subscribed',$packet);
-$this->_call_handler('unsubscribe',$packet);
-$this->_call_handler('unsubscribed',$packet);
-$this->_call_handler("privatedata",$packetid,$namespace,$values);
-$this->_call_handler('debug_log',$msg);
-$this->_call_handler("contactupdated",$packetid);
-$this->_call_handler("contactupdatefailure",-2,"Unrecognized response from server");
-
-*/
-
-require_once(dirname(__FILE__)."/class_ConnectionSocket.php");
-require_once(dirname(__FILE__)."/class_XMLParser.php");
-
-// Version string
-define("CLASS_JABBER_VERSION","0.9rc1");
-
-// Default connection timeout
-define("DEFAULT_CONNECT_TIMEOUT",15);
-
-// Default Jabber resource
-define("DEFAULT_RESOURCE","JabberClass");
-
-// Minimum/Maximum callback frequencies
-define("MIN_CALLBACK_FREQ",1); // more than once per second is dangerous
-define("MAX_CALLBACK_FREQ",10); // less than once every 10 seconds will be very, very slow
-
-// Make sure we have SHA1 support, one way or another, such that we can
-// perform encrypted logins.
-if (!function_exists('sha1')) {  // PHP v4.3.0+ supports sha1 internally
-
-       if (function_exists('mhash')) { // is the Mhash extension installed?
-
-               // implement the sha1() function using mhash
-               function sha1($str) {
-                       return bin2hex(mhash(MHASH_SHA1, $str));
-               }
-
-       } else {
-
-               // implement the sha1() function in native PHP using the SHA1Library class;
-               // this is slow, but it's better than plaintext.
-               require_once(dirname(__FILE__)."/class_SHA1Library.php");
-       }
-       
-}
-
-// Jabber communication class
-class Jabber {
-       var $jid                                = "";
-       var $use_msg_composing  = true;
-       var $use_msg_delivered  = false;
-       var $use_msg_displayed  = false;
-       var $use_msg_offline    = false;
-
-       var $_server_host               = "";
-       var $_server_ip                 = "";
-       var $_server_port               = 5222;
-       var $_connect_timeout   = DEFAULT_CONNECT_TIMEOUT;
-       var $_username                  = "";
-       var $_password                  = "";
-       var $_resource                  = "";
-
-       var $_iq_version_name   = "class_Jabber.php - http://www.centova.com - Copyright 2003-2007, Centova Technologies Inc.";
-       var $_iq_version_version= CLASS_JABBER_VERSION;
-       //var   $_iq_version_os = $_SERVER['SERVER_SOFTWARE'];
-
-       var $_connector                 = "ConnectionSocket";
-       var $_authenticated             = false;
-       
-       var $_packet_queue              = array();
-       var $_last_ping_time    = 0;
-
-       var $_iq_handlers               = array();
-       var $_event_handlers    = array();
-       
-       var $execute_loop               = true;
-       
-       // DEBUGGING ONLY - causes the log file to be closed/flushed after each write
-       var $_log_flush                 = true;
-
-       // if true, roster updates generate only one "rosterupdate" event,
-       // regardless of how many contacts were actually updated/added;
-       // useful for the initial roster download
-       var $roster_single_update = false;
-
-       // if true, service updates generate only one "serviceupdate" event,
-       // regardless of how many services were actually updated/added;
-       // useful for retrieving a service list
-       var $service_single_update = false;
-       
-       // if true, contacts without "@"'s in their name will be assumed
-       // to be services and will not be listed in the roster; if the
-       // corresponding JID is found in the $this->services array, its
-       // "status" and "show" elements will be updated to reflect the
-       // presence/availability of the service (and the "serviceupdate"
-       // event will be fired)
-       var $handle_services_internally = false;
-
-       // If true, the server software name and version will automatically be queried
-       // and stored in $this->server_software and $this->server_version at login
-       var $auto_server_identify = true;
-       
-       var $server_software = "";
-       var $server_version = "";
-       var $server_os = "";
-       
-       var $protocol_version = false; // set this to an XMPP protocol revision to include it in the <stream:stream> tag
-       
-       // Constructor
-       function Jabber($enable_logging = false) {
-               $this->_use_log = $enable_logging;
-               $this->_unique_counter = 0;
-               $this->_log_open();
-               
-               $this->xml = &new XMLParser();
-       }
-
-       // ==== General Methods ==================================================================
-       
-       // set a handler method for a specific Jabber event; valid handler names
-       // are listed at the top of this script
-       function set_handler($handler_name,&$handler_object,$method_name) {
-               $this->_event_handlers[$handler_name] = array(&$handler_object,$method_name);
-       }
-       
-       function set_handler_object(&$handler_object,$handlers) {
-               foreach ($handlers as $handler_name=>$method_name) {
-                       $this->set_handler(
-                               $handler_name,
-                               $handler_object,
-                               $method_name
-                       );
-               }
-       }
-       
-       // same as above, but accepts a plain ol' function instead of a method
-       function set_handler_function($handler_name,$method_name) {
-               $this->_event_handlers[$handler_name] = $method_name;
-       }
-       
-       // calls the specified handler with the specified parameters; accepts:
-       //
-       // $handler_name - the name of the handler (as defined with ::set_handler())
-       //                 to call
-       // (optional) other parameters - the parameters to pass to the handler method
-       function _call_handler() {
-
-               $numargs = func_num_args(); 
-               if ($numargs<1) return false;
-
-               $arg_list = func_get_args(); 
-               $handler_name = array_shift($arg_list);
-
-               if (($handler_name!="debug_log") && ($handler_name!="heartbeat")) $this->_log("Calling handler: $handler_name");
-               
-               
-               if ($this->_event_handlers[$handler_name]) {
-                       
-                       // ---- REMOVE THIS AFTER BENCHMARKING! ----
-                       if (defined('JX_HANDLER_BENCHMARK')) $GLOBALS["jxeh"]->t_start('event.'.$handler_name);
-                       // ---- REMOVE THIS AFTER BENCHMARKING! ----
-                       
-                       call_user_func_array(&$this->_event_handlers[$handler_name],$arg_list);
-                       
-                       // ---- REMOVE THIS AFTER BENCHMARKING! ----
-                       if (defined('JX_HANDLER_BENCHMARK')) $GLOBALS["jxeh"]->t_end('event.'.$handler_name);
-                       // ---- REMOVE THIS AFTER BENCHMARKING! ----
-                       
-               }
-       }
-       
-       // posix platforms support usleep(), to sleep for a specific number of
-       // microseonds; we use that when possible, as it allows for a more responsive
-       // interface
-       function posix_sleep() {
-               $micro_seconds = 250000;
-               usleep($micro_seconds);
-               
-               return round($micro_seconds/1000000,2);
-       }
-       
-       // Windows doesn't support usleep(), so we have to sleep for minimum 1-second
-       // intervals.. this makes the interface a bit more sluggish, but allows for 
-       // Win32 compatibility
-       function win32_sleep() {
-               $secs = 1;
-               sleep($secs);
-               
-               return $secs;
-       }
-       
-
-       // returns a unique ID to be sent with packets
-       function _unique_id($prefix) {
-               $this->_unique_counter++;
-               return $prefix."_" . md5(time() . $_SERVER['REMOTE_ADDR'] . $this->_unique_counter);
-       }
-       
-       // public method for creating a log entry
-       function log($msg,$level=1) {
-               $this->_log($msg,$level);
-       }
-       
-       // private method for creating a log entry
-       function _log($msg,$level = 1) {
-               if ($this->_use_log) {
-                       if ($this->_log_flush) $this->_log_file = @fopen(dirname(__FILE__)."/log/logfile.txt","a");
-                       
-                       if ($this->_log_file) {
-                               fwrite($this->_log_file,"$msg\n");
-                               if ($this->_log_flush) fclose($this->_log_file);
-                       }
-
-                       $this->_call_handler("debug_log",$msg,$level);
-               }
-       }
-       
-       // debug method for creating a log entry (for ease of commenting-out :) )
-       function dlog($msg,$level=1) {
-               $this->_log($msg,$level);
-       }
-
-       
-       function _log_open() {
-               if ($this->_use_log) {
-                       $this->_log_file = @fopen(dirname(__FILE__)."/log/logfile.txt","w");
-                       if ($this->_log_file && $this->_log_flush) {
-                               fclose($this->_log_file);
-                       }
-               }
-       }
-
-       function _log_close() {
-               if ($this->_use_log && $this->_log_file && !$this->_log_flush) {
-                       fclose($this->_log_file);
-               }
-       }
-
-       // splits a JID into its three components; returns an array
-       // of (username,domain,resource)
-       function _split_jid($jid) {
-               preg_match("/(([^\@]+)\@)?([^\/]+)(\/(.*))?$/",$jid,$matches);
-               return array($matches[2],$matches[3],$matches[5]);
-       }
-       
-       function _bare_jid($jid) {
-               list($u_username,$u_domain,$u_resource) = $this->_split_jid($jid);
-               return ($u_username?$u_username."@":"").$u_domain;
-       }
-
-       
-
-       // ==== Core Jabber Methods ==============================================================
-
-       // Connects to the specified Jabber server.
-       //
-       // Returns true if the socket was opened, otherwise false.
-       // A "connected" event is also fired when the server responds to our <stream> packet.
-       //
-       // $server_host     - Hostname of your Jabber server (portion after the "@" in your JID)
-       // $server_port     - Port for your Jabber server
-       // $connect_timeout - Maximum number of seconds to wait for a connection
-       // $alternate_ip    - If $server_host does not resolve to your Jabber server's IP,
-       //                    specify the correct IP to connect to here
-       //      
-       //
-       function connect($server_host,$server_port=5222,$connect_timeout=null,$alternate_ip=false) {
-               
-               if (is_null($connect_timeout)) $connect_timeout = DEFAULT_CONNECT_TIMEOUT;
-               $connector = $this->_connector;
-               
-               $this->_connection = &new $connector();
-               $this->_server_host = $server_host;
-               $this->_server_port = $server_port;
-               $this->_server_ip = $alternate_ip ? $alternate_ip : $server_host;
-               $this->_connect_timeout = $connect_timeout;
-               
-               $this->roster = array();
-               $this->services = array();
-               
-               $this->_is_win32 = (substr(strtolower(php_uname()),0,3)=="win");
-               $this->_sleep_func = $this->_is_win32 ? "win32_sleep" : "posix_sleep";
-               
-               return $this->_connect_socket();
-       }
-       
-       function _connect_socket() {
-               $this->log('connecting: '.$this->_server_ip.' '.$this->_server_port.' '.$this->_connect_timeout);
-               if ($this->_connection->socket_open($this->_server_ip,$this->_server_port,$this->_connect_timeout)) {
-                       $this->_send("<?xml version='1.0' encoding='UTF-8' ?" . ">\n");
-                       
-                       $xmpp_version = ($this->protocol_version) ? " version='{$this->protocol_version}'" : '';
-                       
-                       $this->_send("<stream:stream to='{$this->_server_host}' xmlns='jabber:client' xmlns:stream='http://etherx.jabber.org/streams'{$xmpp_version}>\n");
-                       return true;
-               } else {
-                       $this->error = $this->_connection->error;
-                       return false;
-               }
-       }
-       
-       // disconnect from the server
-       function disconnect() {
-               
-               $this->_send("</stream:stream>");
-               
-               $this->_log_close();
-               return $this->_connection->socket_close();
-       }
-       
-       
-       // logs in to the server
-       function login($username,$password,$resource=NULL) {
-               if (!$username || !$password) return false;
-               
-               // setup handler to automatically respond to the request
-               $auth_id        = $this->_unique_id("auth");
-               $this->_set_iq_handler("_on_authentication_methods",$auth_id,"result");
-               $this->_set_iq_handler("_on_authentication_result",$auth_id,"error");
-               
-               // prepare our shiny new JID
-               $this->_username = $username;
-               $this->_password = $password;
-               $this->_resource = !is_null($resource) ? $resource : DEFAULT_RESOURCE;
-               $this->jid              = "{$this->_username}@{$this->_server_host}/{$this->_resource}";
-               
-               // request available authentication methods
-               $payload        = "<username>{$this->_username}</username>";
-               $packet         = $this->_send_iq(NULL, 'get', $auth_id, "jabber:iq:auth", $payload);
-               
-               return true;
-       }
-       
-       // browse the services (transports) available on the server
-       function browse() {
-               $browse_id = $this->_unique_id("browse");
-               $this->_set_iq_handler("_on_browse_result",$browse_id);
-               
-               return $this->_send_iq($this->_server_host, 'get', $browse_id, "jabber:iq:browse");
-       }
-       
-       // retrieve the user's roster from the jabber server
-       function get_roster() {
-               $roster_id = $this->_unique_id("roster");
-               $this->_set_iq_handler("_on_roster_result",$roster_id);
-               
-               return $this->_send_iq(NULL, 'get', $roster_id, "jabber:iq:roster");
-       }
-       
-       // sets a user's presence (when simply used to set your availability, it's more convenient
-       // to call this way, as usually only the first 2 fields are necessary)
-       function set_presence($show = NULL, $status = NULL, $to = NULL, $priority = NULL) {
-               return $this->send_presence(NULL,$to,$show,$status,$priority);
-       }
-       
-       // sends presence to another contact/entity
-       function send_presence($type = NULL, $to = NULL, $show = NULL, $status = NULL, $priority = NULL) {
-               $xml = "<presence";
-               $xml .= ($to) ? " to='$to'" : '';
-               $xml .= ($type) ? " type='$type'" : '';
-               $xml .= ($status || $show || $priority) ? ">\n" : " />\n";
-
-               $xml .= ($status) ? "   <status>$status</status>\n" : '';
-               $xml .= ($show) ? "     <show>$show</show>\n" : '';
-               $xml .= ($priority) ? " <priority>$priority</priority>\n" : '';
-
-               $xml .= ($status || $show || $priority) ? "</presence>\n" : '';
-
-               if ($this->_send($xml)) {
-                       return true;
-               } else {
-                       $this->_log("ERROR: send_presence() #1");
-                       return false;
-               }
-               
-       }
-       
-       // indicate (to another contact) that the user is composing a message
-       function composing($to,$id,$start=true) {
-               $payload = "<x xmlns='jabber:x:event'><composing/>".($start?"<id>$id</id>":"")."</x>";
-               return $this->message($to,"normal",NULL,NULL,NULL,NULL,$payload);
-       }
-       
-       function xmlentities($string, $quote_style=ENT_QUOTES) {
-               return htmlspecialchars($string,$quote_style);
-               
-          $trans = get_html_translation_table(HTML_ENTITIES, $quote_style);
-          foreach ($trans as $key => $value)
-              $trans[$key] = '&#'.ord($key).';';
-          return strtr($string, $trans);
-       }       
-       
-       function message($to, $type = "normal", $id = NULL, $body = NULL, $thread = NULL, $subject = NULL, $payload = NULL, $raw = false) {
-               if ($to && ($body || $subject || $payload)) {
-                       if (!$id) $id = $this->_unique_id("msg");
-
-//                     $body = htmlspecialchars($body);
-//                     $subject = htmlspecialchars($subject);
-
-                       if (!$raw) {
-                               $body = $this->xmlentities($body);
-                               $subject = $this->xmlentities($subject);
-                               $thread = $this->xmlentities($thread);
-                       }
-
-                       //$body = str_replace("&ccedil;","&#0231;",$body);
-
-                       $xml = "<message to='$to' type='$type' id='$id'>\n";
-
-                       if ($subject)   $xml .= "<subject>$subject</subject>\n";
-                       if ($thread)    $xml .= "<thread>$thread</thread>\n";
-                       if ($body)              $xml .= "<body>$body</body>\n";
-                       
-                       if ($body || $subject) {
-                               $jabber_x_event = "";
-                               if ($this->use_msg_composing) $jabber_x_event .= "<composing/>";
-                               if ($this->use_msg_delivered) $jabber_x_event .= "<delivered/>";
-                               if ($this->use_msg_displayed) $jabber_x_event .= "<displayed/>";
-                               if ($this->use_msg_offline) $jabber_x_event .= "<offline/>";
-                               if ($jabber_x_event) $xml .= "<x xmlns='jabber:x:event'>$jabber_x_event</x>";
-                       }
-                                               
-                       $xml .= $payload;
-                       $xml .= "</message>\n";
-
-                       if ($this->_send($xml)) {
-                               return true;
-                       } else {
-                               $this->_log("ERROR: message() #1");
-                               return false;
-                       }
-               } else {
-                       $this->_log("ERROR: message() #2");
-                       return false;
-               }
-       }
-       
-       // create a new Jabber account
-       function register($username, $password, $reg_email = NULL, $reg_name = NULL) {
-               if (!$username || !$password) return false;
-               
-               $reg_id = $this->_unique_id("reg");
-               $this->_set_iq_handler("_on_register_get_result",$reg_id);
-               
-               $this->_username = $this->xmlentities($username);
-               $this->_password = $this->xmlentities($password);
-               $this->_reg_email = $this->xmlentities($reg_email);
-               $this->_reg_name = $this->xmlentities($reg_name);
-               
-               return $this->_send_iq($this->_server_host, 'get', $reg_id, 'jabber:iq:register');
-       }
-       
-       // cancels an existing Jabber account, removing it from the server (careful!)
-       //
-       // Note: on jabberd 1.4.2 this always seems to return 503 Service Unavailable for me;
-       // not sure if this is a problem with this method, a problem with my server, or a
-       // problem with jabberd 1.4.2.
-       function deregister() {
-               $dereg_id = $this->_unique_id("dereg");
-               $this->_set_iq_handler("_on_deregister_result",$dereg_id);
-
-               $payload = "<remove/>";
-               return $this->_send_iq($this->_server_host, 'set', $dereg_id, "jabber:iq:register", $payload, $this->jid);
-       }
-       
-       
-       // changes the user's password
-       function change_password($newpassword) {
-               if (!$newpassword) return false;
-               
-               $chg_id = $this->_unique_id("chg");
-               $this->_set_iq_handler("_on_chgpassword_result",$chg_id);
-               
-               $newpassword = $this->xmlentities($newpassword);
-               
-               $payload = "<username>{$this->_username}</username><password>$newpassword</password>";
-               return $this->_send_iq($this->_server_host, 'set', $chg_id, "jabber:iq:register", $payload);
-       }
-       
-       // subscribes to an entity's presence ($request_message specifies the "reason for requesting subscription" message)
-       function subscribe($to,$request_message=NULL) {
-               return $this->send_presence("subscribe", $to, NULL, $request_message);
-       }
-
-       // unsubscribes from an entity's presence
-       function unsubscribe($to) {
-               return $this->send_presence("unsubscribe", $to);
-       }
-       
-       // accepts a subscription request from an entity
-       function subscription_request_accept($to) {
-               return $this->send_presence("subscribed", $to);
-       }
-
-       // denies a subscription request from an entity
-       function subscription_request_deny($to) {
-               return $this->send_presence("unsubscribed", $to);
-       }
-       
-       // get the registration fields for a service/transport
-       function query_service_fields($transport)
-       {
-               $reg_id = $this->_unique_id("reg");
-               $this->_set_iq_handler("_on_servicefields_result",$reg_id);
-               
-               if ($this->_send_iq($transport, 'get', $reg_id, "jabber:iq:register", NULL, $this->jid)) {
-                       return $reg_id;
-               } else {
-                       return false;
-               }
-       }
-       
-
-       // register with a service/transport
-       function register_service($transport,$reg_id,$reg_key = NULL,$fields)
-       {
-               if (!$transport || !$reg_id || !$fields) return false;
-               
-               $this->_set_iq_handler("_on_serviceregister_result",$reg_id);
-               
-
-               $payload = ($reg_key) ? "<key>$reg_key</key>\n" : '';
-               foreach ($fields as $element => $value) {
-                       $payload .= "<$element>".$this->xmlentities($value)."</$element>\n";
-               }
-
-               return $this->_send_iq($transport, 'set', $reg_id, "jabber:iq:register", $payload);
-       }
-       
-       function deregister_service($transport,$reg_id,$reg_key = NULL) {
-               if (!$transport || !$reg_id) return false;
-
-               $this->_set_iq_handler("_on_servicedereg_initial_result",$reg_id);
-
-               $payload = "<remove/>";
-               return $this->_send_iq($transport, 'set', $reg_id, "jabber:iq:register", $payload);
-       }
-       
-       // adds a contact to the roster
-       function roster_add($jid, $name = NULL, $group = NULL) {
-               if (!$jid) return false;
-               $add_id = $this->_unique_id("add");
-               
-               $this->_set_iq_handler("_on_rosteradd_result",$add_id);
-
-               $payload = "<item jid='$jid'";
-               $payload .= ($name) ? " name='" . $this->xmlentities($name) . "'" : '';
-               $payload .= (($group) ? "><group>". $this->xmlentities($group). "</group>\n</item": "/") . ">\n";
-
-               if ($this->_send_iq(NULL, 'set', $add_id, "jabber:iq:roster", $payload)) {
-                       return $add_id;
-               } else {
-                       return false;
-               }
-       }
-       
-       function roster_remove($jid) {
-               if (!$jid) return false;
-               $rem_id = $this->_unique_id("remove");
-               
-               $this->_set_iq_handler("_on_rosterremove_result",$rem_id);
-
-               $payload = "<item jid='$jid' subscription='remove'/>";
-
-               if ($this->_send_iq(NULL, 'set', $rem_id, "jabber:iq:roster", $payload)) {
-                       return $rem_id;
-               } else {
-                       return false;
-               }
-       }
-       
-       // updates a roster contact's name and/or group
-       function roster_update($jid,$name = NULL,$group = NULL) {
-               if (!$jid) return false;
-               $update_id = $this->_unique_id("update");
-               
-               $this->_set_iq_handler("_on_rosterupdate_result",$update_id);
-
-               $payload = "<item jid='$jid'";
-               $payload .= ($name) ? " name='" . $this->xmlentities($name) . "'" : '';
-               $payload .= (($group) ? "><group>". $this->xmlentities($group) . "</group>\n</item": "/") . ">\n";
-
-               if ($this->_send_iq(NULL, 'set', $update_id, "jabber:iq:roster", $payload)) {
-                       return $add_id;
-               } else {
-                       return false;
-               }                               
-       }
-       
-       // adds a contact to the roster and subscribes to his presence in one step;
-       // simply a time saver.
-       function add_contact($jid,$name = NULL,$group = NULL) {
-               if ($this->roster_add($jid,$name,$group)) {
-                       return $this->subscribe($jid);
-               } else {
-                       return false;
-               }
-       }
-
-       // alias for roster_remove()
-       function remove_contact($jid) {
-               return $this->roster_remove($jid);
-       }
-       
-       function set_private_data($namespace,$rootelement,$values) {
-               if ((!$namespace) || (!$rootelement) || (!$values)) return false;
-
-               $data_id = $this->_unique_id("privdata");
-
-//             $this->_set_iq_handler("_on_xxx_result",$data_id); // we don't really need the result from this... do we?
-
-               $payload = "<$rootelement xmlns='$namespace'>";
-               foreach ($values as $key=>$value) {
-                       $payload .= "<$key>$value</$key>";
-               }
-               $payload .= "</$rootelement>";
-
-               if ($this->_send_iq(NULL, 'set', $data_id, "jabber:iq:private", $payload)) {
-                       return $data_id;
-               } else {
-                       return false;
-               }
-       }
-
-       function get_private_data($namespace,$rootelement) {
-               if ((!$namespace) || (!$rootelement)) return false;
-
-               $data_id = $this->_unique_id("privdata");
-               $this->_set_iq_handler("_on_private_data",$data_id);
-
-               $payload = "<$rootelement xmlns='$namespace' />";
-
-               if ($this->_send_iq(NULL, 'get', $data_id, "jabber:iq:private", $payload)) {
-                       return $data_id;
-               } else {
-                       return false;
-               }
-       }
-       
-       function adjust_callback_frequency($factor) {
-               if ($this->active_cbk_freq<0) return;
-               
-               $this->dlog("Setting callback frequency factor to $factor");
-
-               $this->active_cbk_freq = $this->initial_cbk_freq*$factor;
-
-               $this->dlog("Setting active frequency to {$this->active_cbk_freq}");
-
-               if ($this->active_cbk_freq<MIN_CALLBACK_FREQ) $this->active_cbk_freq = MIN_CALLBACK_FREQ;
-               if ($this->active_cbk_freq>MAX_CALLBACK_FREQ) $this->active_cbk_freq = MAX_CALLBACK_FREQ;
-       }
-
-       
-       // begin execution loop... sort of a ghetto-multithreading type thing, I guess... :)
-       function execute($callback_freq = -1,$seconds = -1)
-       {
-               $sleepfunc = $this->_sleep_func;
-               $this->active_cbk_freq = $this->initial_cbk_freq = $callback_freq;
-               
-               $count = 0;
-               $cb_count = 0;
-               
-               // set terminated to true in any event handler to cause this method to exit immediately
-               $this->terminated = false;
-
-               while (($count != $seconds) && (!$this->terminated)) {
-                       
-                       // check to see if there are any packets waiting
-                       if ($this->_receive()) {
-                               
-                               while (count($this->_packet_queue)) {
-                                       $packet = $this->_get_next_packet();
-       
-                                       // if a packet was available (should always be)
-                                       if ($packet) {
-                                               // check the packet type, and dispatch the appropriate handler
-                                               if (!empty($packet['iq'])) {
-                                                       $this->_handle_iq($packet);
-                                               } elseif (!empty($packet['message'])) {
-                                                       $this->_handle_message($packet);
-                                               } elseif (!empty($packet['presence'])) {
-                                                       $this->_handle_presence($packet);
-                                               } elseif (!empty($packet['stream:stream'])) {
-                                                       $this->_handle_stream($packet);
-                                               } elseif (!empty($packet['stream:features'])) {
-                                                       $this->_handle_stream_features($packet);
-                                               } elseif (!empty($packet['stream:error'])) {
-                                                       $this->_handle_stream_error($packet);
-                                               } else {
-                                                       $this->_log("Unknown packet type!");
-                                                       $x = $this->dump($packet);
-                                                       $this->_log($x);
-                                               }
-                                       }
-                               }
-                       }
-
-                       
-                       $sleeptime = $this->$sleepfunc();
-
-                       $count += $sleeptime;
-                       $cb_count += $sleeptime;
-                       
-                       if ($this->_last_ping_time != date("H:i")) {
-                               if (!$this->_send(" ",true)) {
-                                       // Lost connection to Jabber server!
-                                       $this->_call_handler('disconnected');
-                                       $this->terminated = true;
-                               }
-                               $this->_last_ping_time = date("H:i");
-                       }
-                       
-                       if (($this->active_cbk_freq>0) && ($cb_count>=$this->active_cbk_freq) && ($this->_authenticated)) {
-
-                               $this->dlog("Heartbeat - cbcount:{$cb_count} / active_cbk_freq:{$this->active_cbk_freq}");
-
-                               $this->_call_handler("heartbeat");
-                               $cb_count = 0;  
-                       }
-                       
-                       if (!$this->execute_loop) break;
-               }
-
-               if ($this->execute_loop) $this->_call_handler("terminated");
-
-               return TRUE;
-       }
-
-
-
-
-
-
-
-
-       // ==== Event Handlers (Raw Packets) =====================================================
-       
-       // Sets a handler for a particular IQ packet ID (and optionally packet type).
-       // Assumes that $method is the name of a method of $this
-       function _set_iq_handler($method,$id,$type=NULL) {
-               if (is_null($type)) $type = "_all";
-               $this->_iq_handlers[$id][$type] = array(&$this,$method);
-       }
-       
-       
-       function _node($packet,$path,$checkset = false) {
-               $cursor = &$packet;
-               
-               $pathlength = count($path);
-               for ($i=0; $i<$pathlength; $i++) {
-                       $last = ($i==$pathlength-1);
-                       
-                       $element = $path[$i];
-                       
-                       if (!is_array($cursor) || !isset($cursor[$element])) return ($checkset ? false : NULL);
-                       
-                       if ($last) {
-                               if ($checkset) {
-                                       return isset($cursor[$element]);
-                               } else {
-                                       return $cursor[$element];
-                               }
-                       } else {
-                               $cursor = &$cursor[$element];
-                       }
-                       
-               }
-               
-               return ($checkset ? false : NULL);
-       }
-       
-       function _nodeset($packet,$path) {
-               return $this->_node($packet,$path,true);
-       }
-       
-       // handle IQ packets
-       function _handle_iq(&$packet) {
-               $iq_id = $this->_node($packet,array('iq','@','id'));
-               
-               $iq_type = $this->_node($packet,array('iq','@','type'));
-               
-               // see if we already have a handler setup for this ID number; the vast majority of IQ
-               // packets are handled by their ID number, since they are usually in response to a
-               // request we submitted
-               if ($this->_iq_handlers[$iq_id]) {
-                       
-                       // OK, is there a handler for this specific packet type as well?
-                       if ($this->_iq_handlers[$iq_id][$iq_type]) {
-                               // yup - try  the handler for our packet type
-                               $iqt = $iq_type;
-                       } else {
-                               // nope - try the catch-all handler
-                               $iqt = "_all";
-                       } 
-                       
-                       $this->dlog("Handling $iq_id [$iqt]");
-                       $handler_method = $this->_iq_handlers[$iq_id][$iqt];
-                       unset($this->_iq_handlers[$iq_id][$iqt]);
-                       
-                       if ($handler_method) {
-                               call_user_func($handler_method,&$packet);
-                       } else {
-                               $this->_log("Don't know what to do with packet: ".$this->dump($packet));
-                       }
-               } else {
-                       // this packet didn't have an ID number (or the ID number wasn't recognized), so
-                       // see if we can salvage it.
-                       switch($iq_type) {
-                               case "get":
-                                       if (!$this->_node($packet,array('iq','#','query'))) return;
-                                       
-                                       $xmlns = $this->_node($packet,array('iq','#','query',0,'@','xmlns'));
-                                       switch($xmlns) {
-                                               case "jabber:iq:version":
-                                                       // handle version inquiry/response
-                                                       $this->_handle_version_packet($packet);
-                                                       break;
-                                               case "jabber:iq:time":
-                                                       // handle time inquiry/response
-                                                       $this->_handle_time_packet($packet);
-                                                       break;
-                                               default:
-                                                       // unknown XML namespace; borkie borkie!
-                                                       break;
-                                       }
-                                       break;
-                                       
-                               case "set": // handle <iq type="set"> packets
-                                       if (!$this->_node($packet,array('iq','#','query'))) return;
-                                       
-                                       $xmlns = $this->_node($packet,array('iq','#','query',0,'@','xmlns'));
-                                       switch($xmlns) {
-                                               case "jabber:iq:roster":
-                                                       $this->_on_roster_result($packet);
-                                                       break;
-                                               default:
-                                                       // unknown XML namespace; borkie borkie!
-                                                       break;
-                                       }
-                                       break;
-
-                               default:
-                                       // don't know what to do with other types of IQ packets!
-                                       break;
-
-                       }
-               }
-       }
-       
-       function varset($v) {
-               return is_string($v) ? strlen($v)>0 : !empty($v);
-       }
-       
-       // handle Message packets
-       function _handle_message(&$packet) {
-               // events that we recognize
-               $events = array("composing","offine","delivered","displayed");
-               
-               // grab the message details
-               $type = $this->_node($packet,array('message','@','type'));
-               if (!$type) $type = "chat";
-
-               $from = $this->_node($packet,array('message','@','from'));
-               $to = $this->_node($packet,array('message','@','to'));
-               $id = $this->_node($packet,array('message','@','id'));
-               
-               list($f_username,$f_domain,$f_resource) = $this->_split_jid($from);
-               $from_jid = ($f_username?"{$f_username}@":"").$f_domain;
-               
-               $body = $this->_node($packet,array('message','#','body',0,'#'));
-               $subject = $this->_node($packet,array('message','#','subject',0,'#'));
-               $thread = $this->_node($packet,array('message','#','thread',0,'#'));
-               
-               // handle extended message info (to a certain extent, anyway)...
-               // if any of the tags in $events are passed under an x element in the
-               // jabber:x:event namespace, $extended[tagname] is set to TRUE
-               $extended = false;
-               $extended_id = NULL;
-               $x = $this->_node($packet,array('message','#','x'));
-               
-               if (is_array($x)) {
-                       foreach ($x as $key=>$element) {
-                               if ($this->_node($element,array('@','xmlns'))=="jabber:x:event") {
-                                       if ( !isset($element['#']) || !is_array($element['#']) ) continue;
-                                       
-                                       foreach ($element['#'] as $tag=>$element_content) {
-                                               if (in_array($tag,$events)) {
-                                                       $extended[$tag] = true;
-                                               }
-                                               if ($tag=="id") {
-                                                       $extended_id = $this->_node($element_content,array('0','#'));
-                                                       if (!$extended) $extended = array();
-                                               }
-                                       }
-                               }
-                       }
-               }
-               
-               // if a message contains an x tag in the jabber:x:event namespace,
-               // and doesn't contain a body or subject, then it's an event notification
-               if (!$this->varset($body) && !$this->varset($subject) && is_array($extended)) {
-                       
-                       // is this a composing event (which needs special handling)?
-                       if (isset($extended['composing'])) {
-                               $this->_call_handler("msgevent_composing_start",$from);
-                               $this->roster[$from_jid]["composing"] = true;
-                       } else {
-                               if ($this->roster[$from_jid]["composing"]) {
-                                       $this->_call_handler("msgevent_composing_stop",$from);
-                                       $this->roster[$from_jid]["composing"] = false;
-                               }
-                       }
-
-                       foreach ($extended as $event=>$value) {
-                               $this->_call_handler("msgevent_$event",$from);
-                       }
-                       
-                       // don't process the rest of the message event, as it's not really a message
-                       return;
-               }
-               
-               
-               // process the message
-               switch($type) {
-                       case "error":
-                               $this->_handle_error(&$packet);
-                               break;
-                       case "groupchat":
-                               $this->_call_handler("message_groupchat",$packet);
-                               break;
-                       case "headline":
-                               $this->_call_handler("message_headline",$from,$to,$body,$subject,$x,$packet);
-                               break;
-                       case "chat":
-                       case "normal":
-                       default:
-                               if ($this->roster[$from_jid]["composing"]) $this->roster[$from_jid]["composing"] = false;
-                               if (($type!="chat") && ($type!="normal")) $type = "normal";
-                               $this->_call_handler("message_$type",$from,$to,$body,$subject,$thread,$id,$extended,$packet);
-                               break;
-                               
-               }
-       }
-       
-       // handle Presence packets
-       function _handle_presence(&$packet) {
-       
-               $type = $this->_node($packet,array('presence','@','type'));
-               if (!$type) $type = "available";
-
-               $from = $this->_node($packet,array('presence','@','from'));
-               
-               list($f_username,$f_domain,$f_resource) = $this->_split_jid($from);
-               $from_jid = ($f_username?"{$f_username}@":"").$f_domain;
-               
-               $is_service = (!strlen($f_username));
-
-               $exists = ($is_service && $this->handle_services_internally) ? isset($this->services[$from_jid]) : isset($this->roster[$from_jid]);
-               // $this->dlog("TRACE::_handle_presence() called with from=$from, exists=[$exists]");
-               
-               $nothing = false;
-               $rosteritem = &$nothing;
-               
-               /*
-               // Merak doesn't send roster items for gateway contacts for some reason - it just throws
-               // presence packets at you all willy-nilly... so we simulate a roster update if a non-roster
-               // presence packet is received and we've identified the server as Merak
-               
-               // This doesn't work, as internally Merak records the contacts as having no subscription,
-               // but doesn't send any subscription requests to the client.  Craptacular.
-               if (!$exists && $this->is_merak && !$is_service) {
-                       $this->roster[$from_jid] = array(
-                               "username"              => $f_username,
-                               "domain"                => $f_domain,
-                               "resource"              => $f_resource,
-                               "jid"                   => $from_jid,
-                               "transport"             => $this->get_transport($f_domain)
-                       );
-                       $exists = true;
-               }
-               */
-               
-               if ($exists) {
-                       if ($is_service && $this->handle_services_internally) {
-                               // $this->dlog("SVC: rosteritem=service[{$from_jid}]");
-                               $use_services_array = true;
-                               $rosteritem = &$this->services[$from_jid];
-                       } else {
-                               // $this->dlog("SVC: rosteritem=roster[{$from_jid}]");
-                               $use_services_array = false;
-                               $rosteritem = &$this->roster[$from_jid];
-                               
-                               unset($rosteritem['customnickname']);
-                       }
-               } else {
-                       // Ignore roster updates for JIDs not in our roster, except
-                       // for subscription requests...
-                       
-                       if ($type=="available") {
-                               // ... but make note of the presence of non-roster items here, in case
-                               // the roster item is sent AFTER the presence packet... then we can apply the
-                               // presence when the roster item is received
-                               $show = $this->_show($this->_node($packet,array('presence','#','show',0,'#')));
-                               $this->presence_cache[$from_jid] = array(
-                                       "status"=>$this->_node($packet,array('presence','#','status',0,'#')),
-                                       "show"=>$show ? $show : "on"
-                               );
-                               // $this->dlog("TRACE::_handle_presence(): Caching presence for [$from_jid]; type=available, status=[".$this->presence_cache[$from_jid]["status"]."], show=[".$this->presence_cache[$from_jid]["show"]."]");
-                               
-                               return;
-                       }
-                       
-                       if ($type!="subscribe") {
-                               // $this->dlog("TRACE::_handle_presence(): type!=subscribe; exiting _handle_presence()");
-                               return;
-                       }
-                       // $this->dlog("TRACE::_handle_presence(): type=subscribe; passing through");
-               }
-               $call_update = false;
-
-               /*
-               ob_start();
-               echo "\n----PRESENCE----\n";
-               echo "[$type]\n";
-               var_dump($packet);
-               echo "----END PRESENCE----\n\n";
-               $y = ob_get_contents();
-               $this->dlog($y);
-               ob_end_clean();
-               */
-
-               switch($type) {
-                       case "error":
-                               $this->_handle_error(&$packet);
-                               break;
-                       case "probe":
-                               $this->_call_handler('probe',$packet);
-                               break;
-                       case "subscribe":
-                               // note: $rosteritem is not set here
-                               $this->_call_handler('subscribe',$packet);
-                               break;
-                       case "subscribed":
-                               $this->_call_handler('subscribed',$packet);
-                               break;
-                       case "unsubscribe":
-                               $this->_call_handler('unsubscribe',$packet);
-                               break;
-                       case "unsubscribed":
-                               $this->_call_handler('unsubscribed',$packet);
-                               break;
-                       case "unavailable":
-                               // $this->dlog("NOTE: Setting rosteritem[status] for ".($use_services_array?"service":"roster item")." $from_jid to off (unavailable)");
-                               $rosteritem["show"] = "off";
-                               $call_update = true;
-                               break;
-                       case "available":
-                               $rosteritem["status"] = $this->_node($packet,array('presence','#','status',0,'#'));
-                               $show = $this->_show($this->_node($packet,array('presence','#','show',0,'#')));
-                               $rosteritem["show"] = $show ? $show : "on"; // away, chat, xa, dnd, or "" = online
-                               
-                               if ($this->_node($packet,array('presence','#','x',0,'@','xmlns'))=='vcard-temp:x:update') {
-                                       $rosteritem['customnickname'] = $this->_node($packet,array('presence','#','x',0,'#','nickname',0,'#'));
-                               }
-
-                               // $this->dlog("NOTE: Setting rosteritem[status] for ".($use_services_array?"service":"roster item")." $from_jid to ".$rosteritem["status"]);
-                               $call_update = true;
-                               break;
-                       default:
-                               $this->_log("Unknown presence type: $type");
-                               break;
-               }
-               if ($call_update) {
-                       if ($use_services_array) {
-                               // $this->dlog("TRACE::_handle_presence(): calling serviceupdate for $from");
-                               $this->_call_handler("serviceupdate",$from,false);
-                       } else {
-                               // $this->dlog("TRACE::_handle_presence(): calling rosterupdate for $from");
-                               $this->_call_handler("rosterupdate",$from,false);
-                       }
-               }
-       }
-       
-       // handle Stream packets
-       function _handle_stream(&$packet) {
-               $ss = $this->_node($packet,array('stream:stream','@'));
-               if (is_array($ss)) {
-                       if ($ss['from'] == $this->_server_host
-                               && $ss['xmlns'] == "jabber:client"
-                               && $ss["xmlns:stream"] == "http://etherx.jabber.org/streams")
-                       {
-                               $this->_stream_id = $this->_node($packet,array("stream:stream",'@','id'));
-                               $this->_call_handler('connected');
-                               return;
-                       }
-               }
-
-               $this->_log("Unrecognized stream packet");
-               var_dump($packet);
-       }
-
-       // handle Stream features packets
-       function _handle_stream_features(&$packet) {
-               $this->features = &$packet;
-       }
-       
-       // handle stream error
-       function _handle_stream_error(&$packet) {
-               $this->_call_handler('stream_error',$packet);
-       }
-
-
-
-       // ==== Event Handlers (Event Specific) ==================================================
-
-       // receives a list of authentication methods and sends an authentication
-       // request with the most appropriate one
-       function _on_authentication_methods(&$packet) {
-               $auth_id = $this->_node($packet,array('iq','@','id'));
-               $auth_request_sent = true;
-               
-               // check for auth method availability in descending order (best to worst)
-               
-               // Note: As noted in JEP-0078 (http://www.jabber.org/jeps/jep-0078.html), the so-called
-               // "zero-knowledge" authentication is no stronger than digest authentication, and is not
-               // even documented in JEP-0078 anymore.  As such, it is not supported here.
-               //
-               // SASL authentication is not yet supported (for unrelated reasons).
-               
-               // digest
-               if ($this->_nodeset($packet,array('iq','#','query',0,'#','digest'))) {
-                       $this->_sendauth_digest($auth_id);
-
-               // plain text
-               } elseif ($this->_node($packet,array('iq','#','query',0,'#','password'))) {
-                       $this->_sendauth_plaintext($auth_id);
-
-               // no auth methods
-               } else {
-                       $auth_request_sent = false;
-                       $this->_call_handler("authfailure",-1,"No authentication method available","");
-                       $this->_log("ERROR: _on_authentication_methods() #2 - No auth method available!");
-               }
-               
-               if ($auth_request_sent) {
-                       $this->_set_iq_handler("_on_authentication_result",$auth_id);
-               }
-               
-       }
-       
-       // receives the results of an authentication attempt
-       function _on_authentication_result(&$packet) {
-               $auth_id = $this->_node($packet,array('iq','@','id'));
-               $result_type = $this->_node($packet,array('iq','@','type'));
-               
-               if ($result_type=="result") {
-                       if ($this->auto_server_identify) $this->request_version($this->_server_host);
-                       
-                       $this->_call_handler("authenticated");
-                       $this->_authenticated = true;
-               } elseif ($result_type=="error") {
-                       $this->_handle_iq_error(&$packet,"authfailure");
-               }
-       }
-       
-       // receives the results of a service browse query
-       function _on_browse_result(&$packet) {
-               $packet_type = $this->_node($packet,array('iq','@','type'));
-               
-//             $this->_log("BROWSE packet: ".var_export($packet,true));
-               
-               // did we get a result?  if so, process it, and remember the service list       
-               if ($packet_type=="result") {
-                       
-                       $this->services = array();
-
-                       //$this->_log("SERVICES: ".print_r($packet,true));
-                       
-                       //$this->_log("\n\nSOFTWARE: ".$this->server_software." v".$this->server_version."\n\n");
-                       
-                       if ($this->_node($packet,array('iq','#','service'))) {
-                               // Jabberd uses the 'service' element
-                               $servicekey = $itemkey = 'service';
-                       } elseif ($this->_node($packet,array('iq','#','item'))) {
-                               // Older versions of Merak use 'item'
-                               $servicekey = $itemkey = 'item';
-                       } elseif ($this->_node($packet,array('iq','#','query'))) {
-                               // Newer versions of Merak use 'query'
-                               $servicekey = 'query';
-                               $itemkey = 'item';
-                       } else {
-                               // try to figure out what to use
-                               $k = array_keys($this->_node($packet,array('iq','#')));
-                               $servicekey = $k[0];
-                               if (!$servicekey) return;
-                       }
-                       // if the item key is incorrect, try to figure that out as well
-                       if ($this->_node($packet,array('iq','#',$servicekey)) && !$this->_node($packet,array('iq','#',$servicekey,0,'#',$itemkey))) {
-                               $k = array_keys($this->_node($packet,array('iq','#',$servicekey,0,'#')));
-                               $itemkey = $k[0];
-                       }
-                       
-                       $number_of_services = is_array($this->_node($packet,array('iq','#',$servicekey,0,'#',$itemkey))) ? count($this->_node($packet,array('iq','#',$servicekey,0,'#',$itemkey))) : 0;
-
-                       $services_updated = false;
-                       for ($a = 0; $a < $number_of_services; $a++)
-                       {
-                               $svc = $this->_node($packet,array('iq','#',$servicekey,0,'#',$itemkey,$a));
-
-                               $jid = strtolower($this->_node($svc,array('@','jid')));
-                               $is_new = !isset($this->services[$jid]);
-                               $this->services[$jid] = array(  
-                                                                                       "type"                  => strtolower($this->_node($svc,array('@','type'))),
-                                                                                       "status"                => "Offline",
-                                                                                       "show"                  => "off",
-                                                                                       "name"                  => $this->_node($svc,array('@','name')),
-                                                                                       "namespaces"    => array()
-                               );
-                               
-                               $number_of_namespaces = is_array($this->_node($packet,array('iq','#',$servicekey,0,'#',$itemkey,$a,'#','ns'))) ? count($this->_node($packet,array('iq','#',$servicekey,0,'#',$itemkey,$a,'#','ns'))) : 0;
-                               for ($b = 0; $b < $number_of_namespaces; $b++) {
-                                               $this->services[$jid]['namespaces'][$b] = $this->_node($packet,array('iq','#',$servicekey,0,'#',$itemkey,$a,'#','ns',$b,'#'));
-                               }
-
-                               if ($this->service_single_update) {
-                                       $services_updated = true;
-                               } else {
-                                       $this->_call_handler("serviceupdate",$jid,$is_new);
-                               }
-                       }
-                       
-                       if ($this->service_single_update && $services_updated) {
-                               $this->_call_handler("serviceupdate",NULL,$is_new);
-                       }
-                       
-                       $this->_log("Received service list");
-                       //$this->_log("Received service list: ".print_r($this->services,true));
-               // choke on error
-               } elseif ($packet_type=="error") {
-                       $this->_handle_iq_error($packet);
-                       
-               // confusion sets in
-               } else {
-                       $this->_log("Don't know what to do with jabber:iq:browse packet!");
-               }
-       }
-       
-       // request software version from a JabberID
-       function request_version($jid) {
-               
-               $this->_log('Requesting version information from '.$jid);
-               // setup handler to automatically respond to the request (it would anyway,
-               // because of how we handle version packets, but... hey, why not be thorough)
-               $ver_id = $this->_unique_id("ver");
-               
-               $this->_set_iq_handler("_handle_version_packet",$ver_id);
-
-               return $this->_send_iq($jid, 'get', $ver_id, "jabber:iq:version");              
-       }
-       
-       // handle a jabber:iq:version packet (either a request, or a response)
-       function _handle_version_packet(&$packet) {
-               $packet_type = $this->_node($packet,array('iq','@','type'));
-               $from = $this->_node($packet,array('iq','@','from'));
-               $packetid = $this->_node($packet,array('iq','@','id'));
-
-               if ($packet_type=="result") {
-                       // did we get a result?  if so, process it, and update the contact's version information
-                       $jid = $this->_bare_jid($from);
-                       
-                       $version = $this->_node($packet,array('iq','#','query',0,'#'));
-                       $this->_log("$jid/".$this->_server_host);
-                       if ($jid==$this->_server_host) {
-                               //$this->_log("\n\n\n\nVERSION: ".print_r($version,true)."\n\n\n\n".print_r($packet,true)."\n\n\n\n");
-                               $this->server_software = $this->_node($version,array('name',0,'#'));
-                               $this->server_version = $this->_node($version,array('version',0,'#'));
-                               $this->server_os = $this->_node($version,array('os',0,'#'));
-                               
-                               $this->is_merak = strtolower(substr($this->server_software,0,5))=="merak";
-                       } elseif ($this->roster[$jid]) {
-                               $this->roster[$jid]["version"] = $version;
-                       }
-
-                       // $this->dlog("TRACE::_handle_version_packet(): calling rosterupdate for $jid");
-                       $this->_call_handler("rosterupdate",$jid,false);
-
-               } elseif ($packet_type=="get") {
-                       // did we get an inquiry?  if so, send our version info
-                       $payload        = "<name>{$this->_iq_version_name}</name><version>{$this->_iq_version_version}</version>";
-                       if ($this->_iq_version_os) $payload .= "<os>{$this->_iq_version_os}</os>";
-                       $packet         = $this->_send_iq($from, 'result', $packetid, "jabber:iq:version", $payload);
-               }
-               // other types of packets are probably just error responses (eg: the remote
-               // client doesn't support jabber:iq:version requests) so we ignore those
-               
-               return true;
-       }
-       
-       // handle a jabber:iq:time packet (either a request, or a response)
-       function _handle_time_packet(&$packet) {
-               $packet_type = $this->_node($packet,array('iq','@','type'));
-               $from = $this->_node($packet,array('iq','@','from'));
-               $packetid = $this->_node($packet,array('iq','@','id'));
-
-               if ($packet_type=="result") {
-                       // did we get a result?  if so, process it, and update the contact's time information
-                       $jid = $this->_bare_jid($from);
-                       
-                       $timeinfo = $this->_node($packet,array('iq','#','query',0,'#'));
-                       $this->roster[$jid]["time"] = $timeinfo;
-
-                       // $this->dlog("TRACE::_handle_time_packet(): calling rosterupdate for $jid");
-                       $this->_call_handler("rosterupdate",$jid,false);
-               } elseif ($packet_type=="get") {
-                       // did we get an inquiry?  if so, send our time info
-                       $utc = gmdate('Ymd\TH:i:s');
-                       $tz = date("T");
-                       $display = date("D M d H:i:s Y");
-                       
-                       $payload        = "<utc>{$utc}</utc><tz>{$tz}</tz><display>{$display}</display>";
-                       $packet         = $this->_send_iq($from, 'result', $packetid, "jabber:iq:time", $payload);
-               }
-               // other types of packets are probably just error responses (eg: the remote
-               // client doesn't support jabber:iq:time requests) so we ignore those
-               
-               return true;
-       }
-       
-       // receives the results of a roster query
-       //
-       // Note: You should always browse services BEFORE calling get_roster(), as this
-       // will ensure that the correct services get marked as "registered" in $this->services,
-       // and each roster contact will automatically have its "transport" element set to the
-       // correct transport.
-       function _on_roster_result(&$packet) {
-               $packet_type = $this->_node($packet,array('iq','@','type'));
-
-               // did we get a result?  if so, process it, and remember the service list       
-               if (($packet_type=="result") || ($packet_type=="set")) {
-                       
-                       $roster_updated = false;
-
-                       $itemlist = $this->_node($packet,array('iq','#','query',0,'#','item'));
-                       $number_of_contacts = is_array($itemlist) ? count($itemlist) : 0;
-                       
-                       //echo "<pre>"; echo "itemlist:\n"; var_dump($itemlist); echo "</pre>";
-
-                       for ($a = 0; $a < $number_of_contacts; $a++)
-                       {
-                               if (!isset($itemlist[$a])) continue;
-                               
-                               $queryitem = &$itemlist[$a];
-                               //echo "<pre>"; echo "itemlist:\n"; var_dump($queryitem); echo "</pre>";
-                               $jid = strtolower($this->_node($queryitem,array('@','jid')));
-                               
-                               $subscription = $this->_node($queryitem,array('@','subscription'));
-                               
-                               
-                               list($u_username,$u_domain,$u_resource) = $this->_split_jid($jid);
-                               //echo "[$u_username/$u_domain/$u_resource/$jid]";
-                               $jid = ($u_username?"{$u_username}@":"").$u_domain;
-                               
-                               
-                               $is_new = !isset($this->roster[$jid]);
-                               
-                               //$x = $this->dump($this->roster[$jid]);
-                               // $this->dlog("TRACE::_on_roster_result(): processing roster contact [{$jid}] (is_new=={$is_new}; existing item=[{$x}])");
-                               
-                               
-                               // Is it a transport?
-                               $is_service = (!strlen($u_username)); 
-                               if ($is_service) {
-                                       // are we registered with it?
-                                       /*if ($u_resource=="registered") {*/
-                                               if (!in_array($subscription,array("none","remove"))) { // if we're not subscribed to it, then we'll consider it unregistered
-                                                       $this->services[$jid]["registered"] = true;
-                                               }
-                                       /*}*/
-                               }
-                       
-                               // don't add the entry to the roster if it's a service, and we've been
-                               // configured to handle service presence internally (via $this->services)
-                               if (!($is_service && $this->handle_services_internally)) {
-                                       // if not new, don't clobber the old presence/availability
-                                       $u_jid = $u_username."@".$u_domain;
-                                       $status = $is_new?"Offline":$this->roster[$jid]["status"];
-                                       $show = $is_new?"off":$this->roster[$jid]["show"];
-                                       
-                                       // if presence was received before roster, grab the show value from the presence
-                                       if ($this->presence_cache[$u_jid]) {
-                                               if (!$show || $is_new) {
-                                                       $show = $this->presence_cache[$u_jid]["show"];
-                                                       // $this->dlog("TRACE::_on_roster_result: Using cached 'show' state for [{$u_jid}]; show=[{$show}]");
-                                               }
-                                               if (!$status || $is_new) {
-                                                       $status = $this->presence_cache[$u_jid]["status"];
-                                                       // $this->dlog("TRACE::_on_roster_result: Using cached 'status' state for [{$u_jid}]; status=[{$status}]");
-                                               }
-       
-                                               // remove any cached presence info, as the roster item now exists
-                                               // $this->dlog("TRACE::_on_roster_result: Clearing presence cache for {$u_jid}");
-                                               unset($this->presence_cache[$u_jid]);
-                                       }
-                                       
-                                       $nodename = $this->_node($queryitem,array('@','name'));
-                                       $rostername = strlen($nodename) ? $nodename : $u_username;
-                                       
-                                       
-                                       // prepare the roster item
-                                       $rosteritem = array(
-                                                                                               "name"                  => $rostername,
-                                                                                               "subscription"  => $this->_node($queryitem,array('@','subscription')),
-                                                                                               "ask"                   => $this->_node($queryitem,array('@','ask')),
-                                                                                               "group"                 => $this->_node($queryitem,array('#','group',0,'#')),
-                                                                                               "status"                => $status,
-                                                                                               "show"                  => $show,
-                                                                                               "username"              => $u_username,
-                                                                                               "domain"                => $u_domain,
-                                                                                               "resource"              => $u_resource,
-                                                                                               "jid"                   => $u_jid,
-                                                                                               "transport"             => $this->get_transport($u_domain)
-                                                                                       );
-                                       if ($is_new) {
-                                               // if it's a new entry, just add it to the roster
-                                               $this->roster[$jid] = $rosteritem;
-                                       } else {
-                                               // otherwise, carefully update the existing entry, preserving
-                                               // any elements that may have been added externally
-                                               foreach ($rosteritem as $k=>$v) {
-                                                       $this->roster[$jid][$k] = $v;
-                                               }
-                                       }
-                                       
-                                       //$this->_log('ROSTER UPDATE: '.print_r($this->roster[$jid],true));
-                                       // you may wish to set roster_single_update to TRUE before
-                                       // calling your initial browse(); this will allow you to
-                                       // initialize your entire roster in one swoop, rather than
-                                       // doing it contact-by-contact
-                                       if ($this->roster_single_update) {
-                                               // $this->dlog("TRACE::_on_roster_result(): updated contact for future roster_single_update; jid=$jid,is_new=[$is_new]");
-
-                                               $roster_updated = true;
-                                       } else {
-                                               // $this->dlog("TRACE::_on_roster_result(): calling rosterupdate for jid=$jid,is_new=$is_new (individual)");
-                                               $this->_call_handler("rosterupdate",$jid,$is_new);
-                                       }
-                               }
-                       }
-                       
-                       if ($this->roster_single_update && $roster_updated) {
-                               // $this->dlog("TRACE::_on_roster_result(): calling rosterupdate for jid=NULL,is_new=false (roster_single_update==true)");
-                               $this->_call_handler("rosterupdate",NULL,false);
-                       }
-
-                       $this->_log("Received roster");
-               // choke on error
-               } elseif ($packet_type=="error") {
-                       $this->_handle_iq_error($packet);
-                       
-               // confusion sets in
-               } else {
-                       $this->_log("Don't know what to do with jabber:iq:roster packet!");
-               }
-       }
-       
-       function _is_error_packet($packet) {
-               $packet_type = $this->_node($packet,array('iq','@','type'));
-               return ( $packet_type == 'error' && $this->_nodeset($packet,array('iq','#','error',0,'#')) );
-       }
-       
-       // receives the results of an account registration 'get' query (retrieving fields)
-       function _on_register_get_result(&$packet) {
-               $packet_type = $this->_node($packet,array('iq','@','type'));
-               $reg_id = $this->_unique_id("reg");
-
-               if ($packet_type=="result") {
-
-                       if ($this->_nodeset($packet,array('iq','#','query',0,'#','registered',0,'#'))) {
-                               $this->_call_handler("regfailure",-1,"Username already registered","");
-                               return;
-                       } 
-       
-                       $key = $this->_node($packet,array('iq','#','query',0,'#','key',0,'#'));
-                       unset($packet);
-       
-                       // Looks like CJP just hardcoded these fields, regardless of what the server sends...?!
-                       // FIXME: parse fields dynamically this when time permits
-                       $payload = "<username>{$this->_username}</username>
-               <password>{$this->_password}</password>
-               <email>{$this->_reg_email}</email>
-               <name>{$this->_reg_name}</name>\n";
-               
-                       $payload .= ($key) ? "<key>$key</key>\n" : '';
-       
-                       $this->_set_iq_handler("_on_register_set_result",$reg_id);
-                       $this->_send_iq($this->_server_host, 'set', $reg_id, "jabber:iq:register", $payload);
-               
-               
-               } elseif ($this->_is_error_packet($packet)) {
-                       $this->_handle_iq_error(&$packet,"regfailure");
-               
-               } else {
-                       $this->_call_handler("regfailure",-2,"Unrecognized response from server","");
-               }
-       }
-       
-       // receives the results of an account registration 'set' query (the actual result of
-       // the account registration attempt)
-       function _on_register_set_result(&$packet) {
-               $packet_type = $this->_node($packet,array('iq','@','type'));
-               $error_code = 0;
-               
-               if ($packet_type=="result") {
-
-                       if ($this->_resource) {
-                               $this->jid = "{$this->_username}@{$this->_server_host}/{$this->_resource}";
-                       } else {
-                               $this->jid = "{$this->_username}@{$this->_server_host}";
-                       }
-                       $this->_call_handler("registered",$this->jid);
-                       
-               } elseif ($this->_is_error_packet($packet)) {
-                       // "conflict" error, i.e. already registered
-                       if ($this->_node($packet,array('iq','#','error',0,'@','code')) == '409') {
-                               $this->_call_handler("regfailure",-1,"Username already registered","");
-                       } else {
-                               $this->_handle_iq_error(&$packet,"regfailure");
-                       }
-
-               } else {
-                       $this->_call_handler("regfailure",-2,"Unrecognized response from server");
-               }
-       }
-       
-       function _on_deregister_result(&$packet) {
-
-               $packet_type = $this->_node($packet,array('iq','@','type'));
-               
-               if ($packet_type=="result") {
-                       $this->_call_handler("deregistered",$this->jid);
-               } elseif ($this->_is_error_packet($packet)) {
-                       $this->_handle_iq_error(&$packet,"deregfailure");
-               } else {
-                       $this->_call_handler("deregfailure",-2,"Unrecognized response from server");
-               }               
-       }
-       
-
-       // receives the result of a password change     
-       function _on_chgpassword_result(&$packet) {
-               $packet_type = $this->_node($packet,array('iq','@','type'));
-               if ($packet_type=="result") {
-                       $this->_call_handler("passwordchanged");
-                       
-               } elseif ($this->_is_error_packet($packet)) {
-                       $this->_handle_iq_error(&$packet,"passwordfailure");
-               } else {
-                       $this->_call_handler("passwordfailure",-2,"Unrecognized response from server");
-               }                               
-       }
-       
-       // receives the result of a service (transport) registration
-       function _on_servicefields_result(&$packet) {
-               $packet_type = $this->_node($packet,array('iq','@','type'));
-               $packet_id = $this->_node($packet,array('iq','@','id'));
-
-               if ($packet_type=="result") {
-                               
-                       $reg_key = "";
-                       $reg_instructions = "";
-                       $reg_x = "";
-                       $fields = array();
-                       
-                       foreach ($this->_node($packet,array('iq','#','query',0,'#')) as $element => $data) {
-                               switch($element) {
-                                       case "key":
-                                               $reg_key = $this->_node($data,array(0,'#'));
-                                               break;
-                                       case "instructions":
-                                               $reg_instructions = $this->_node($data,array(0,'#'));
-                                               break;
-                                       case "x":
-                                               $reg_x = $this->_node($data,array(0,'#'));
-                                               break;
-                                       default:
-                                               $fields[] = $element;
-                                               break;
-                               }
-                       }
-                       $this->_call_handler("servicefields",&$fields,$packet_id,$reg_key,$reg_instructions,&$reg_x);
-                       
-               } elseif ($this->_is_error_packet($packet)) {
-                       $this->_handle_iq_error(&$packet,"servicefieldsfailure");
-               } else {
-                       $this->_call_handler("servicefieldsfailure",-2,"Unrecognized response from server");
-               }                               
-       }
-       
-       function _on_serviceregister_result(&$packet) {
-               $packet_type = $this->_node($packet,array('iq','@','type'));
-               $from = $this->_node($packet,array('iq','@','from'));
-               if ($packet_type == 'result') {
-                       if ($this->_nodeset($packet,array('iq','#','query',0,'#','registered',0,'#'))) {
-                               $this->_call_handler("serviceregfailure",-1,"Already registered with service","");
-                       } else {
-                               $jid = $this->_bare_jid($from);
-                               $this->_call_handler("serviceregistered",$from);
-                       }
-               } elseif ($this->_is_error_packet($packet)) {
-                       $this->_handle_iq_error(&$packet,"serviceregfailure");
-               } else {
-                       $this->_call_handler("serviceregfailure",-2,"Unrecognized response from server");
-               }                               
-       }
-       
-       function _on_servicedereg_initial_result(&$packet) {
-               
-               $packet_type = $this->_node($packet,array('iq','@','type'));
-               $from = $this->_node($packet,array('iq','@','from'));
-               
-               if ($packet_type == 'result') {
-                       
-                       // we're now deregistered with the transport, but we need to remove
-                       // our roster subscription
-                       $dereg_id = $this->_unique_id("svcdereg");
-                       $this->_set_iq_handler("_on_servicedereg_final_result",$dereg_id);
-
-
-                       $this->services[$from]["registered"] = false;
-                       $this->services[$from]["subscription"] = "none";
-
-                       $payload = "<item jid='{$from}' subscription='remove'/>";
-       
-                       $this->dlog("TRACE:: _on_servicedereg_initial_result() has positive result, setting handler ID#$dereg_id for final result");
-       
-                       if ($this->_send_iq(NULL, 'set', $dereg_id, "jabber:iq:roster", $payload)) {
-                               $this->dlog("TRACE:: _on_deregister_initial_result() SENT, existing");
-
-                               return $dereg_id;
-                       } else {
-                               $this->dlog("TRACE:: _on_deregister_initial_result() FAILURE!!");
-
-                               return false;
-                       }                       
-                       
-               } elseif ($this->_is_error_packet($packet)) {
-                       $this->_handle_iq_error(&$packet,"servicederegfailure");
-               } else {
-                       $this->_call_handler("servicederegfailure",-2,"Unrecognized response from server");
-               }                               
-       }
-
-       function _on_servicedereg_final_result(&$packet) {
-               $this->dlog("TRACE:: _on_deregister_final_result() called!");
-
-               $packet_type = $this->_node($packet,array('iq','@','type'));
-               if ($packet_type == 'result') {
-                       $this->_call_handler("servicederegistered");
-               } elseif ($this->_is_error_packet($packet)) {
-                       $this->_handle_iq_error(&$packet,"servicederegfailure");
-               } else {
-                       $this->_call_handler("servicederegfailure",-2,"Unrecognized response from server");
-               }                               
-       }
-       
-       function _on_rosteradd_result(&$packet) {
-               $packet_type = $this->_node($packet,array('iq','@','type'));;
-               if ($packet_type == 'result') {
-
-                       $this->_call_handler("rosteradded",$this->_node($packet,array('iq','@','id')));
-                       
-               } elseif ($this->_is_error_packet($packet)) {
-                       $this->_handle_iq_error(&$packet,"rosteraddfailure");
-               } else {
-                       $this->_call_handler("rosteraddfailure",-2,"Unrecognized response from server");
-               }                               
-       }
-
-       function _on_rosterupdate_result(&$packet) {
-               $packet_type = $this->_node($packet,array('iq','@','type'));
-               if ($packet_type == 'result') {
-                       $this->_call_handler("contactupdated",$this->_node($packet,array('iq','@','id')));
-                       
-               } elseif ($this->_is_error_packet($packet)) {
-                       $this->_handle_iq_error(&$packet,"contactupdatefailure");
-               } else {
-                       $this->_call_handler("contactupdatefailure",-2,"Unrecognized response from server");
-               }                               
-       }
-       function _on_rosterremove_result(&$packet) {
-               $packet_type = $this->_node($packet,array('iq','@','type'));
-               if ($packet_type == 'result') {
-                       $this->_call_handler("rosterremoved",$this->_node($packet,array('iq','@','id')));
-                       
-               } elseif ($this->_is_error_packet($packet)) {
-                       $this->_handle_iq_error(&$packet,"rosterremovefailure");
-               } else {
-                       $this->_call_handler("rosterremovefailure",-2,"Unrecognized response from server");
-               }                               
-       }
-       
-       function _on_private_data(&$packet) {
-               $packet_type = $this->_node($packet,array('iq','@','type'));
-               if ($packet_type == 'result') {
-
-                       $rootnode = $this->_node($packet,array('iq','#','query',0,'#'));
-                       unset($rootnode[0]);
-                       $rootnode = array_shift($rootnode);
-                       $data = $rootnode[0];
-                       $namespace = $this->_node($data,array('@','xmlns'));
-                       $rawvalues = $this->_node($data,array('#'));
-                       
-                       $values = array();
-                       if (is_array($rawvalues)) {
-                               foreach ($rawvalues as $k=>$v) {
-                                       $values[$k] = $this->_node($v,array(0,'#'));
-                               }
-                       }
-                       
-                       $this->_call_handler("privatedata",$this->_node($packet,array('iq','@','id')),$namespace,$values);
-                       
-               } elseif ($this->_is_error_packet($packet)) {
-                       $this->_handle_iq_error(&$packet,"privatedatafailure");
-               } else {
-                       $this->_call_handler("privatedatafailure",-2,"Unrecognized response from server");
-               }                               
-       }
-
-
-       // handles a generic IQ error; fires the specified error handler method
-       // with the error code/message retrieved from the IQ packet
-       function _handle_iq_error(&$packet,$error_handler="error") {
-               $error = $this->_node($packet,array('iq','#','error',0));
-               $xmlns = $this->_node($packet,array('iq','#','query',0,'@','xmlns'));
-               $this->_call_handler(
-                       $error_handler,
-                       $this->_node($error,array('@','code')),
-                       $this->_node($error,array('#')),
-                       $xmlns,
-                       $packet
-               );
-       }
-       
-       // handles a generic error; fires the specified error handler method
-       // with the error code/message retrieved from the packet
-       function _handle_error(&$packet,$error_handler="error") {
-               $packet = array_shift($packet);
-               $error = $this->_node($packet,array('#','error',0));
-               $xmlns = $this->_node($packet,array('#','query',0,'@','xmlns'));
-               $this->_call_handler(
-                       $error_handler,
-                       $this->_node($error,array('@','code')),
-                       $this->_node($error,array('#')),
-                       $xmlns,
-                       $packet
-               );
-       }
-       
-       
-       
-       // ==== Authentication Methods ===========================================================
-
-       function _sendauth_digest($auth_id) {
-               $this->_log("Using digest authentication");
-
-               $payload = "<username>{$this->_username}</username>
-       <resource>{$this->_resource}</resource>
-       <digest>" . sha1($this->_stream_id . $this->_password) . "</digest>";
-
-               $this->_send_iq(NULL, 'set', $auth_id, "jabber:iq:auth", $payload);
-       }
-
-       function _sendauth_plaintext($auth_id) {
-               $this->_log("Using plaintext authentication");
-
-               $payload = "<username>{$this->_username}</username>
-       <password>{$this->_password}</password>
-       <resource>{$this->_resource}</resource>";
-
-               $this->_send_iq(NULL, 'set', $auth_id, "jabber:iq:auth", $payload);
-       }       
-
-
-       // ==== Helper Methods ===================================================================
-       
-       function _show($show) {
-               // off is not valid, but is used internally
-               $valid_shows = array("","away","chat","dnd","xa","off");
-               if (!in_array($show,$valid_shows)) $show = "";
-               
-               return $show;
-       }
-
-       function dump(&$v) {
-               ob_start();
-               var_dump($v);
-               $x = ob_get_contents();
-               ob_end_clean();
-               return $x;
-               
-               
-               return print_r($v,true); 
-       }
-
-       
-       function standardize_transport($transport,$force=true) {
-               $transports = array("msn","aim","yim","icq","jab");
-               if (!in_array($transport,$transports)) {
-                       if ($transport=="aol") {
-                               $transport = "aim";
-                       } elseif ($transport=="yahoo") {
-                               $transport = "yim";
-                       } else {
-                               if ($force) $transport = "jab";
-                       }
-               }
-               return $transport;
-       }
-               
-       function get_transport($domain) {
-               $transport = $this->services[$domain]["type"];
-               return $this->standardize_transport($transport);
-       }
-
-
-
-
-
-       // ==== Packet Handling & Connection Methods =============================================
-
-       // generates and transmits an IQ packet
-       function _send_iq($to = NULL, $type = 'get', $id = NULL, $xmlns = NULL, $payload = NULL, $from = NULL) {
-               if (!preg_match("/^(get|set|result|error)$/", $type)) {
-                       unset($type);
-
-                       $this->_log("ERROR: _send_iq() #2 - type must be 'get', 'set', 'result' or 'error'");
-                       return false;
-               
-               } elseif ($id && $xmlns) {
-                       $xml = "<iq type='$type' id='$id'";
-                       $xml .= ($to) ? " to='$to'" : '';
-                       $xml .= ($from) ? " from='$from'" : '';
-                       $xml .= ">
-       <query xmlns='$xmlns'>
-               $payload
-       </query>
-</iq>";
-
-                       return $this->_send($xml);
-               } else {
-                       $this->_log("ERROR: SendIq() #1 - to, id and xmlns are mandatory");
-                       return false;
-               }
-       }       
-       
-       
-       // writes XML data to the socket; trims and UTF8 encodes $xml before
-       // sending unless $pristine is true
-       function _send($xml,$pristine = false) {
-               // need UTF8 encoding to prevent character coding issues when
-           // users enter international characters
-           /*
-           if (!$pristine) {
-                       $xml = trim(utf8_encode($xml));
-               if (!$xml) return false;
-           }
-           */
-               if(strlen($xml)==0) return true;
-               
-               if ($res = $this->_connection->socket_write($xml)) {
-                       $this->_log("SEND: $xml");
-               } else {
-                       $this->_log("ERROR SENDING: $xml");
-               }
-               return $res;
-       }       
-       
-       
-       
-       function _receive() {
-               unset($incoming);
-               $packet_count = 0;
-
-               $sleepfunc = $this->_sleep_func;
-
-               $iterations = 0; 
-               $empties = 0;
-               do {
-                       $line = $this->_connection->socket_read(16384);
-                       if (strlen($line)==0) {
-                               $empties++;
-                               if ($empties>15) break;
-                       } else {
-                               $empties = 0;
-                       }
-                       
-                       $incoming .= $line;
-                       $iterations++;
-                       
-               // the iteration limit is just a brake to prevent infinite loops if
-               // something goes awry in socket_read()
-               } while($iterations<200);
-
-               $incoming = trim($incoming);
-
-               if ($incoming != "") {
-                       //$this->_log("RECV: $incoming");
-
-                       $temp = $this->_split_incoming($incoming);
-                       
-                       $packet_count = count($temp);
-
-                       for ($a = 0; $a < $packet_count; $a++) {
-                               $this->_packet_queue[] = $this->xml->xmlize($temp[$a]);
-                               
-                               $this->_log("RECV: ".$temp[$a]);
-                               //.$this->_packet_queue[count($this->_packet_queue)-1]);
-                       }
-               }
-
-               return $packet_count;
-       }       
-       
-       function _get_next_packet() {
-               return array_shift($this->_packet_queue);
-       }
-       
-       function _split_incoming($incoming) {
-               $temp = preg_split("/<(message|iq|presence|stream)(?=[\:\s\>])/", $incoming, -1, PREG_SPLIT_DELIM_CAPTURE);
-               $array = array();
-
-               for ($a = 1; $a < count($temp); $a = $a + 2) {
-                       $array[] = "<" . $temp[$a] . $temp[($a + 1)];
-               }
-
-               return $array;
-       }
-       
-       
-}
-
-?>
\ No newline at end of file
diff --git a/message/output/jabber/jabberclass/class_SHA1Library.php b/message/output/jabber/jabberclass/class_SHA1Library.php
deleted file mode 100644 (file)
index 2b1e526..0000000
+++ /dev/null
@@ -1,264 +0,0 @@
-<?
-/*
- * This file was contributed (in part or whole) by a third party, and is
- * released under a BSD-compatible free software license.  Please see the
- * CREDITS and LICENSE sections below for details.
- * 
- *****************************************************************************
- *
- * DETAILS
- *
- * A PHP implementation of the Secure Hash Algorithm, SHA-1, as defined in
- * FIPS PUB 180-1.  This is used by Centova only when using PHP
- * versions older than 4.3.0 (which did not support the sha1() function) and
- * the server does not have the mhash extension installed.
- *
- *
- * CREDITS/LICENSE
- *
- * Adjusted from the Javascript implementation by Joror (daan@parse.nl).
- *
- * Javascript Version 2.1 Copyright Paul Johnston 2000 - 2002.
- * Other contributors: Greg Holt, Andrew Kepert, Ydnar, Lostinet
- * Distributed under the BSD License
- * See http://pajhome.org.uk/crypt/md5 for details.
- *
- */
-
-class SHA1Library
-{
-       /*
-        * Configurable variables. You may need to tweak these to be compatible with
-        * the server-side, but the defaults work in most cases.
-        */
-       var $hexcase = 0;  /* hex output format. 0 - lowercase; 1 - uppercase        */
-       var $b64pad  = ""; /* base-64 pad character. "=" for strict RFC compliance   */
-       var $chrsz   = 8;  /* bits per input character. 8 - ASCII; 16 - Unicode      */
-       
-       /*
-        * These are the functions you'll usually want to call
-        * They take string arguments and return either hex or base-64 encoded strings
-        */
-       function hex_sha1($s){return $this->binb2hex($this->core_sha1($this->str2binb($s),strlen($s) * $this->chrsz));}
-       function b64_sha1($s){return $this->binb2b64($this->core_sha1($this->str2binb($s),strlen($s) * $this->chrsz));}
-       function str_sha1($s){return $this->binb2str($this->core_sha1($this->str2binb($s),strlen($s) * $this->chrsz));}
-       function hex_hmac_sha1($key, $data){ return $this->binb2hex($this->core_hmac_sha1($key, $data));}
-       function b64_hmac_sha1($key, $data){ return $this->binb2b64($this->core_hmac_sha1($key, $data));}
-       function str_hmac_sha1($key, $data){ return $this->binb2str($this->core_hmac_sha1($key, $data));}
-       
-       /*
-        * Perform a simple self-test to see if the VM is working
-        */
-       function sha1_vm_test()
-       {
-               return $this->hex_sha1("abc") == "a9993e364706816aba3e25717850c26c9cd0d89d";
-       }
-       
-       /*
-        * Calculate the SHA-1 of an array of big-endian words, and a bit $length
-        */
-       function core_sha1($x, $len)
-       {
-               /* append padding */
-               $x[$len >> 5] |= 0x80 << (24 - $len % 32);
-               $x[(($len + 64 >> 9) << 4) + 15] = $len;
-       
-               $w = Array();
-               $a =  1732584193;
-               $b = -271733879;
-               $c = -1732584194;
-               $d =  271733878;
-               $e = -1009589776;
-       
-               for($i = 0; $i < sizeof($x); $i += 16)
-               {
-                       $olda = $a;
-                       $oldb = $b;
-                       $oldc = $c;
-                       $oldd = $d;
-                       $olde = $e;
-       
-                       for($j = 0; $j < 80; $j++)
-                       {
-                               if ($j < 16) 
-                                       $w[$j] = $x[$i + $j];
-                               else 
-                                       $w[$j] = $this->rol($w[$j-3] ^ $w[$j-8] ^ $w[$j-14] ^ $w[$j-16], 1);
-                                       
-                               $t = $this->safe_add(   $this->safe_add($this->rol($a, 5), $this->sha1_ft($j, $b, $c, $d)), 
-                                                                               $this->safe_add($this->safe_add($e, $w[$j]), $this->sha1_kt($j)));
-                               $e = $d;
-                               $d = $c;
-                               $c = $this->rol($b, 30);
-                               $b = $a;
-                               $a = $t;
-                       }
-
-                       $a = $this->safe_add($a, $olda);
-                       $b = $this->safe_add($b, $oldb);
-                       $c = $this->safe_add($c, $oldc);
-                       $d = $this->safe_add($d, $oldd);
-                       $e = $this->safe_add($e, $olde);
-               }
-               
-               return Array($a, $b, $c, $d, $e);
-       }
-       
-       /*
-        * Joror: PHP does not have the java(script) >>> operator, so this is a 
-        * replacement function. Credits to Terium.
-        */
-       function zerofill_rightshift($a, $b) 
-       { 
-               $z = hexdec(80000000); 
-               if ($z & $a) 
-               { 
-                       $a >>= 1; 
-                       $a &= (~ $z); 
-                       $a |= 0x40000000; 
-                       $a >>= ($b-1); 
-               } 
-               else 
-               { 
-                       $a >>= $b; 
-               } 
-               return $a; 
-       }
-       
-       /*
-        * Perform the appropriate triplet combination function for the current
-        * iteration
-        */
-       function sha1_ft($t, $b, $c, $d)
-       {
-               if($t < 20) return ($b & $c) | ((~$b) & $d);
-               if($t < 40) return $b ^ $c ^ $d;
-               if($t < 60) return ($b & $c) | ($b & $d) | ($c & $d);
-               return $b ^ $c ^ $d;
-       }
-       
-       /*
-        * Determine the appropriate additive constant for the current iteration
-        * Silly php does not understand the inline-if operator well when nested,
-        * so that's why it's ()ed now.
-        */
-       function sha1_kt($t)
-       {
-               return ($t < 20) ?  1518500249 : (($t < 40) ?  1859775393 :
-                               (($t < 60) ? -1894007588 : -899497514));
-       }  
-       
-       /*
-        * Calculate the HMAC-SHA1 of a key and some data
-        */
-       function core_hmac_sha1($key, $data)
-       {
-               $bkey = $this->str2binb($key);
-               if(sizeof($bkey) > 16) $bkey = $this->core_sha1($bkey, sizeof($key) * $this->chrsz);
-       
-               $ipad = Array();
-               $opad = Array();
-               
-               for($i = 0; $i < 16; $i++) 
-               {
-                       $ipad[$i] = $bkey[$i] ^ 0x36363636;
-                       $opad[$i] = $bkey[$i] ^ 0x5C5C5C5C;
-               }
-       
-               $hash = $this->core_sha1(array_merge($ipad,$this->str2binb($data)), 512 + sizeof($data) * $this->chrsz);
-               return $this->core_sha1(array_merge($opad,$hash), 512 + 160);
-       }
-       
-       /*
-        * Add integers, wrapping at 2^32. This uses 16-bit operations internally
-        * to work around bugs in some JS interpreters.
-        */
-       function safe_add($x, $y)
-       {
-               $lsw = ($x & 0xFFFF) + ($y & 0xFFFF);
-               $msw = ($x >> 16) + ($y >> 16) + ($lsw >> 16);
-               return ($msw << 16) | ($lsw & 0xFFFF);
-       }
-       
-       /*
-        * Bitwise rotate a 32-bit number to the left.
-        */
-       function rol($num, $cnt)
-       {
-               return ($num << $cnt) | $this->zerofill_rightshift($num, (32 - $cnt));
-       }
-       
-       /*
-        * Convert an 8-bit or 16-bit string to an array of big-endian words
-        * In 8-bit function, characters >255 have their hi-byte silently ignored.
-        */
-       function str2binb($str)
-       {
-               $bin = Array();
-               $mask = (1 << $this->chrsz) - 1;
-               for($i = 0; $i < strlen($str) * $this->chrsz; $i += $this->chrsz)
-                       $bin[$i >> 5] |= (ord($str{$i / $this->chrsz}) & $mask) << (24 - $i%32);
-               
-               return $bin;
-       }
-       
-       /*
-        * Convert an array of big-endian words to a string
-        */
-       function binb2str($bin)
-       {
-               $str = "";
-               $mask = (1 << $this->chrsz) - 1;
-               for($i = 0; $i < sizeof($bin) * 32; $i += $this->chrsz)
-                       $str .= chr($this->zerofill_rightshift($bin[$i>>5], 24 - $i%32) & $mask);
-               return $str;
-       }
-       
-       /*
-        * Convert an array of big-endian words to a hex string.
-        */
-       function binb2hex($binarray)
-       {
-               $hex_tab = $this->hexcase ? "0123456789ABCDEF" : "0123456789abcdef";
-               $str = "";
-               for($i = 0; $i < sizeof($binarray) * 4; $i++)
-               {
-                       $str .= $hex_tab{($binarray[$i>>2] >> ((3 - $i%4)*8+4)) & 0xF} .
-                                       $hex_tab{($binarray[$i>>2] >> ((3 - $i%4)*8  )) & 0xF};
-               }
-               
-               return $str;
-       }
-       
-       /*
-        * Convert an array of big-endian words to a base-64 string
-        */
-       function binb2b64($binarray)
-       {
-               $tab = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
-               $str = "";
-               for($i = 0; i < sizeof($binarray) * 4; $i += 3)
-               {
-                       $triplet =      ((($binarray[$i   >> 2] >> 8 * (3 -  $i   %4)) & 0xFF) << 16)
-                                               | ((($binarray[$i+1 >> 2] >> 8 * (3 - ($i+1)%4)) & 0xFF) << 8 )
-                                               |  (($binarray[$i+2 >> 2] >> 8 * (3 - ($i+2)%4)) & 0xFF);
-                       for($j = 0; $j < 4; $j++)
-                       {
-                               if($i * 8 + $j * 6 > sizeof($binarray) * 32) $str .= $this->b64pad;
-                               else $str .= $tab{($triplet >> 6*(3-j)) & 0x3F};
-                       }
-               }
-               return $str;
-       }
-}
-
-if ( !function_exists('sha1') )
-{
-       function sha1( $string, $raw_output = false )
-       {
-               $library = &new SHA1Library();
-               
-               return $raw_output ? $library->str_sha1($string) : $library->hex_sha1($string);
-       }
-}
-?>
\ No newline at end of file
diff --git a/message/output/jabber/jabberclass/class_XMLParser.php b/message/output/jabber/jabberclass/class_XMLParser.php
deleted file mode 100644 (file)
index 335ec24..0000000
+++ /dev/null
@@ -1,139 +0,0 @@
-<?php
-/*
- * This file was contributed (in part or whole) by a third party, and is
- * released under a BSD-compatible free software license.  Please see the
- * CREDITS and LICENSE sections below for details.
- * 
- *****************************************************************************
- *
- * DETAILS
- *
- * Provides the XML parser used by class_Jabber.php to parse Jabber XML data
- * received from the Jabber server.
- *
- *
- * CREDITS
- *
- * Originally by Hans Anderson (http://www.hansanderson.com/php/xml)
- * Adapted for class.jabber.php by Carlo Zottman (http://phpjabber.g-blog.net)
- * Adapted for class_Jabber.php by Steve Blinch (http://www.centova.com)
- *
- *
- * LICENSE
- *
- * xmlize() is by Hans Anderson, www.hansanderson.com/contact/
- *
- * Ye Ole "Feel Free To Use it However" License [PHP, BSD, GPL].
- * some code in xml_depth is based on code written by other PHPers
- * as well as one Perl script.  Poor programming practice and organization
- * on my part is to blame for the credit these people aren't receiving.
- * None of the code was copyrighted, though.
- *
- *
- * REFERENCE
- *
- * @ = attributes
- * # = nested tags
- * 
-*/
-
-class XMLParser {
-
-       function XMLParser() {
-       }
-       
-       // 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_OPTION_SKIP_WHITE is disabled as it clobbers valid 
-    // newlines in instant messages
-               xml_parser_set_option($parser, XML_OPTION_SKIP_WHITE, 0);
-               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 ($vals[$i]['value']) {
-                       array_push($children, trim($vals[$i]['value']));
-               }
-
-               while (++$i < count($vals)) {
-                       switch ($vals[$i]['type']) {
-                               case 'cdata':
-                                       array_push($children, trim($vals[$i]['value']));
-                                       break;
-
-                               case 'complete':
-                                       $tagname = $vals[$i]['tag'];
-                                       $size = sizeof($children[$tagname]);
-                                       $children[$tagname][$size]['#'] = trim($vals[$i]['value']);
-                                       if ($vals[$i]['attributes']) {
-                                               $children[$tagname][$size]['@'] = $vals[$i]['attributes'];
-                                       }
-                                       break;
-
-                               case 'open':
-                                       $tagname = $vals[$i]['tag'];
-                                       $size = sizeof($children[$tagname]);
-                                       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;
-       }
-
-
-
-       // TraverseXMLize()
-       // (c) acebone@f2s.com, a HUGE help!
-
-       function TraverseXMLize($array, $arrName = "array", $level = 0) {
-               if ($level == 0) {
-                       echo "<pre>";
-               }
-
-               while (list($key, $val) = @each($array)) {
-                       if (is_array($val)) {
-                               $this->TraverseXMLize($val, $arrName . "[" . $key . "]", $level + 1);
-                       } else {
-                               echo '$' . $arrName . '[' . $key . '] = "' . $val . "\"\n";
-                       }
-               }
-
-               if ($level == 0) {
-                       echo "</pre>";
-               }
-       }
-
-}
-?>
\ No newline at end of file
diff --git a/message/output/jabber/jabberclass/jabber_example.php b/message/output/jabber/jabberclass/jabber_example.php
deleted file mode 100644 (file)
index 6528bec..0000000
+++ /dev/null
@@ -1,224 +0,0 @@
-#!/usr/local/bin/php -q
-<?php
-/* Jabber Class Example
- * Copyright 2002-2007, Steve Blinch
- * http://code.blitzaffe.com
- * ============================================================================
- *
- * DETAILS
- *
- * Provides a very basic example of how to use class_Jabber.php.
- *
- * This example connects to a Jabber server, logs in, fetches (and displays)
- * the roster, and then waits until a message is received from another contact.
- *
- * It then starts a countdown which, in sequence:
- * 
- * 1) sends a "composing" event to the other contact (eg: "so-and-so is typing a message"),
- * 2) sends a "composing stopped" event,
- * 3) sends another "composing" event",
- * 4) sends a message to the other contact,
- * 5) logs out
- *
- */
-// set your Jabber server hostname, username, and password here
-define("JABBER_SERVER","jabber.blitzaffe.com");
-define("JABBER_USERNAME","helium");
-define("JABBER_PASSWORD","zv4.5k1p8");
-
-define("RUN_TIME",30); // set a maximum run time of 30 seconds
-define("CBK_FREQ",1);  // fire a callback event every second
-
-
-// This class handles all events fired by the Jabber client class; you
-// can optionally use individual functions instead of a class, but this
-// method is a bit cleaner.
-class TestMessenger {
-       
-       function TestMessenger(&$jab) {
-               $this->jab = &$jab;
-               $this->first_roster_update = true;
-               
-               echo "Created!\n";
-               $this->countdown = 0;
-       }
-       
-       // called when a connection to the Jabber server is established
-       function handleConnected() {
-               echo "Connected!\n";
-               
-               // now that we're connected, tell the Jabber class to login
-               echo "Authenticating ...\n";
-               $this->jab->login(JABBER_USERNAME,JABBER_PASSWORD);
-       }
-       
-       // called after a login to indicate the the login was successful
-       function handleAuthenticated() {
-               echo "Authenticated!\n";
-               
-               
-               echo "Fetching service list and roster ...\n";
-               
-               // browser for transport gateways
-               $this->jab->browse();
-               
-               // retrieve this user's roster
-               $this->jab->get_roster();
-               
-               // set this user's presence
-               $this->jab->set_presence("","Ya, I'm online... so what?");
-       }
-       
-       // called after a login to indicate that the login was NOT successful
-       function handleAuthFailure($code,$error) {
-               echo "Authentication failure: $error ($code)\n";
-               
-               // set terminated to TRUE in the Jabber class to tell it to exit
-               $this->jab->terminated = true;
-       }
-       
-       // called periodically by the Jabber class to allow us to do our own
-       // processing
-       function handleHeartbeat() {
-               echo "Heartbeat - ";
-               
-               // if the countdown is in progress, determine if we need to take any action
-               if ($this->countdown>0) {
-                       $this->countdown--;
-
-                       // display our countdown progress
-                       echo "Countdown: {$this->countdown}\n";
-
-                       
-                       // first, we want to fire our composing event
-                       if ($this->countdown==7) {
-                               echo "Composing start\n";
-                               $this->jab->composing($this->last_msg_from,$this->last_msg_id);
-                       }
-                       
-                       // next, we want to indicate that we've stopped composing a message
-                       if ($this->countdown==5) {
-                               echo "Composing stop\n";
-                               $this->jab->composing($this->last_msg_from,$this->last_msg_id,false);
-                       }
-                       
-                       // next, we indicate that we're composing again
-                       if ($this->countdown==3) {
-                               echo "Composing start\n";
-                               $this->jab->composing($this->last_msg_from,$this->last_msg_id);
-                       }
-                       
-                       // and finally, we send a message to the remote user and tell the Jabber class
-                       // to exit
-                       if ($this->countdown==1) {
-                               echo "Send message\n";
-                               $this->jab->message($this->last_msg_from,"chat",NULL,"Hello! You said: ".$this->last_message);
-                               $this->jab->terminated = true;
-                       }
-               } else {
-                       echo "Waiting for incoming message ...\n";
-               }
-               /*
-               reset($this->jab->roster);
-               foreach ($this->jab->roster as $jid=>$details) {
-                       echo "$jid\t\t\t".$details["transport"]."\t".$details["show"]."\t".$details["status"]."\n";
-               }
-               */
-       }
-       
-       // called when an error is received from the Jabber server
-       function handleError($code,$error,$xmlns) {
-               echo "Error: $error ($code)".($xmlns?" in $xmlns":"")."\n";
-       }
-       
-       // called when a message is received from a remote contact
-       function handleMessage($from,$to,$body,$subject,$thread,$id,$extended) {
-               echo "Incoming message!\n";
-               echo "From: $from\t\tTo: $to\n";
-               echo "Subject: $subject\tThread; $thread\n";
-               echo "Body: $body\n";
-               echo "ID: $id\n";
-               var_dump($extended);
-               echo "\n";
-               
-               $this->last_message = $body;
-               
-               $this->last_msg_id = $id;
-               $this->last_msg_from = $from;
-               
-               // for the purposes of our example, we start a countdown here to do some
-               // random events, just for the sake of demonstration
-               echo "Starting countdown\n";
-               $this->countdown = 10;
-       }
-       
-       function _contact_info($contact) {
-               return sprintf("Contact %s (JID %s) has status %s and message %s\n",$contact['name'],$contact['jid'],$contact['show'],$contact['status']);
-       }
-       
-       function handleRosterUpdate($jid) {
-               if ($this->first_roster_update) {
-                       // the first roster update indicates that the entire roster has been
-                       // downloaded for the first time
-                       echo "Roster downloaded:\n";
-                       
-                       foreach ($this->jab->roster as $k=>$contact) {
-                               echo $this->_contact_info($contact);
-                       }       
-                       $this->first_roster_update = false;
-               } else {
-                       // subsequent roster updates indicate changes for individual roster items
-                       $contact = $this->jab->roster[$jid];
-                       echo "Contact updated: " . $this->_contact_info($contact);
-               }
-       }
-       
-       function handleDebug($msg,$level) {
-               echo "DBG: $msg\n";
-       }
-       
-}
-
-// include the Jabber class
-require_once("class_Jabber.php");
-
-// create an instance of the Jabber class
-$display_debug_info = false;
-$jab = new Jabber($display_debug_info);
-
-// create an instance of our event handler class
-$test = new TestMessenger($jab);
-
-// set handlers for the events we wish to be notified about
-$jab->set_handler("connected",$test,"handleConnected");
-$jab->set_handler("authenticated",$test,"handleAuthenticated");
-$jab->set_handler("authfailure",$test,"handleAuthFailure");
-$jab->set_handler("heartbeat",$test,"handleHeartbeat");
-$jab->set_handler("error",$test,"handleError");
-$jab->set_handler("message_normal",$test,"handleMessage");
-$jab->set_handler("message_chat",$test,"handleMessage");
-$jab->set_handler("debug_log",$test,"handleDebug");
-$jab->set_handler("rosterupdate",$test,"handleRosterUpdate");
-
-echo "Connecting ...\n";
-
-// connect to the Jabber server
-if (!$jab->connect(JABBER_SERVER)) {
-       die("Could not connect to the Jabber server!\n");
-}
-
-// now, tell the Jabber class to begin its execution loop
-$jab->execute(CBK_FREQ,RUN_TIME);
-
-// Note that we will not reach this point (and the execute() method will not
-// return) until $jab->terminated is set to TRUE.  The execute() method simply
-// loops, processing data from (and to) the Jabber server, and firing events
-// (which are handled by our TestMessenger class) until we tell it to terminate.
-//
-// This event-based model will be familiar to programmers who have worked on
-// desktop applications, particularly in Win32 environments.
-
-// disconnect from the Jabber server
-$jab->disconnect();
-?>
\ No newline at end of file
index 1ed8d6c..167e4a2 100644 (file)
@@ -40,39 +40,7 @@ define("JABBER_PASSWORD","");
 define("RUN_TIME",15);  // set a maximum run time of 15 seconds
 
 require_once($CFG->dirroot.'/message/output/lib.php');
-require_once($CFG->dirroot.'/message/output/jabber/jabberclass/class_Jabber.php');
-
-class JabberMessenger {
-    function JabberMessenger(&$jab, $message) {
-        $this->jab = &$jab;
-        $this->message = $message;
-        $this->first_roster_update = true;
-        $this->countdown = 0;
-    }
-    // called when a connection to the Jabber server is established
-    function handleConnected() {        
-        $this->jab->login(JABBER_USERNAME,JABBER_PASSWORD);
-    }
-    // called after a login to indicate the the login was successful
-    function handleAuthenticated() {
-        global $DB;        
-        $userfrom = $DB->get_record('user', array('id' => $this->message->useridfrom));
-        $userto = $DB->get_record('user', array('id' => $this->message->useridto));            
-        
-        $jabberdest = get_user_preferences('message_processor_jabber_jabberid', $userto->email , $userto->id);
-        if (empty($jabberdest)){
-            $jabberdest = $userto->email;
-        }
-        $this->jab->message($jabberdest,"chat",NULL,fullname($userfrom)." says: ".$this->message->fullmessage);
-        $this->jab->terminated = true;
-    }
-    // called after a login to indicate that the login was NOT successful
-    function handleAuthFailure($code,$error) {
-        // set terminated to TRUE in the Jabber class to tell it to exit
-        $this->jab->terminated = true;
-    }
-}
-
+require_once($CFG->libdir.'/jabber/XMPP/XMPP.php');
 
 class message_output_jabber extends message_output {
     
@@ -82,26 +50,31 @@ class message_output_jabber extends message_output {
      * @return true if ok, false if error
      */
     function send_message($message){
+        global $DB;
         
-        //jabber object
-        $jab = new Jabber(True);
-        // create an instance of our event handler class
-        $test = new JabberMessenger($jab, $message);
-        
-        // set handlers for the events we wish to be notified about
-        $jab->set_handler("connected",$test,"handleConnected");
-        $jab->set_handler("authenticated",$test,"handleAuthenticated");
-        $jab->set_handler("authfailure",$test,"handleAuthFailure");
-        
-        if (!$jab->connect(JABBER_SERVER)) {
+        if (!$userfrom = $DB->get_record('user', array('id' => $message->useridfrom))) {
+            return false;
+        }
+        if (!$userto = $DB->get_record('user', array('id' => $this->message->useridto))) {
             return false;
         }
+        if (!$jabberaddress = get_user_preferences('message_processor_jabber_jabberid', $userto->email, $userto->id)) {
+            $jabberaddress = $userto->email;
+        }
+        $jabbermessage = fullname($userfrom).': '.$message->fullmessage;
 
-        // now, tell the Jabber class to begin its execution loop
-        // don't way for events
-        $jab->execute(-1,RUN_TIME);
-        $jab->disconnect();
+        $conection = new XMPPHP_XMPP(JABBER_SERVER, 5222, JABBER_USERNAME, JABBER_PASSWORD, 'moodle', JABBER_SERVER);
 
+        try {
+            $conn->connect();
+            $conn->processUntil('session_start');
+            $conn->presence();
+            $conn->message($jabberaddress, $jabbermessage);
+            $conn->disconnect();
+        } catch(XMPPHP_Exception $e) {
+            return false;
+        }
+        
         return true;
     }
 
index 54b060e..9abc461 100755 (executable)
@@ -32,7 +32,7 @@
  * @package
  */
 
-$plugin->version  = 2008072401;
-$plugin->requires = 2008072401;
+$plugin->version  = 2008090900;
+$plugin->requires = 2008091500;
 
 ?>
index aa9ad54..e1f31d8 100644 (file)
@@ -6,7 +6,7 @@
 // This is compared against the values stored in the database to determine
 // whether upgrades should be performed (see lib/db/*.php)
 
-    $version = 2008091000;  // YYYYMMDD   = date of the last version bump
+    $version = 2008091500;  // YYYYMMDD   = date of the last version bump
                             //         XX = daily increments
 
     $release = '2.0 dev (Build: 20080915)';  // Human-friendly version name