source: companies/serpro/jabberit_messenger/inc/class.jabber.inc.php @ 903

Revision 903, 41.5 KB checked in by niltonneto, 15 years ago (diff)

Importacao inicial do Expresso do Serpro

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