source: trunk/jabberit_messenger/inc/class.jabber.inc.php @ 382

Revision 382, 40.6 KB checked in by niltonneto, 16 years ago (diff)

Inclusão do módulo JabberIt? Messenger, novo módulo de mensagens
instantâneas do Expresso. É uma customização do projeto original
Jeti, e foi desenvolvido em Java.

  • Property svn:executable set to *
Line 
1<?php
2
3        /***************************************************************************
4                Class.Jabber.PHP v0.4.2
5                (c) 2004 Nathan "Fritzy" Fritz
6                http://cjphp.netflint.net *** fritzy@netflint.net
7         ***************************************************************************/
8
9class Jabber
10{
11        var $server;
12        var $port;
13        var $username;
14        var $password;
15        var $resource;
16        var $jid;
17
18        var $connection;
19        var $delay_disconnect;
20
21        var $stream_id;
22        var $roster;
23
24        var $enable_logging;
25        var $log_array;
26        var $log_filename;
27        var $log_filehandler;
28
29        var $iq_sleep_timer;
30        var $last_ping_time;
31
32        var $packet_queue;
33        var $subscription_queue;
34
35        var $iq_version_name;
36        var $iq_version_os;
37        var $iq_version_version;
38
39        var $error_codes;
40
41        var $connected;
42        var $keep_alive_id;
43        var $returned_keep_alive;
44        var $txnid;
45
46        var $CONNECTOR;
47
48
49
50        function Jabber()
51        {
52                $this->port                                     = "5222";
53
54                $this->enable_logging           = FALSE;
55                $this->log_array                        = array();
56                $this->log_filename                     = '';
57                $this->log_filehandler          = FALSE;
58
59                $this->packet_queue                     = array();
60                $this->subscription_queue       = array();
61
62                $this->iq_sleep_timer           = 1;
63                $this->delay_disconnect         = 1;
64
65                $this->returned_keep_alive      = TRUE;
66                $this->txnid                            = 0;
67
68                $this->iq_version_name          = "Class.Jabber.PHP -- http://cjphp.netflint.net -- by Nathan 'Fritzy' Fritz, fritz@netflint.net";
69                $this->iq_version_version       = "0.4";
70                $this->iq_version_os            = $_SERVER['SERVER_SOFTWARE'];
71
72                $this->connection_class         = "CJP_StandardConnector";
73
74                $this->error_codes                      = array(400 => "Bad Request",
75                                                                                        401 => "Unauthorized",
76                                                                                        402 => "Payment Required",
77                                                                                        403 => "Forbidden",
78                                                                                        404 => "Not Found",
79                                                                                        405 => "Not Allowed",
80                                                                                        406 => "Not Acceptable",
81                                                                                        407 => "Registration Required",
82                                                                                        408 => "Request Timeout",
83                                                                                        409 => "Conflict",
84                                                                                        500 => "Internal Server Error",
85                                                                                        501 => "Not Implemented",
86                                                                                        502 => "Remove Server Error",
87                                                                                        503 => "Service Unavailable",
88                                                                                        504 => "Remove Server Timeout",
89                                                                                        510 => "Disconnected");
90        }
91
92
93
94        function Connect()
95        {
96                $this->_create_logfile();
97
98                $this->CONNECTOR = new $this->connection_class;
99
100                if ($this->CONNECTOR->OpenSocket($this->server, $this->port))
101                {
102                        $this->SendPacket("<?xml version='1.0' encoding='UTF-8' ?" . ">\n");
103                        $this->SendPacket("<stream:stream to='{$this->server}' xmlns='jabber:client' xmlns:stream='http://etherx.jabber.org/streams' version='1.0'>\n");
104
105                        sleep(2);
106
107                        if ($this->_check_connected())
108                        {
109                                $this->connected = TRUE;        // Nathan Fritz
110                                return TRUE;
111                        }
112                        else
113                        {
114                                $this->AddToLog("ERROR: Connect() #1");
115                                return FALSE;
116                        }
117                }
118                else
119                {
120                        $this->AddToLog("ERROR: Connect() #2");
121                        return FALSE;
122                }
123        }
124
125
126
127        function Disconnect()
128        {
129                if (is_int($this->delay_disconnect))
130                {
131                        sleep($this->delay_disconnect);
132                }
133
134                $this->SendPacket("</stream:stream>");
135                $this->CONNECTOR->CloseSocket();
136
137                $this->_close_logfile();
138                $this->PrintLog();
139        }
140
141
142
143        function SendAuth()
144        {
145                $this->auth_id  = "auth_" . md5(time() . $_SERVER['REMOTE_ADDR']);
146
147                $this->resource = ($this->resource != NULL) ? $this->resource : ("Class.Jabber.PHP " . md5($this->auth_id));
148                $this->jid              = "{$this->username}@{$this->server}/{$this->resource}";
149
150                // request available authentication methods
151                $payload        = "<username>{$this->username}</username>";
152                $packet         = $this->SendIq(NULL, 'get', $this->auth_id, "jabber:iq:auth", $payload);
153
154                // was a result returned?
155                if ($this->GetInfoFromIqType($packet) == 'result' && $this->GetInfoFromIqId($packet) == $this->auth_id)
156                {
157                        // yes, now check for auth method availability in descending order (best to worst)
158
159                        if (!function_exists("mhash"))
160                        {
161                                $this->AddToLog("ATTENTION: SendAuth() - mhash() is not available; screw 0k and digest method, we need to go with plaintext auth");
162                        }
163
164                        // auth_0k
165                        if (function_exists("mhash") && isset($packet['iq']['#']['query'][0]['#']['sequence'][0]["#"]) && isset($packet['iq']['#']['query'][0]['#']['token'][0]["#"]))
166                        {
167                                return $this->_sendauth_0k($packet['iq']['#']['query'][0]['#']['token'][0]["#"], $packet['iq']['#']['query'][0]['#']['sequence'][0]["#"]);
168                        }
169                        // digest
170                        elseif (function_exists("mhash") && isset($packet['iq']['#']['query'][0]['#']['digest']))
171                        {
172                                return $this->_sendauth_digest();
173                        }
174                        // plain text
175                        elseif ($packet['iq']['#']['query'][0]['#']['password'])
176                        {
177                                return $this->_sendauth_plaintext();
178                        }
179                        // dude, you're fucked
180                        {
181                                $this->AddToLog("ERROR: SendAuth() #2 - No auth method available!");
182                                return FALSE;
183                        }
184                }
185                else
186                {
187                        // no result returned
188                        $this->AddToLog("ERROR: SendAuth() #1");
189                        return FALSE;
190                }
191        }
192
193
194
195        function AccountRegistration($reg_email = NULL, $reg_name = NULL)
196        {
197                $packet = $this->SendIq($this->server, 'get', 'reg_01', 'jabber:iq:register');
198
199                if ($packet)
200                {
201                        $key = $this->GetInfoFromIqKey($packet);        // just in case a key was passed back from the server
202                        unset($packet);
203
204                        $payload = "<username>{$this->username}</username>
205                                                <password>{$this->password}</password>
206                                                <email>$reg_email</email>
207                                                <name>$reg_name</name>\n";
208
209                        $payload .= ($key) ? "<key>$key</key>\n" : '';
210
211                        $packet = $this->SendIq($this->server, 'set', "reg_01", "jabber:iq:register", $payload);
212
213                        if ($this->GetInfoFromIqType($packet) == 'result')
214                        {
215                                if (isset($packet['iq']['#']['query'][0]['#']['registered'][0]['#']))
216                                {
217                                        $return_code = 1;
218                                }
219                                else
220                                {
221                                        $return_code = 2;
222                                }
223
224                                if ($this->resource)
225                                {
226                                        $this->jid = "{$this->username}@{$this->server}/{$this->resource}";
227                                }
228                                else
229                                {
230                                        $this->jid = "{$this->username}@{$this->server}";
231                                }
232
233                        }
234                        elseif ($this->GetInfoFromIqType($packet) == 'error' && isset($packet['iq']['#']['error'][0]['#']))
235                        {
236                                // "conflict" error, i.e. already registered
237                                if ($packet['iq']['#']['error'][0]['@']['code'] == '409')
238                                {
239                                        $return_code = 1;
240                                }
241                                else
242                                {
243                                        $return_code = "Error " . $packet['iq']['#']['error'][0]['@']['code'] . ": " . $packet['iq']['#']['error'][0]['#'];
244                                }
245                        }
246
247                        return $return_code;
248
249                }
250                else
251                {
252                        return 3;
253                }
254        }
255
256
257
258        function SendPacket($xml)
259        {
260                $xml = trim($xml);
261
262                if ($this->CONNECTOR->WriteToSocket($xml))
263                {
264                        $this->AddToLog("SEND: $xml");
265                        return TRUE;
266                }
267                else
268                {
269                        $this->AddToLog('ERROR: SendPacket() #1');
270                        return FALSE;
271                }
272        }
273
274
275
276        function Listen()
277        {
278                unset($incoming);
279
280                while ($line = $this->CONNECTOR->ReadFromSocket(4096))
281                {
282                        $incoming .= $line;
283                }
284
285                $incoming = trim($incoming);
286
287                if ($incoming != "")
288                {
289                        $this->AddToLog("RECV: $incoming");
290                }
291
292                if ($incoming != "")
293                {
294                        $temp = $this->_split_incoming($incoming);
295
296                        for ($a = 0; $a < count($temp); $a++)
297                        {
298                                $this->packet_queue[] = $this->xmlize($temp[$a]);
299                        }
300                }
301
302                return TRUE;
303        }
304
305
306
307        function StripJID($jid = NULL)
308        {
309                preg_match("/(.*)\/(.*)/Ui", $jid, $temp);
310                return ($temp[1] != "") ? $temp[1] : $jid;
311        }
312
313
314
315        function SendMessage($to, $type = "normal", $id = NULL, $content = NULL, $payload = NULL)
316        {
317                if ($to && is_array($content))
318                {
319                        if (!$id)
320                        {
321                                $id = $type . "_" . time();
322                        }
323
324                        $content = $this->_array_htmlspecialchars($content);
325
326                        $xml = "<message to='$to' type='$type' id='$id'>\n";
327
328                        if ($content['subject'])
329                        {
330                                $xml .= "<subject>" . $content['subject'] . "</subject>\n";
331                        }
332
333                        if ($content['thread'])
334                        {
335                                $xml .= "<thread>" . $content['thread'] . "</thread>\n";
336                        }
337
338                        $xml .= "<body>" . $content['body'] . "</body>\n";
339                        $xml .= $payload;
340                        $xml .= "</message>\n";
341
342
343                        if ($this->SendPacket($xml))
344                        {
345                                return TRUE;
346                        }
347                        else
348                        {
349                                $this->AddToLog("ERROR: SendMessage() #1");
350                                return FALSE;
351                        }
352                }
353                else
354                {
355                        $this->AddToLog("ERROR: SendMessage() #2");
356                        return FALSE;
357                }
358        }
359
360
361
362        function SendPresence($type = NULL, $to = NULL, $status = NULL, $show = NULL, $priority = NULL)
363        {
364                $xml = "<presence";
365                $xml .= ($to) ? " to='$to'" : '';
366                $xml .= ($type) ? " type='$type'" : '';
367                $xml .= ($status || $show || $priority) ? ">\n" : " />\n";
368
369                $xml .= ($status) ? "   <status>$status</status>\n" : '';
370                $xml .= ($show) ? "     <show>$show</show>\n" : '';
371                $xml .= ($priority) ? " <priority>$priority</priority>\n" : '';
372
373                $xml .= ($status || $show || $priority) ? "</presence>\n" : '';
374
375                if ($this->SendPacket($xml))
376                {
377                        return TRUE;
378                }
379                else
380                {
381                        $this->AddToLog("ERROR: SendPresence() #1");
382                        return FALSE;
383                }
384        }
385
386
387
388        function SendError($to, $id = NULL, $error_number, $error_message = NULL)
389        {
390                $xml = "<iq type='error' to='$to'";
391                $xml .= ($id) ? " id='$id'" : '';
392                $xml .= ">\n";
393                $xml .= "       <error code='$error_number'>";
394                $xml .= ($error_message) ? $error_message : $this->error_codes[$error_number];
395                $xml .= "</error>\n";
396                $xml .= "</iq>";
397
398                $this->SendPacket($xml);
399        }
400
401
402
403        function RosterUpdate()
404        {
405                $roster_request_id = "roster_" . time();
406
407                $incoming_array = $this->SendIq(NULL, 'get', $roster_request_id, "jabber:iq:roster");
408
409                if (is_array($incoming_array))
410                {
411                        if ($incoming_array['iq']['@']['type'] == 'result'
412                                && $incoming_array['iq']['@']['id'] == $roster_request_id
413                                && $incoming_array['iq']['#']['query']['0']['@']['xmlns'] == "jabber:iq:roster")
414                        {
415                                $number_of_contacts = count($incoming_array['iq']['#']['query'][0]['#']['item']);
416                                $this->roster = array();
417
418                                for ($a = 0; $a < $number_of_contacts; $a++)
419                                {
420                                        $this->roster[$a] = array(      "jid"                   => strtolower($incoming_array['iq']['#']['query'][0]['#']['item'][$a]['@']['jid']),
421                                                                                                "name"                  => $incoming_array['iq']['#']['query'][0]['#']['item'][$a]['@']['name'],
422                                                                                                "subscription"  => $incoming_array['iq']['#']['query'][0]['#']['item'][$a]['@']['subscription'],
423                                                                                                "group"                 => $incoming_array['iq']['#']['query'][0]['#']['item'][$a]['#']['group'][0]['#']
424                                                                                        );
425                                }
426
427                                return TRUE;
428                        }
429                        else
430                        {
431                                $this->AddToLog("ERROR: RosterUpdate() #1");
432                                return FALSE;
433                        }
434                }
435                else
436                {
437                        $this->AddToLog("ERROR: RosterUpdate() #2");
438                        return FALSE;
439                }
440        }
441
442    // Mod by ALC;
443        function RosterAddUser($jid = NULL, $id = NULL, $name = NULL, $group = NULL)
444        {
445                $id = ($id) ? $id : "adduser_" . time();
446
447                if ($jid)
448                {
449                        $payload = "<item jid='$jid'";
450                        $payload .= ($name) ? " name='" . htmlspecialchars($name) . "'" : '';
451                        $payload .= (($group) ? "><group>". htmlspecialchars($group). "</group></item>": "/") . ">";
452                       
453                        $packet = $this->SendIq(NULL, 'set', $id, "jabber:iq:roster", $payload);
454
455                        if ($this->GetInfoFromIqType($packet) == 'result')
456                        {
457                                $this->RosterUpdate();
458                                return TRUE;
459                        }
460                        else
461                        {
462                                $this->AddToLog("ERROR: RosterAddUser() #2");
463                                return FALSE;
464                        }
465                }
466                else
467                {
468                        $this->AddToLog("ERROR: RosterAddUser() #1");
469                        return FALSE;
470                }
471        }
472
473        function RosterRemoveUser($jid = NULL, $id = NULL)
474        {
475                $id = ($id) ? $id : 'deluser_' . time();
476
477                if ($jid && $id)
478                {
479                        $packet = $this->SendIq(NULL, 'set', $id, "jabber:iq:roster", "<item jid='$jid' subscription='remove'/>");
480
481                        if ($this->GetInfoFromIqType($packet) == 'result')
482                        {
483                                $this->RosterUpdate();
484                                return TRUE;
485                        }
486                        else
487                        {
488                                $this->AddToLog("ERROR: RosterRemoveUser() #2");
489                                return FALSE;
490                        }
491                }
492                else
493                {
494                        $this->AddToLog("ERROR: RosterRemoveUser() #1");
495                        return FALSE;
496                }
497        }
498
499
500
501        function RosterExistsJID($jid = NULL)
502        {
503                if ($jid)
504                {
505                        if ($this->roster)
506                        {
507                                for ($a = 0; $a < count($this->roster); $a++)
508                                {
509                                        if ($this->roster[$a]['jid'] == strtolower($jid))
510                                        {
511                                                return $a;
512                                        }
513                                }
514                        }
515                        else
516                        {
517                                $this->AddToLog("ERROR: RosterExistsJID() #2");
518                                return FALSE;
519                        }
520                }
521                else
522                {
523                        $this->AddToLog("ERROR: RosterExistsJID() #1");
524                        return FALSE;
525                }
526        }
527
528
529
530        function GetFirstFromQueue()
531        {
532                return array_shift($this->packet_queue);
533        }
534
535
536
537        function GetFromQueueById($packet_type, $id)
538        {
539                $found_message = FALSE;
540
541                foreach ($this->packet_queue as $key => $value)
542                {
543                        if ($value[$packet_type]['@']['id'] == $id)
544                        {
545                                $found_message = $value;
546                                unset($this->packet_queue[$key]);
547
548                                break;
549                        }
550                }
551
552                return (is_array($found_message)) ? $found_message : FALSE;
553        }
554
555
556
557        function CallHandler($packet = NULL)
558        {
559                $packet_type    = $this->_get_packet_type($packet);
560
561                if ($packet_type == "message")
562                {
563                        $type           = $packet['message']['@']['type'];
564                        $type           = ($type != "") ? $type : "normal";
565                        $funcmeth       = "Handler_message_$type";
566                }
567                elseif ($packet_type == "iq")
568                {
569                        $namespace      = $packet['iq']['#']['query'][0]['@']['xmlns'];
570                        $namespace      = str_replace(":", "_", $namespace);
571                        $funcmeth       = "Handler_iq_$namespace";
572                }
573                elseif ($packet_type == "presence")
574                {
575                        $type           = $packet['presence']['@']['type'];
576                        $type           = ($type != "") ? $type : "available";
577                        $funcmeth       = "Handler_presence_$type";
578                }
579
580
581                if ($funcmeth != '')
582                {
583                        if (function_exists($funcmeth))
584                        {
585                                call_user_func($funcmeth, $packet);
586                        }
587                        elseif (method_exists($this, $funcmeth))
588                        {
589                                call_user_func(array(&$this, $funcmeth), $packet);
590                        }
591                        else
592                        {
593                                $this->Handler_NOT_IMPLEMENTED($packet);
594                                $this->AddToLog("ERROR: CallHandler() #1 - neither method nor function $funcmeth() available");
595                        }
596                }
597        }
598
599
600
601        function CruiseControl($seconds = -1)
602        {
603                $count = 0;
604
605                while ($count != $seconds)
606                {
607                        $this->Listen();
608
609                        do {
610                                $packet = $this->GetFirstFromQueue();
611
612                                if ($packet) {
613                                        $this->CallHandler($packet);
614                                }
615
616                        } while (count($this->packet_queue) > 1);
617
618                        $count += 0.25;
619                        usleep(250000);
620                       
621                        if ($this->last_ping_time + 180 < time())
622                        {
623                                // Modified by Nathan Fritz
624                                if ($this->returned_keep_alive == FALSE)
625                                {
626                                        $this->connected = FALSE;
627                                        $this->AddToLog('EVENT: Disconnected');
628                                }
629                                if ($this->returned_keep_alive == TRUE)
630                                {
631                                        $this->connected = TRUE;
632                                }
633
634                                $this->returned_keep_alive = FALSE;
635                                $this->keep_alive_id = 'keep_alive_' . time();
636                                //$this->SendPacket("<iq id='{$this->keep_alive_id}'/>", 'CruiseControl');
637                                $this->SendPacket("<iq type='get' from='" . $this->username . "@" . $this->server . "/" . $this->resource . "' to='" . $this->server . "' id='" . $this->keep_alive_id . "'><query xmlns='jabber:iq:time' /></iq>");
638                                // **
639
640                                $this->last_ping_time = time();
641                        }
642                }
643
644                return TRUE;
645        }
646
647
648
649        function SubscriptionAcceptRequest($to = NULL)
650        {
651                return ($to) ? $this->SendPresence("subscribed", $to) : FALSE;
652        }
653
654
655
656        function SubscriptionDenyRequest($to = NULL)
657        {
658                return ($to) ? $this->SendPresence("unsubscribed", $to) : FALSE;
659        }
660
661
662
663        function Subscribe($to = NULL)
664        {
665                return ($to) ? $this->SendPresence("subscribe", $to) : FALSE;
666        }
667
668
669
670        function Unsubscribe($to = NULL)
671        {
672                return ($to) ? $this->SendPresence("unsubscribe", $to) : FALSE;
673        }
674
675
676
677        function SendIq($to = NULL, $type = 'get', $id = NULL, $xmlns = NULL, $payload = NULL, $from = NULL)
678        {
679                if (!preg_match("/^(get|set|result|error)$/", $type))
680                {
681                        unset($type);
682
683                        $this->AddToLog("ERROR: SendIq() #2 - type must be 'get', 'set', 'result' or 'error'");
684                        return FALSE;
685                }
686                elseif ($id && $xmlns)
687                {
688                        $xml = "<iq type='$type' id='$id'";
689                        $xml .= ($to) ? " to='" . htmlspecialchars($to) . "'" : '';
690                        $xml .= ($from) ? " from='$from'" : '';
691                        $xml .= ">
692                                                <query xmlns='$xmlns'>
693                                                        $payload
694                                                </query>
695                                        </iq>";
696
697                        $this->SendPacket($xml);
698                        sleep($this->iq_sleep_timer);
699                        $this->Listen();
700
701                        return (preg_match("/^(get|set)$/", $type)) ? $this->GetFromQueueById("iq", $id) : TRUE;
702                }
703                else
704                {
705                        $this->AddToLog("ERROR: SendIq() #1 - to, id and xmlns are mandatory");
706                        return FALSE;
707                }
708        }
709
710
711
712        // get the transport registration fields
713        // method written by Steve Blinch, http://www.blitzaffe.com
714        function TransportRegistrationDetails($transport)
715        {
716                $this->txnid++;
717                $packet = $this->SendIq($transport, 'get', "reg_{$this->txnid}", "jabber:iq:register", NULL, $this->jid);
718
719                if ($packet)
720                {
721                        $res = array();
722
723                        foreach ($packet['iq']['#']['query'][0]['#'] as $element => $data)
724                        {
725                                if ($element != 'instructions' && $element != 'key')
726                                {
727                                        $res[] = $element;
728                                }
729                        }
730
731                        return $res;
732                }
733                else
734                {
735                        return 3;
736                }
737        }
738       
739
740
741        // register with the transport
742        // method written by Steve Blinch, http://www.blitzaffe.com
743        function TransportRegistration($transport, $details)
744        {
745                $this->txnid++;
746                $packet = $this->SendIq($transport, 'get', "reg_{$this->txnid}", "jabber:iq:register", NULL, $this->jid);
747
748                if ($packet)
749                {
750                        $key = $this->GetInfoFromIqKey($packet);        // just in case a key was passed back from the server
751                        unset($packet);
752               
753                        $payload = ($key) ? "<key>$key</key>\n" : '';
754                        foreach ($details as $element => $value)
755                        {
756                                $payload .= "<$element>$value</$element>\n";
757                        }
758               
759                        $packet = $this->SendIq($transport, 'set', "reg_{$this->txnid}", "jabber:iq:register", $payload);
760               
761                        if ($this->GetInfoFromIqType($packet) == 'result')
762                        {
763                                if (isset($packet['iq']['#']['query'][0]['#']['registered'][0]['#']))
764                                {
765                                        $return_code = 1;
766                                }
767                                else
768                                {
769                                        $return_code = 2;
770                                }
771                        }
772                        elseif ($this->GetInfoFromIqType($packet) == 'error')
773                        {
774                                if (isset($packet['iq']['#']['error'][0]['#']))
775                                {
776                                        $return_code = "Error " . $packet['iq']['#']['error'][0]['@']['code'] . ": " . $packet['iq']['#']['error'][0]['#'];
777                                        $this->AddToLog('ERROR: TransportRegistration()');
778                                }
779                        }
780
781                        return $return_code;
782                }
783                else
784                {
785                        return 3;
786                }
787        }
788
789
790
791        function GetvCard($jid = NULL, $id = NULL)
792        {
793                if (!$id)
794                {
795                        $id = "vCard_" . md5(time() . $_SERVER['REMOTE_ADDR']);
796                }
797
798                if ($jid)
799                {
800                        $xml = "<iq type='get' to='$jid' id='$id'>
801                                                <vCard xmlns='vcard-temp'/>
802                                        </iq>";
803
804                        $this->SendPacket($xml);
805                        sleep($this->iq_sleep_timer);
806                        $this->Listen();
807
808                        return $this->GetFromQueueById("iq", $id);
809                }
810                else
811                {
812                        $this->AddToLog("ERROR: GetvCard() #1 - to and id are mandatory");
813                        return FALSE;
814                }
815        }
816
817
818
819        function PrintLog()
820        {
821                if ($this->enable_logging)
822                {
823                        if ($this->log_filehandler)
824                        {
825                                echo "<h2>Logging enabled, logged events have been written to the file {$this->log_filename}.</h2>\n";
826                        }
827                        else
828                        {
829                                echo "<h2>Logging enabled, logged events below:</h2>\n";
830                                echo "<pre>\n";
831                                echo (count($this->log_array) > 0) ? implode("\n\n\n", $this->log_array) : "No logged events.";
832                                echo "</pre>\n";
833                        }
834                }
835        }
836
837
838
839        // ======================================================================
840        // private methods
841        // ======================================================================
842
843
844
845        function _sendauth_0k($zerok_token, $zerok_sequence)
846        {
847                // initial hash of password
848                $zerok_hash = mhash(MHASH_SHA1, $this->password);
849                $zerok_hash = bin2hex($zerok_hash);
850
851                // sequence 0: hash of hashed-password and token
852                $zerok_hash = mhash(MHASH_SHA1, $zerok_hash . $zerok_token);
853                $zerok_hash = bin2hex($zerok_hash);
854
855                // repeat as often as needed
856                for ($a = 0; $a < $zerok_sequence; $a++)
857                {
858                        $zerok_hash = mhash(MHASH_SHA1, $zerok_hash);
859                        $zerok_hash = bin2hex($zerok_hash);
860                }
861
862                $payload = "<username>{$this->username}</username>
863                                        <hash>$zerok_hash</hash>
864                                        <resource>{$this->resource}</resource>";
865
866                $packet = $this->SendIq(NULL, 'set', $this->auth_id, "jabber:iq:auth", $payload);
867
868                // was a result returned?
869                if ($this->GetInfoFromIqType($packet) == 'result' && $this->GetInfoFromIqId($packet) == $this->auth_id)
870                {
871                        return TRUE;
872                }
873                else
874                {
875                        $this->AddToLog("ERROR: _sendauth_0k() #1");
876                        return FALSE;
877                }
878        }
879
880
881
882        function _sendauth_digest()
883        {
884                $payload = "<username>{$this->username}</username>
885                                        <resource>{$this->resource}</resource>
886                                        <digest>" . bin2hex(mhash(MHASH_SHA1, $this->stream_id . $this->password)) . "</digest>";
887
888                $packet = $this->SendIq(NULL, 'set', $this->auth_id, "jabber:iq:auth", $payload);
889
890                // was a result returned?
891                if ($this->GetInfoFromIqType($packet) == 'result' && $this->GetInfoFromIqId($packet) == $this->auth_id)
892                {
893                        return TRUE;
894                }
895                else
896                {
897                        $this->AddToLog("ERROR: _sendauth_digest() #1");
898                        return FALSE;
899                }
900        }
901
902
903
904        function _sendauth_plaintext()
905        {
906                $payload = "<username>{$this->username}</username>
907                                        <password>{$this->password}</password>
908                                        <resource>{$this->resource}</resource>";
909
910                $packet = $this->SendIq(NULL, 'set', $this->auth_id, "jabber:iq:auth", $payload);
911
912                // was a result returned?
913                if ($this->GetInfoFromIqType($packet) == 'result' && $this->GetInfoFromIqId($packet) == $this->auth_id)
914                {
915                        return TRUE;
916                }
917                else
918                {
919                        $this->AddToLog("ERROR: _sendauth_plaintext() #1");
920                        return FALSE;
921                }
922        }
923
924
925
926        function _listen_incoming()
927        {
928                unset($incoming);
929
930                while ($line = $this->CONNECTOR->ReadFromSocket(4096))
931                {
932                        $incoming .= $line;
933                }
934
935                $incoming = trim($incoming);
936
937                if ($incoming != "")
938                {
939                        $this->AddToLog("RECV: $incoming");
940                }
941
942                return $this->xmlize($incoming);
943        }
944
945
946
947        function _check_connected()
948        {
949                $incoming_array = $this->_listen_incoming();
950
951                if (is_array($incoming_array))
952                {
953                        if ($incoming_array["stream:stream"]['@']['from'] == $this->server
954                                && $incoming_array["stream:stream"]['@']['xmlns'] == "jabber:client"
955                                && $incoming_array["stream:stream"]['@']["xmlns:stream"] == "http://etherx.jabber.org/streams")
956                        {
957                                $this->stream_id = $incoming_array["stream:stream"]['@']['id'];
958
959                                if ($incoming_array["stream:stream"]["#"]["stream:features"][0]["#"]["starttls"][0]["@"]["xmlns"] == "urn:ietf:params:xml:ns:xmpp-tls")
960                                {
961                                        return $this->_starttls();
962                                }
963                                else
964                                {
965                                        return TRUE;
966                                }
967                        }
968                        else
969                        {
970                                $this->AddToLog("ERROR: _check_connected() #1");
971                                return FALSE;
972                        }
973                }
974                else
975                {
976                        $this->AddToLog("ERROR: _check_connected() #2");
977                        return FALSE;
978                }
979        }
980
981
982
983        function _starttls()
984        {
985                if (!function_exists("stream_socket_enable_crypto"))
986                {
987                        $this->AddToLog("WARNING: TLS is not available");
988                        return TRUE;
989                }
990
991                $this->SendPacket("<starttls xmlns='urn:ietf:params:xml:ns:xmpp-tls'/>\n");
992                sleep(2);
993                $incoming_array = $this->_listen_incoming();
994
995                if (!is_array($incoming_array))
996                {
997                        $this->AddToLog("ERROR: _starttls() #1");
998                        return FALSE;
999                }
1000
1001                if ($incoming_array["proceed"]["@"]["xmlns"] != "urn:ietf:params:xml:ns:xmpp-tls")
1002                {
1003                        $this->AddToLog("ERROR: _starttls() #2");
1004                        return FALSE;
1005                }
1006
1007                $meta = stream_get_meta_data($this->CONNECTOR->active_socket);
1008                socket_set_blocking($this->CONNECTOR->active_socket, 1);
1009                //if (!stream_socket_enable_crypto($this->CONNECTOR->active_socket, TRUE, STREAM_CRYPTO_METHOD_SSLv23_CLIENT))
1010                if (!stream_socket_enable_crypto($this->CONNECTOR->active_socket, TRUE, STREAM_CRYPTO_METHOD_TLS_CLIENT))
1011                {
1012                        socket_set_blocking($this->CONNECTOR->active_socket, $meta["blocked"]);
1013                        $this->AddToLog("ERROR: _starttls() #3");
1014                        return FALSE;
1015                }
1016                socket_set_blocking($this->CONNECTOR->active_socket, $meta["blocked"]);
1017
1018                $this->SendPacket("<?xml version='1.0' encoding='UTF-8' ?" . ">\n");
1019                $this->SendPacket("<stream:stream to='{$this->server}' xmlns='jabber:client' xmlns:stream='http://etherx.jabber.org/streams' version='1.0'>\n");
1020                sleep(2);
1021
1022                if (!$this->_check_connected())
1023                {
1024                        $this->AddToLog("ERROR: _starttls() #4");
1025                        return FALSE;
1026                }
1027
1028                return TRUE;
1029        }
1030
1031
1032
1033        function _get_packet_type($packet = NULL)
1034        {
1035                if (is_array($packet))
1036                {
1037                        reset($packet);
1038                        $packet_type = key($packet);
1039                }
1040
1041                return ($packet_type) ? $packet_type : FALSE;
1042        }
1043
1044
1045
1046        function _split_incoming($incoming)
1047        {
1048                $temp = preg_split("/<(message|iq|presence|stream)/", $incoming, -1, PREG_SPLIT_DELIM_CAPTURE);
1049                $array = array();
1050
1051                for ($a = 1; $a < count($temp); $a = $a + 2)
1052                {
1053                        $array[] = "<" . $temp[$a] . $temp[($a + 1)];
1054                }
1055
1056                return $array;
1057        }
1058
1059
1060
1061        function _create_logfile()
1062        {
1063                if ($this->log_filename != '' && $this->enable_logging)
1064                {
1065                        $this->log_filehandler = fopen($this->log_filename, 'w');
1066                }
1067        }
1068
1069
1070
1071        function AddToLog($string)
1072        {
1073                if ($this->enable_logging)
1074                {
1075                        if ($this->log_filehandler)
1076                        {
1077                                #fwrite($this->log_filehandler, $string . "\n\n");
1078                                print "$string \n\n";
1079                        }
1080                        else
1081                        {
1082                                $this->log_array[] = htmlspecialchars($string);
1083                        }
1084                }
1085        }
1086
1087
1088
1089        function _close_logfile()
1090        {
1091                if ($this->log_filehandler)
1092                {
1093                        fclose($this->log_filehandler);
1094                }
1095        }
1096
1097
1098
1099        // _array_htmlspecialchars()
1100        // applies htmlspecialchars() to all values in an array
1101
1102        function _array_htmlspecialchars($array)
1103        {
1104                if (is_array($array))
1105                {
1106                        foreach ($array as $k => $v)
1107                        {
1108                                if (is_array($v))
1109                                {
1110                                        $v = $this->_array_htmlspecialchars($v);
1111                                }
1112                                else
1113                                {
1114                                        $v = htmlspecialchars($v);
1115                                }
1116                        }
1117                }
1118
1119                return $array;
1120        }
1121
1122
1123
1124        // ======================================================================
1125        // <message/> parsers
1126        // ======================================================================
1127
1128
1129
1130        function GetInfoFromMessageFrom($packet = NULL)
1131        {
1132                return (is_array($packet)) ? $packet['message']['@']['from'] : FALSE;
1133        }
1134
1135
1136
1137        function GetInfoFromMessageType($packet = NULL)
1138        {
1139                return (is_array($packet)) ? $packet['message']['@']['type'] : FALSE;
1140        }
1141
1142
1143
1144        function GetInfoFromMessageId($packet = NULL)
1145        {
1146                return (is_array($packet)) ? $packet['message']['@']['id'] : FALSE;
1147        }
1148
1149
1150
1151        function GetInfoFromMessageThread($packet = NULL)
1152        {
1153                return (is_array($packet)) ? $packet['message']['#']['thread'][0]['#'] : FALSE;
1154        }
1155
1156
1157
1158        function GetInfoFromMessageSubject($packet = NULL)
1159        {
1160                return (is_array($packet)) ? $packet['message']['#']['subject'][0]['#'] : FALSE;
1161        }
1162
1163
1164
1165        function GetInfoFromMessageBody($packet = NULL)
1166        {
1167                return (is_array($packet)) ? $packet['message']['#']['body'][0]['#'] : FALSE;
1168        }
1169
1170        function GetInfoFromMessageXMLNS($packet = NULL)
1171        {
1172                return (is_array($packet)) ? $packet['message']['#']['x'] : FALSE;
1173        }
1174
1175
1176
1177        function GetInfoFromMessageError($packet = NULL)
1178        {
1179                $error = preg_replace("/^\/$/", "", ($packet['message']['#']['error'][0]['@']['code'] . "/" . $packet['message']['#']['error'][0]['#']));
1180                return (is_array($packet)) ? $error : FALSE;
1181        }
1182
1183
1184
1185        // ======================================================================
1186        // <iq/> parsers
1187        // ======================================================================
1188
1189
1190
1191        function GetInfoFromIqFrom($packet = NULL)
1192        {
1193                return (is_array($packet)) ? $packet['iq']['@']['from'] : FALSE;
1194        }
1195
1196
1197
1198        function GetInfoFromIqType($packet = NULL)
1199        {
1200                return (is_array($packet)) ? $packet['iq']['@']['type'] : FALSE;
1201        }
1202
1203
1204
1205        function GetInfoFromIqId($packet = NULL)
1206        {
1207                return (is_array($packet)) ? $packet['iq']['@']['id'] : FALSE;
1208        }
1209
1210
1211
1212        function GetInfoFromIqKey($packet = NULL)
1213        {
1214                return (is_array($packet)) ? $packet['iq']['#']['query'][0]['#']['key'][0]['#'] : FALSE;
1215        }
1216
1217
1218
1219        function GetInfoFromIqError($packet = NULL)
1220        {
1221                $error = preg_replace("/^\/$/", "", ($packet['iq']['#']['error'][0]['@']['code'] . "/" . $packet['iq']['#']['error'][0]['#']));
1222                return (is_array($packet)) ? $error : FALSE;
1223        }
1224
1225
1226
1227        // ======================================================================
1228        // <presence/> parsers
1229        // ======================================================================
1230
1231
1232
1233        function GetInfoFromPresenceFrom($packet = NULL)
1234        {
1235                return (is_array($packet)) ? $packet['presence']['@']['from'] : FALSE;
1236        }
1237
1238
1239
1240        function GetInfoFromPresenceType($packet = NULL)
1241        {
1242                return (is_array($packet)) ? $packet['presence']['@']['type'] : FALSE;
1243        }
1244
1245
1246
1247        function GetInfoFromPresenceStatus($packet = NULL)
1248        {
1249                return (is_array($packet)) ? $packet['presence']['#']['status'][0]['#'] : FALSE;
1250        }
1251
1252
1253
1254        function GetInfoFromPresenceShow($packet = NULL)
1255        {
1256                return (is_array($packet)) ? $packet['presence']['#']['show'][0]['#'] : FALSE;
1257        }
1258
1259
1260
1261        function GetInfoFromPresencePriority($packet = NULL)
1262        {
1263                return (is_array($packet)) ? $packet['presence']['#']['priority'][0]['#'] : FALSE;
1264        }
1265
1266
1267
1268        // ======================================================================
1269        // <message/> handlers
1270        // ======================================================================
1271
1272
1273
1274        function Handler_message_normal($packet)
1275        {
1276                $from = $packet['message']['@']['from'];
1277                $this->AddToLog("EVENT: Message (type normal) from $from");
1278        }
1279
1280
1281
1282        function Handler_message_chat($packet)
1283        {
1284                $from = $packet['message']['@']['from'];
1285                $this->AddToLog("EVENT: Message (type chat) from $from");
1286        }
1287
1288
1289
1290        function Handler_message_groupchat($packet)
1291        {
1292                $from = $packet['message']['@']['from'];
1293                $this->AddToLog("EVENT: Message (type groupchat) from $from");
1294        }
1295
1296
1297
1298        function Handler_message_headline($packet)
1299        {
1300                $from = $packet['message']['@']['from'];
1301                $this->AddToLog("EVENT: Message (type headline) from $from");
1302        }
1303
1304
1305
1306        function Handler_message_error($packet)
1307        {
1308                $from = $packet['message']['@']['from'];
1309                $this->AddToLog("EVENT: Message (type error) from $from");
1310        }
1311
1312
1313
1314        // ======================================================================
1315        // <iq/> handlers
1316        // ======================================================================
1317
1318
1319
1320        // application version updates
1321        function Handler_iq_jabber_iq_autoupdate($packet)
1322        {
1323                $from   = $this->GetInfoFromIqFrom($packet);
1324                $id             = $this->GetInfoFromIqId($packet);
1325
1326                $this->SendError($from, $id, 501);
1327                $this->AddToLog("EVENT: jabber:iq:autoupdate from $from");
1328        }
1329
1330
1331
1332        // interactive server component properties
1333        function Handler_iq_jabber_iq_agent($packet)
1334        {
1335                $from   = $this->GetInfoFromIqFrom($packet);
1336                $id             = $this->GetInfoFromIqId($packet);
1337
1338                $this->SendError($from, $id, 501);
1339                $this->AddToLog("EVENT: jabber:iq:agent from $from");
1340        }
1341
1342
1343
1344        // method to query interactive server components
1345        function Handler_iq_jabber_iq_agents($packet)
1346        {
1347                $from   = $this->GetInfoFromIqFrom($packet);
1348                $id             = $this->GetInfoFromIqId($packet);
1349
1350                $this->SendError($from, $id, 501);
1351                $this->AddToLog("EVENT: jabber:iq:agents from $from");
1352        }
1353
1354
1355
1356        // simple client authentication
1357        function Handler_iq_jabber_iq_auth($packet)
1358        {
1359                $from   = $this->GetInfoFromIqFrom($packet);
1360                $id             = $this->GetInfoFromIqId($packet);
1361
1362                $this->SendError($from, $id, 501);
1363                $this->AddToLog("EVENT: jabber:iq:auth from $from");
1364        }
1365
1366
1367
1368        // out of band data
1369        function Handler_iq_jabber_iq_oob($packet)
1370        {
1371                $from   = $this->GetInfoFromIqFrom($packet);
1372                $id             = $this->GetInfoFromIqId($packet);
1373
1374                $this->SendError($from, $id, 501);
1375                $this->AddToLog("EVENT: jabber:iq:oob from $from");
1376        }
1377
1378
1379
1380        // method to store private data on the server
1381        function Handler_iq_jabber_iq_private($packet)
1382        {
1383                $from   = $this->GetInfoFromIqFrom($packet);
1384                $id             = $this->GetInfoFromIqId($packet);
1385
1386                $this->SendError($from, $id, 501);
1387                $this->AddToLog("EVENT: jabber:iq:private from $from");
1388        }
1389
1390
1391
1392        // method for interactive registration
1393        function Handler_iq_jabber_iq_register($packet)
1394        {
1395                $from   = $this->GetInfoFromIqFrom($packet);
1396                $id             = $this->GetInfoFromIqId($packet);
1397
1398                $this->SendError($from, $id, 501);
1399                $this->AddToLog("EVENT: jabber:iq:register from $from");
1400        }
1401
1402
1403
1404        // client roster management
1405        function Handler_iq_jabber_iq_roster($packet)
1406        {
1407                $from   = $this->GetInfoFromIqFrom($packet);
1408                $id             = $this->GetInfoFromIqId($packet);
1409
1410                $this->SendError($from, $id, 501);
1411                $this->AddToLog("EVENT: jabber:iq:roster from $from");
1412        }
1413
1414
1415
1416        // method for searching a user database
1417        function Handler_iq_jabber_iq_search($packet)
1418        {
1419                $from   = $this->GetInfoFromIqFrom($packet);
1420                $id             = $this->GetInfoFromIqId($packet);
1421
1422                $this->SendError($from, $id, 501);
1423                $this->AddToLog("EVENT: jabber:iq:search from $from");
1424        }
1425
1426
1427
1428        // method for requesting the current time
1429        function Handler_iq_jabber_iq_time($packet)
1430        {
1431                if ($this->keep_alive_id == $this->GetInfoFromIqId($packet))
1432                {
1433                        $this->returned_keep_alive = TRUE;
1434                        $this->connected = TRUE;
1435                        $this->AddToLog('EVENT: Keep-Alive returned, connection alive.');
1436                }
1437                $type   = $this->GetInfoFromIqType($packet);
1438                $from   = $this->GetInfoFromIqFrom($packet);
1439                $id             = $this->GetInfoFromIqId($packet);
1440                $id             = ($id != "") ? $id : "time_" . time();
1441
1442                if ($type == 'get')
1443                {
1444                        $payload = "<utc>" . gmdate("Ydm\TH:i:s") . "</utc>
1445                                                <tz>" . date("T") . "</tz>
1446                                                <display>" . date("Y/d/m h:i:s A") . "</display>";
1447
1448                        $this->SendIq($from, 'result', $id, "jabber:iq:time", $payload);
1449                }
1450
1451                $this->AddToLog("EVENT: jabber:iq:time (type $type) from $from");
1452        }
1453
1454
1455
1456        // method for requesting version
1457        function Handler_iq_jabber_iq_version($packet)
1458        {
1459                $type   = $this->GetInfoFromIqType($packet);
1460                $from   = $this->GetInfoFromIqFrom($packet);
1461                $id             = $this->GetInfoFromIqId($packet);
1462                $id             = ($id != "") ? $id : "version_" . time();
1463
1464                if ($type == 'get')
1465                {
1466                        $payload = "<name>{$this->iq_version_name}</name>
1467                                                <os>{$this->iq_version_os}</os>
1468                                                <version>{$this->iq_version_version}</version>";
1469
1470                        #$this->SendIq($from, 'result', $id, "jabber:iq:version", $payload);
1471                }
1472
1473                $this->AddToLog("EVENT: jabber:iq:version (type $type) from $from -- DISABLED");
1474        }
1475
1476
1477
1478        // keepalive method, added by Nathan Fritz
1479        /*
1480        function Handler_jabber_iq_time($packet)
1481        {
1482                if ($this->keep_alive_id == $this->GetInfoFromIqId($packet))
1483                {
1484                        $this->returned_keep_alive = TRUE;
1485                        $this->connected = TRUE;
1486                        $this->AddToLog('EVENT: Keep-Alive returned, connection alive.');
1487                }
1488        }
1489        */
1490       
1491       
1492        // ======================================================================
1493        // <presence/> handlers
1494        // ======================================================================
1495
1496
1497
1498        function Handler_presence_available($packet)
1499        {
1500                $from = $this->GetInfoFromPresenceFrom($packet);
1501
1502                $show_status = $this->GetInfoFromPresenceStatus($packet) . " / " . $this->GetInfoFromPresenceShow($packet);
1503                $show_status = ($show_status != " / ") ? " ($addendum)" : '';
1504
1505                $this->AddToLog("EVENT: Presence (type: available) - $from is available $show_status");
1506        }
1507
1508
1509
1510        function Handler_presence_unavailable($packet)
1511        {
1512                $from = $this->GetInfoFromPresenceFrom($packet);
1513
1514                $show_status = $this->GetInfoFromPresenceStatus($packet) . " / " . $this->GetInfoFromPresenceShow($packet);
1515                $show_status = ($show_status != " / ") ? " ($addendum)" : '';
1516
1517                $this->AddToLog("EVENT: Presence (type: unavailable) - $from is unavailable $show_status");
1518        }
1519
1520
1521
1522        function Handler_presence_subscribe($packet)
1523        {
1524                $from = $this->GetInfoFromPresenceFrom($packet);
1525                $this->SubscriptionAcceptRequest($from);
1526                $this->RosterUpdate();
1527
1528                $this->log_array[] = "<b>Presence:</b> (type: subscribe) - Subscription request from $from, was added to \$this->subscription_queue, roster updated";
1529        }
1530
1531
1532
1533        function Handler_presence_subscribed($packet)
1534        {
1535                $from = $this->GetInfoFromPresenceFrom($packet);
1536                $this->RosterUpdate();
1537
1538                $this->AddToLog("EVENT: Presence (type: subscribed) - Subscription allowed by $from, roster updated");
1539        }
1540
1541
1542
1543        function Handler_presence_unsubscribe($packet)
1544        {
1545                $from = $this->GetInfoFromPresenceFrom($packet);
1546                $this->SendPresence("unsubscribed", $from);
1547                $this->RosterUpdate();
1548
1549                $this->AddToLog("EVENT: Presence (type: unsubscribe) - Request to unsubscribe from $from, was automatically approved, roster updated");
1550        }
1551
1552
1553
1554        function Handler_presence_unsubscribed($packet)
1555        {
1556                $from = $this->GetInfoFromPresenceFrom($packet);
1557                $this->RosterUpdate();
1558
1559                $this->AddToLog("EVENT: Presence (type: unsubscribed) - Unsubscribed from $from's presence");
1560        }
1561
1562
1563
1564        // Added By Nathan Fritz
1565        function Handler_presence_error($packet)
1566        {
1567                $from = $this->GetInfoFromPresenceFrom($packet);
1568                $this->AddToLog("EVENT: Presence (type: error) - Error in $from's presence");
1569        }
1570       
1571       
1572       
1573        // ======================================================================
1574        // Generic handlers
1575        // ======================================================================
1576
1577
1578
1579        // Generic handler for unsupported requests
1580        function Handler_NOT_IMPLEMENTED($packet)
1581        {
1582                $packet_type    = $this->_get_packet_type($packet);
1583                $from                   = call_user_func(array(&$this, "GetInfoFrom" . ucfirst($packet_type) . "From"), $packet);
1584                $id                             = call_user_func(array(&$this, "GetInfoFrom" . ucfirst($packet_type) . "Id"), $packet);
1585
1586                $this->SendError($from, $id, 501);
1587                $this->AddToLog("EVENT: Unrecognized <$packet_type/> from $from");
1588        }
1589
1590
1591
1592        // ======================================================================
1593        // Third party code
1594        // m@d pr0ps to the coders ;)
1595        // ======================================================================
1596
1597
1598
1599        // xmlize()
1600        // (c) Hans Anderson / http://www.hansanderson.com/php/xml/
1601
1602        function xmlize($data, $WHITE=1, $encoding='UTF-8') {
1603
1604                $data = trim($data);
1605                $vals = $index = $array = array();
1606                $parser = xml_parser_create($encoding);
1607                xml_parser_set_option($parser, XML_OPTION_CASE_FOLDING, 0);
1608                xml_parser_set_option($parser, XML_OPTION_SKIP_WHITE, $WHITE);
1609                xml_parse_into_struct($parser, $data, $vals, $index);
1610                xml_parser_free($parser);
1611
1612                $i = 0;
1613
1614                $tagname = $vals[$i]['tag'];
1615                if ( isset ($vals[$i]['attributes'] ) )
1616                {
1617                        $array[$tagname]['@'] = $vals[$i]['attributes'];
1618                } else {
1619                        $array[$tagname]['@'] = array();
1620                }
1621
1622                $array[$tagname]["#"] = $this->_xml_depth($vals, $i);
1623
1624
1625                return $array;
1626        }
1627
1628
1629
1630        // _xml_depth()
1631        // (c) Hans Anderson / http://www.hansanderson.com/php/xml/
1632
1633        function _xml_depth($vals, &$i) {
1634                $children = array();
1635
1636                if ( isset($vals[$i]['value']) )
1637                {
1638                        array_push($children, $vals[$i]['value']);
1639                }
1640
1641                while (++$i < count($vals)) {
1642
1643                        switch ($vals[$i]['type']) {
1644
1645                                case 'open':
1646
1647                                        if ( isset ( $vals[$i]['tag'] ) )
1648                                        {
1649                                                $tagname = $vals[$i]['tag'];
1650                                        } else {
1651                                                $tagname = '';
1652                                        }
1653
1654                                        if ( isset ( $children[$tagname] ) )
1655                                        {
1656                                                $size = sizeof($children[$tagname]);
1657                                        } else {
1658                                                $size = 0;
1659                                        }
1660
1661                                        if ( isset ( $vals[$i]['attributes'] ) ) {
1662                                                $children[$tagname][$size]['@'] = $vals[$i]["attributes"];
1663
1664                                        }
1665
1666                                        $children[$tagname][$size]['#'] = $this->_xml_depth($vals, $i);
1667
1668                                        break;
1669
1670
1671                                case 'cdata':
1672                                        array_push($children, $vals[$i]['value']);
1673                                        break;
1674
1675                                case 'complete':
1676                                        $tagname = $vals[$i]['tag'];
1677
1678                                        if( isset ($children[$tagname]) )
1679                                        {
1680                                                $size = sizeof($children[$tagname]);
1681                                        } else {
1682                                                $size = 0;
1683                                        }
1684
1685                                        if( isset ( $vals[$i]['value'] ) )
1686                                        {
1687                                                $children[$tagname][$size]["#"] = $vals[$i]['value'];
1688                                        } else {
1689                                                $children[$tagname][$size]["#"] = array();
1690                                        }
1691
1692                                        if ( isset ($vals[$i]['attributes']) ) {
1693                                                $children[$tagname][$size]['@']
1694                                                = $vals[$i]['attributes'];
1695                                        }
1696
1697                                        break;
1698
1699                                case 'close':
1700                                        return $children;
1701                                        break;
1702                        }
1703
1704                }
1705
1706                return $children;
1707
1708
1709        }
1710
1711
1712
1713        // TraverseXMLize()
1714        // (c) acebone@f2s.com, a HUGE help!
1715
1716        function TraverseXMLize($array, $arrName = "array", $level = 0) {
1717
1718                if ($level == 0)
1719                {
1720                        echo "<pre>";
1721                }
1722
1723                foreach($array as $key=>$val)
1724                {
1725                        if ( is_array($val) )
1726                        {
1727                                $this->TraverseXMLize($val, $arrName . "[" . $key . "]", $level + 1);
1728                        } else {
1729                                $GLOBALS['traverse_array'][] = '$' . $arrName . '[' . $key . '] = "' . $val . "\"\n";
1730                        }
1731                }
1732
1733                if ($level == 0)
1734                {
1735                        echo "</pre>";
1736                }
1737
1738                return 1;
1739
1740        }
1741}
1742
1743
1744
1745class MakeXML extends Jabber
1746{
1747        var $nodes;
1748
1749
1750        function MakeXML()
1751        {
1752                $nodes = array();
1753        }
1754
1755
1756
1757        function AddPacketDetails($string, $value = NULL)
1758        {
1759                if (preg_match("/\(([0-9]*)\)$/i", $string))
1760                {
1761                        $string .= "/[\"#\"]";
1762                }
1763
1764                $temp = @explode("/", $string);
1765
1766                for ($a = 0; $a < count($temp); $a++)
1767                {
1768                        $temp[$a] = preg_replace("/^[@]{1}([a-z0-9_]*)$/i", "[\"@\"][\"\\1\"]", $temp[$a]);
1769                        $temp[$a] = preg_replace("/^([a-z0-9_]*)\(([0-9]*)\)$/i", "[\"\\1\"][\\2]", $temp[$a]);
1770                        $temp[$a] = preg_replace("/^([a-z0-9_]*)$/i", "[\"\\1\"]", $temp[$a]);
1771                }
1772
1773                $node = implode("", $temp);
1774
1775                // Yeahyeahyeah, I know it's ugly... get over it. ;)
1776                echo "\$this->nodes$node = \"" . htmlspecialchars($value) . "\";<br/>";
1777                eval("\$this->nodes$node = \"" . htmlspecialchars($value) . "\";");
1778        }
1779
1780
1781
1782        function BuildPacket($array = NULL)
1783        {
1784
1785                if (!$array)
1786                {
1787                        $array = $this->nodes;
1788                }
1789
1790                if (is_array($array))
1791                {
1792                        array_multisort($array, SORT_ASC, SORT_STRING);
1793
1794                        foreach ($array as $key => $value)
1795                        {
1796                                if (is_array($value) && $key == "@")
1797                                {
1798                                        foreach ($value as $subkey => $subvalue)
1799                                        {
1800                                                $subvalue = htmlspecialchars($subvalue);
1801                                                $text .= " $subkey='$subvalue'";
1802                                        }
1803
1804                                        $text .= ">\n";
1805
1806                                }
1807                                elseif ($key == "#")
1808                                {
1809                                        $text .= htmlspecialchars($value);
1810                                }
1811                                elseif (is_array($value))
1812                                {
1813                                        for ($a = 0; $a < count($value); $a++)
1814                                        {
1815                                                $text .= "<$key";
1816
1817                                                if (!$this->_preg_grep_keys("/^@/", $value[$a]))
1818                                                {
1819                                                        $text .= ">";
1820                                                }
1821
1822                                                $text .= $this->BuildPacket($value[$a]);
1823
1824                                                $text .= "</$key>\n";
1825                                        }
1826                                }
1827                                else
1828                                {
1829                                        $value = htmlspecialchars($value);
1830                                        $text .= "<$key>$value</$key>\n";
1831                                }
1832                        }
1833
1834                        return $text;
1835                }
1836        }
1837
1838
1839
1840        function _preg_grep_keys($pattern, $array)
1841        {
1842                while (list($key, $val) = each($array))
1843                {
1844                        if (preg_match($pattern, $key))
1845                        {
1846                                $newarray[$key] = $val;
1847                        }
1848                }
1849                return (is_array($newarray)) ? $newarray : FALSE;
1850        }
1851}
1852
1853
1854
1855class CJP_StandardConnector
1856{
1857        var $active_socket;
1858
1859        function OpenSocket($server, $port)
1860        {
1861                if (function_exists("dns_get_record"))
1862                {
1863                        $record = dns_get_record("_xmpp-client._tcp.$server", DNS_SRV);
1864                        if (!empty($record))
1865                        {
1866                                $server = $record[0]["target"];
1867                                $port = $record[0]["port"];
1868                        }
1869                }
1870
1871                if ($this->active_socket = fsockopen($server, $port))
1872                {
1873                        socket_set_blocking($this->active_socket, 0);
1874                        socket_set_timeout($this->active_socket, 31536000);
1875
1876                        return TRUE;
1877                }
1878                else
1879                {
1880                        return FALSE;
1881                }
1882        }
1883
1884
1885
1886        function CloseSocket()
1887        {
1888                return fclose($this->active_socket);
1889        }
1890
1891
1892
1893        function WriteToSocket($data)
1894        {
1895                return fwrite($this->active_socket, $data);
1896        }
1897
1898
1899
1900        function ReadFromSocket($chunksize)
1901        {
1902                set_magic_quotes_runtime(0);
1903                $buffer = fread($this->active_socket, $chunksize);
1904                set_magic_quotes_runtime(get_magic_quotes_gpc());
1905
1906                return $buffer;
1907        }
1908}
1909
1910
1911
1912?>
Note: See TracBrowser for help on using the repository browser.