PageRenderTime 52ms CodeModel.GetById 19ms RepoModel.GetById 0ms app.codeStats 1ms

/saf/lib/Ext/Jabber/class.jabber.php

https://github.com/lux/siteforge
PHP | 1876 lines | 1256 code | 469 blank | 151 comment | 160 complexity | b6acd437ed237ab6f5e133984737da83 MD5 | raw file
Possible License(s): GPL-2.0, LGPL-2.1, Apache-2.0
  1. <?php
  2. /***************************************************************************
  3. Class.Jabber.PHP v0.4
  4. (c) 2002 Carlo "Gossip" Zottmann
  5. http://phpjabber.g-blog.net *** gossip@jabber.g-blog.net
  6. The FULL documentation and examples for this software can be found at
  7. http://phpjabber.g-blog.net (not many doc comments in here, sorry)
  8. last modified: 27.04.2003 13:01:53 CET
  9. ***************************************************************************/
  10. /***************************************************************************
  11. *
  12. *
  13. ***************************************************************************/
  14. /*
  15. Jabber::Connect()
  16. Jabber::Disconnect()
  17. Jabber::SendAuth()
  18. Jabber::AccountRegistration($reg_email {string}, $reg_name {string})
  19. Jabber::Listen()
  20. Jabber::SendPacket($xml {string})
  21. Jabber::RosterUpdate()
  22. Jabber::RosterAddUser($jid {string}, $id {string}, $name {string})
  23. Jabber::RosterRemoveUser($jid {string}, $id {string})
  24. Jabber::RosterExistsJID($jid {string})
  25. Jabber::Subscribe($jid {string})
  26. Jabber::Unsubscribe($jid {string})
  27. Jabber::CallHandler($message {array})
  28. Jabber::CruiseControl([$seconds {number}])
  29. Jabber::SubscriptionApproveRequest($to {string})
  30. Jabber::SubscriptionDenyRequest($to {string})
  31. Jabber::GetFirstFromQueue()
  32. Jabber::GetFromQueueById($packet_type {string}, $id {string})
  33. Jabber::SendMessage($to {string}, $id {number}, $type {string}, $content {array}[, $payload {array}])
  34. Jabber::SendIq($to {string}, $type {string}, $id {string}, $xmlns {string}[, $payload {string}])
  35. Jabber::SendPresence($type {string}[, $to {string}[, $status {string}[, $show {string}[, $priority {number}]]]])
  36. Jabber::SendError($to {string}, $id {string}, $error_number {number}[, $error_message {string}])
  37. Jabber::TransportRegistrationDetails($transport {string})
  38. Jabber::TransportRegistration($transport {string}, $details {array})
  39. Jabber::GetvCard($jid {string}[, $id {string}]) -- EXPERIMENTAL --
  40. Jabber::GetInfoFromMessageFrom($packet {array})
  41. Jabber::GetInfoFromMessageType($packet {array})
  42. Jabber::GetInfoFromMessageId($packet {array})
  43. Jabber::GetInfoFromMessageThread($packet {array})
  44. Jabber::GetInfoFromMessageSubject($packet {array})
  45. Jabber::GetInfoFromMessageBody($packet {array})
  46. Jabber::GetInfoFromMessageError($packet {array})
  47. Jabber::GetInfoFromIqFrom($packet {array})
  48. Jabber::GetInfoFromIqType($packet {array})
  49. Jabber::GetInfoFromIqId($packet {array})
  50. Jabber::GetInfoFromIqKey($packet {array})
  51. Jabber::GetInfoFromIqError($packet {array})
  52. Jabber::GetInfoFromPresenceFrom($packet {array})
  53. Jabber::GetInfoFromPresenceType($packet {array})
  54. Jabber::GetInfoFromPresenceStatus($packet {array})
  55. Jabber::GetInfoFromPresenceShow($packet {array})
  56. Jabber::GetInfoFromPresencePriority($packet {array})
  57. Jabber::AddToLog($string {string})
  58. Jabber::PrintLog()
  59. MakeXML::AddPacketDetails($string {string}[, $value {string/number}])
  60. MakeXML::BuildPacket([$array {array}])
  61. */
  62. class Jabber
  63. {
  64. var $server;
  65. var $port;
  66. var $username;
  67. var $password;
  68. var $resource;
  69. var $jid;
  70. var $connection;
  71. var $delay_disconnect;
  72. var $stream_id;
  73. var $roster;
  74. var $enable_logging;
  75. var $log_array;
  76. var $log_filename;
  77. var $log_filehandler;
  78. var $iq_sleep_timer;
  79. var $last_ping_time;
  80. var $packet_queue;
  81. var $subscription_queue;
  82. var $iq_version_name;
  83. var $iq_version_os;
  84. var $iq_version_version;
  85. var $error_codes;
  86. var $connected;
  87. var $keep_alive_id;
  88. var $returned_keep_alive;
  89. var $txnid;
  90. var $CONNECTOR;
  91. function Jabber()
  92. {
  93. $this->server = "localhost";
  94. $this->port = "5222";
  95. $this->username = "larry";
  96. $this->password = "curly";
  97. $this->resource = NULL;
  98. $this->enable_logging = FALSE;
  99. $this->log_array = array();
  100. $this->log_filename = '';
  101. $this->log_filehandler = FALSE;
  102. $this->packet_queue = array();
  103. $this->subscription_queue = array();
  104. $this->iq_sleep_timer = 1;
  105. $this->delay_disconnect = 1;
  106. $this->returned_keep_alive = TRUE;
  107. $this->txnid = 0;
  108. $this->iq_version_name = "Class.Jabber.PHP -- http://phpjabber.g-blog.net -- by Carlo 'Gossip' Zottmann, gossip@jabber.g-blog.net";
  109. $this->iq_version_version = "0.4";
  110. $this->iq_version_os = $_SERVER['SERVER_SOFTWARE'];
  111. $this->connection_class = "CJP_StandardConnector";
  112. $this->error_codes = array(400 => "Bad Request",
  113. 401 => "Unauthorized",
  114. 402 => "Payment Required",
  115. 403 => "Forbidden",
  116. 404 => "Not Found",
  117. 405 => "Not Allowed",
  118. 406 => "Not Acceptable",
  119. 407 => "Registration Required",
  120. 408 => "Request Timeout",
  121. 409 => "Conflict",
  122. 500 => "Internal Server Error",
  123. 501 => "Not Implemented",
  124. 502 => "Remove Server Error",
  125. 503 => "Service Unavailable",
  126. 504 => "Remove Server Timeout",
  127. 510 => "Disconnected");
  128. }
  129. function Connect()
  130. {
  131. $this->_create_logfile();
  132. $this->CONNECTOR = new $this->connection_class;
  133. if ($this->CONNECTOR->OpenSocket($this->server, $this->port))
  134. {
  135. $this->SendPacket("<?xml version='1.0' encoding='UTF-8' ?" . ">\n");
  136. $this->SendPacket("<stream:stream to='{$this->server}' xmlns='jabber:client' xmlns:stream='http://etherx.jabber.org/streams'>\n");
  137. sleep(2);
  138. if ($this->_check_connected())
  139. {
  140. $this->connected = TRUE; // Nathan Fritz
  141. return TRUE;
  142. }
  143. else
  144. {
  145. $this->AddToLog("ERROR: Connect() #1");
  146. return FALSE;
  147. }
  148. }
  149. else
  150. {
  151. $this->AddToLog("ERROR: Connect() #2");
  152. return FALSE;
  153. }
  154. }
  155. function Disconnect()
  156. {
  157. if (is_int($this->delay_disconnect))
  158. {
  159. sleep($this->delay_disconnect);
  160. }
  161. $this->SendPacket("</stream:stream>");
  162. $this->CONNECTOR->CloseSocket();
  163. $this->_close_logfile();
  164. $this->PrintLog();
  165. }
  166. function SendAuth()
  167. {
  168. $this->auth_id = "auth_" . md5(time() . $_SERVER['REMOTE_ADDR']);
  169. $this->resource = ($this->resource != NULL) ? $this->resource : ("Class.Jabber.PHP " . md5($this->auth_id));
  170. $this->jid = "{$this->username}@{$this->server}/{$this->resource}";
  171. // request available authentication methods
  172. $payload = "<username>{$this->username}</username>";
  173. $packet = $this->SendIq(NULL, 'get', $this->auth_id, "jabber:iq:auth", $payload);
  174. // was a result returned?
  175. if ($this->GetInfoFromIqType($packet) == 'result' && $this->GetInfoFromIqId($packet) == $this->auth_id)
  176. {
  177. // yes, now check for auth method availability in descending order (best to worst)
  178. if (!function_exists(mhash))
  179. {
  180. $this->AddToLog("ATTENTION: SendAuth() - mhash() is not available; screw 0k and digest method, we need to go with plaintext auth");
  181. }
  182. // auth_0k
  183. if (function_exists(mhash) && isset($packet['iq']['#']['query'][0]['#']['sequence'][0]["#"]) && isset($packet['iq']['#']['query'][0]['#']['token'][0]["#"]))
  184. {
  185. return $this->_sendauth_0k($packet['iq']['#']['query'][0]['#']['token'][0]["#"], $packet['iq']['#']['query'][0]['#']['sequence'][0]["#"]);
  186. }
  187. // digest
  188. elseif (function_exists(mhash) && isset($packet['iq']['#']['query'][0]['#']['digest']))
  189. {
  190. return $this->_sendauth_digest();
  191. }
  192. // plain text
  193. elseif ($packet['iq']['#']['query'][0]['#']['password'])
  194. {
  195. return $this->_sendauth_plaintext();
  196. }
  197. // dude, you're fucked
  198. {
  199. $this->AddToLog("ERROR: SendAuth() #2 - No auth method available!");
  200. return FALSE;
  201. }
  202. }
  203. else
  204. {
  205. // no result returned
  206. $this->AddToLog("ERROR: SendAuth() #1");
  207. return FALSE;
  208. }
  209. }
  210. function AccountRegistration($reg_email = NULL, $reg_name = NULL)
  211. {
  212. $packet = $this->SendIq($this->server, 'get', 'reg_01', 'jabber:iq:register');
  213. if ($packet)
  214. {
  215. $key = $this->GetInfoFromIqKey($packet); // just in case a key was passed back from the server
  216. unset($packet);
  217. $payload = "<username>{$this->username}</username>
  218. <password>{$this->password}</password>
  219. <email>$reg_email</email>
  220. <name>$reg_name</name>\n";
  221. $payload .= ($key) ? "<key>$key</key>\n" : '';
  222. $packet = $this->SendIq($this->server, 'set', "reg_01", "jabber:iq:register", $payload);
  223. if ($this->GetInfoFromIqType($packet) == 'result')
  224. {
  225. if (isset($packet['iq']['#']['query'][0]['#']['registered'][0]['#']))
  226. {
  227. $return_code = 1;
  228. }
  229. else
  230. {
  231. $return_code = 2;
  232. }
  233. if ($this->resource)
  234. {
  235. $this->jid = "{$this->username}@{$this->server}/{$this->resource}";
  236. }
  237. else
  238. {
  239. $this->jid = "{$this->username}@{$this->server}";
  240. }
  241. }
  242. elseif ($this->GetInfoFromIqType($packet) == 'error' && isset($packet['iq']['#']['error'][0]['#']))
  243. {
  244. // "conflict" error, i.e. already registered
  245. if ($packet['iq']['#']['error'][0]['@']['code'] == '409')
  246. {
  247. $return_code = 1;
  248. }
  249. else
  250. {
  251. $return_code = "Error " . $packet['iq']['#']['error'][0]['@']['code'] . ": " . $packet['iq']['#']['error'][0]['#'];
  252. }
  253. }
  254. return $return_code;
  255. }
  256. else
  257. {
  258. return 3;
  259. }
  260. }
  261. function SendPacket($xml)
  262. {
  263. $xml = trim($xml);
  264. if ($this->CONNECTOR->WriteToSocket($xml))
  265. {
  266. $this->AddToLog("SEND: $xml");
  267. return TRUE;
  268. }
  269. else
  270. {
  271. $this->AddToLog('ERROR: SendPacket() #1');
  272. return FALSE;
  273. }
  274. }
  275. function Listen()
  276. {
  277. unset($incoming);
  278. while ($line = $this->CONNECTOR->ReadFromSocket(4096))
  279. {
  280. $incoming .= $line;
  281. }
  282. $incoming = trim($incoming);
  283. if ($incoming != "")
  284. {
  285. $this->AddToLog("RECV: $incoming");
  286. }
  287. if ($incoming != "")
  288. {
  289. $temp = $this->_split_incoming($incoming);
  290. for ($a = 0; $a < count($temp); $a++)
  291. {
  292. $this->packet_queue[] = $this->xmlize($temp[$a]);
  293. }
  294. }
  295. return TRUE;
  296. }
  297. function StripJID($jid = NULL)
  298. {
  299. preg_match("/(.*)\/(.*)/Ui", $jid, $temp);
  300. return ($temp[1] != "") ? $temp[1] : $jid;
  301. }
  302. function SendMessage($to, $type = "normal", $id = NULL, $content = NULL, $payload = NULL)
  303. {
  304. if ($to && is_array($content))
  305. {
  306. if (!$id)
  307. {
  308. $id = $type . "_" . time();
  309. }
  310. $content = $this->_array_htmlspecialchars($content);
  311. $xml = "<message to='$to' type='$type' id='$id'>\n";
  312. if ($content['subject'])
  313. {
  314. $xml .= "<subject>" . $content['subject'] . "</subject>\n";
  315. }
  316. if ($content['thread'])
  317. {
  318. $xml .= "<thread>" . $content['thread'] . "</thread>\n";
  319. }
  320. $xml .= "<body>" . $content['body'] . "</body>\n";
  321. $xml .= $payload;
  322. $xml .= "</message>\n";
  323. if ($this->SendPacket($xml))
  324. {
  325. return TRUE;
  326. }
  327. else
  328. {
  329. $this->AddToLog("ERROR: SendMessage() #1");
  330. return FALSE;
  331. }
  332. }
  333. else
  334. {
  335. $this->AddToLog("ERROR: SendMessage() #2");
  336. return FALSE;
  337. }
  338. }
  339. function SendPresence($type = NULL, $to = NULL, $status = NULL, $show = NULL, $priority = NULL)
  340. {
  341. $xml = "<presence";
  342. $xml .= ($to) ? " to='$to'" : '';
  343. $xml .= ($type) ? " type='$type'" : '';
  344. $xml .= ($status || $show || $priority) ? ">\n" : " />\n";
  345. $xml .= ($status) ? " <status>$status</status>\n" : '';
  346. $xml .= ($show) ? " <show>$show</show>\n" : '';
  347. $xml .= ($priority) ? " <priority>$priority</priority>\n" : '';
  348. $xml .= ($status || $show || $priority) ? "</presence>\n" : '';
  349. if ($this->SendPacket($xml))
  350. {
  351. return TRUE;
  352. }
  353. else
  354. {
  355. $this->AddToLog("ERROR: SendPresence() #1");
  356. return FALSE;
  357. }
  358. }
  359. function SendError($to, $id = NULL, $error_number, $error_message = NULL)
  360. {
  361. $xml = "<iq type='error' to='$to'";
  362. $xml .= ($id) ? " id='$id'" : '';
  363. $xml .= ">\n";
  364. $xml .= " <error code='$error_number'>";
  365. $xml .= ($error_message) ? $error_message : $this->error_codes[$error_number];
  366. $xml .= "</error>\n";
  367. $xml .= "</iq>";
  368. $this->SendPacket($xml);
  369. }
  370. function RosterUpdate()
  371. {
  372. $roster_request_id = "roster_" . time();
  373. $incoming_array = $this->SendIq(NULL, 'get', $roster_request_id, "jabber:iq:roster");
  374. if (is_array($incoming_array))
  375. {
  376. if ($incoming_array['iq']['@']['type'] == 'result'
  377. && $incoming_array['iq']['@']['id'] == $roster_request_id
  378. && $incoming_array['iq']['#']['query']['0']['@']['xmlns'] == "jabber:iq:roster")
  379. {
  380. $number_of_contacts = count($incoming_array['iq']['#']['query'][0]['#']['item']);
  381. $this->roster = array();
  382. for ($a = 0; $a < $number_of_contacts; $a++)
  383. {
  384. $this->roster[$a] = array( "jid" => strtolower($incoming_array['iq']['#']['query'][0]['#']['item'][$a]['@']['jid']),
  385. "name" => $incoming_array['iq']['#']['query'][0]['#']['item'][$a]['@']['name'],
  386. "subscription" => $incoming_array['iq']['#']['query'][0]['#']['item'][$a]['@']['subscription'],
  387. "group" => $incoming_array['iq']['#']['query'][0]['#']['item'][$a]['#']['group'][0]['#']
  388. );
  389. }
  390. return TRUE;
  391. }
  392. else
  393. {
  394. $this->AddToLog("ERROR: RosterUpdate() #1");
  395. return FALSE;
  396. }
  397. }
  398. else
  399. {
  400. $this->AddToLog("ERROR: RosterUpdate() #2");
  401. return FALSE;
  402. }
  403. }
  404. function RosterAddUser($jid = NULL, $id = NULL, $name = NULL)
  405. {
  406. $id = ($id) ? $id : "adduser_" . time();
  407. if ($jid)
  408. {
  409. $payload = " <item jid='$jid'";
  410. $payload .= ($name) ? " name='" . htmlspecialchars($name) . "'" : '';
  411. $payload .= "/>\n";
  412. $packet = $this->SendIq(NULL, 'set', $id, "jabber:iq:roster", $payload);
  413. if ($this->GetInfoFromIqType($packet) == 'result')
  414. {
  415. $this->RosterUpdate();
  416. return TRUE;
  417. }
  418. else
  419. {
  420. $this->AddToLog("ERROR: RosterAddUser() #2");
  421. return FALSE;
  422. }
  423. }
  424. else
  425. {
  426. $this->AddToLog("ERROR: RosterAddUser() #1");
  427. return FALSE;
  428. }
  429. }
  430. function RosterRemoveUser($jid = NULL, $id = NULL)
  431. {
  432. $id = ($id) ? $id : 'deluser_' . time();
  433. if ($jid && $id)
  434. {
  435. $packet = $this->SendIq(NULL, 'set', $id, "jabber:iq:roster", "<item jid='$jid' subscription='remove'/>");
  436. if ($this->GetInfoFromIqType($packet) == 'result')
  437. {
  438. $this->RosterUpdate();
  439. return TRUE;
  440. }
  441. else
  442. {
  443. $this->AddToLog("ERROR: RosterRemoveUser() #2");
  444. return FALSE;
  445. }
  446. }
  447. else
  448. {
  449. $this->AddToLog("ERROR: RosterRemoveUser() #1");
  450. return FALSE;
  451. }
  452. }
  453. function RosterExistsJID($jid = NULL)
  454. {
  455. if ($jid)
  456. {
  457. if ($this->roster)
  458. {
  459. for ($a = 0; $a < count($this->roster); $a++)
  460. {
  461. if ($this->roster[$a]['jid'] == strtolower($jid))
  462. {
  463. return $a;
  464. }
  465. }
  466. }
  467. else
  468. {
  469. $this->AddToLog("ERROR: RosterExistsJID() #2");
  470. return FALSE;
  471. }
  472. }
  473. else
  474. {
  475. $this->AddToLog("ERROR: RosterExistsJID() #1");
  476. return FALSE;
  477. }
  478. }
  479. function GetFirstFromQueue()
  480. {
  481. return array_shift($this->packet_queue);
  482. }
  483. function GetFromQueueById($packet_type, $id)
  484. {
  485. $found_message = FALSE;
  486. foreach ($this->packet_queue as $key => $value)
  487. {
  488. if ($value[$packet_type]['@']['id'] == $id)
  489. {
  490. $found_message = $value;
  491. unset($this->packet_queue[$key]);
  492. break;
  493. }
  494. }
  495. return (is_array($found_message)) ? $found_message : FALSE;
  496. }
  497. function CallHandler($packet = NULL)
  498. {
  499. $packet_type = $this->_get_packet_type($packet);
  500. if ($packet_type == "message")
  501. {
  502. $type = $packet['message']['@']['type'];
  503. $type = ($type != "") ? $type : "normal";
  504. $funcmeth = "Handler_message_$type";
  505. }
  506. elseif ($packet_type == "iq")
  507. {
  508. $namespace = $packet['iq']['#']['query'][0]['@']['xmlns'];
  509. $namespace = str_replace(":", "_", $namespace);
  510. $funcmeth = "Handler_iq_$namespace";
  511. }
  512. elseif ($packet_type == "presence")
  513. {
  514. $type = $packet['presence']['@']['type'];
  515. $type = ($type != "") ? $type : "available";
  516. $funcmeth = "Handler_presence_$type";
  517. }
  518. if ($funcmeth != '')
  519. {
  520. if (function_exists($funcmeth))
  521. {
  522. call_user_func($funcmeth, $packet);
  523. }
  524. elseif (method_exists($this, $funcmeth))
  525. {
  526. call_user_func(array(&$this, $funcmeth), $packet);
  527. }
  528. else
  529. {
  530. $this->Handler_NOT_IMPLEMENTED($packet);
  531. $this->AddToLog("ERROR: CallHandler() #1 - neither method nor function $funcmeth() available");
  532. }
  533. }
  534. }
  535. function CruiseControl($seconds = -1)
  536. {
  537. $count = 0;
  538. while ($count != $seconds)
  539. {
  540. $this->Listen();
  541. do {
  542. $packet = $this->GetFirstFromQueue();
  543. if ($packet) {
  544. $this->CallHandler($packet);
  545. }
  546. } while (count($this->packet_queue) > 1);
  547. $count += 0.25;
  548. usleep(250000);
  549. if ($this->last_ping_time != date('H:i'))
  550. {
  551. // Modified by Nathan Fritz
  552. if ($this->returned_keep_alive == FALSE)
  553. {
  554. $this->connected = FALSE;
  555. $this->AddToLog('EVENT: Disconnected');
  556. }
  557. $this->returned_keep_alive = FALSE;
  558. $this->keep_alive_id = 'keep_alive_' . time();
  559. $this->SendPacket("<iq id='{$this->keep_alive_id}'/>", 'CruiseControl');
  560. // **
  561. $this->last_ping_time = date("H:i");
  562. }
  563. }
  564. return TRUE;
  565. }
  566. function SubscriptionAcceptRequest($to = NULL)
  567. {
  568. return ($to) ? $this->SendPresence("subscribed", $to) : FALSE;
  569. }
  570. function SubscriptionDenyRequest($to = NULL)
  571. {
  572. return ($to) ? $this->SendPresence("unsubscribed", $to) : FALSE;
  573. }
  574. function Subscribe($to = NULL)
  575. {
  576. return ($to) ? $this->SendPresence("subscribe", $to) : FALSE;
  577. }
  578. function Unsubscribe($to = NULL)
  579. {
  580. return ($to) ? $this->SendPresence("unsubscribe", $to) : FALSE;
  581. }
  582. function SendIq($to = NULL, $type = 'get', $id = NULL, $xmlns = NULL, $payload = NULL, $from = NULL)
  583. {
  584. if (!preg_match("/^(get|set|result|error)$/", $type))
  585. {
  586. unset($type);
  587. $this->AddToLog("ERROR: SendIq() #2 - type must be 'get', 'set', 'result' or 'error'");
  588. return FALSE;
  589. }
  590. elseif ($id && $xmlns)
  591. {
  592. $xml = "<iq type='$type' id='$id'";
  593. $xml .= ($to) ? " to='$to'" : '';
  594. $xml .= ($from) ? " from='$from'" : '';
  595. $xml .= ">
  596. <query xmlns='$xmlns'>
  597. $payload
  598. </query>
  599. </iq>";
  600. $this->SendPacket($xml);
  601. sleep($this->iq_sleep_timer);
  602. $this->Listen();
  603. return (preg_match("/^(get|set)$/", $type)) ? $this->GetFromQueueById("iq", $id) : TRUE;
  604. }
  605. else
  606. {
  607. $this->AddToLog("ERROR: SendIq() #1 - to, id and xmlns are mandatory");
  608. return FALSE;
  609. }
  610. }
  611. // get the transport registration fields
  612. // method written by Steve Blinch, http://www.blitzaffe.com
  613. function TransportRegistrationDetails($transport)
  614. {
  615. $this->txnid++;
  616. $packet = $this->SendIq($transport, 'get', "reg_{$this->txnid}", "jabber:iq:register", NULL, $this->jid);
  617. if ($packet)
  618. {
  619. $res = array();
  620. foreach ($packet['iq']['#']['query'][0]['#'] as $element => $data)
  621. {
  622. if ($element != 'instructions' && $element != 'key')
  623. {
  624. $res[] = $element;
  625. }
  626. }
  627. return $res;
  628. }
  629. else
  630. {
  631. return 3;
  632. }
  633. }
  634. // register with the transport
  635. // method written by Steve Blinch, http://www.blitzaffe.com
  636. function TransportRegistration($transport, $details)
  637. {
  638. $this->txnid++;
  639. $packet = $this->SendIq($transport, 'get', "reg_{$this->txnid}", "jabber:iq:register", NULL, $this->jid);
  640. if ($packet)
  641. {
  642. $key = $this->GetInfoFromIqKey($packet); // just in case a key was passed back from the server
  643. unset($packet);
  644. $payload = ($key) ? "<key>$key</key>\n" : '';
  645. foreach ($details as $element => $value)
  646. {
  647. $payload .= "<$element>$value</$element>\n";
  648. }
  649. $packet = $this->SendIq($transport, 'set', "reg_{$this->txnid}", "jabber:iq:register", $payload);
  650. if ($this->GetInfoFromIqType($packet) == 'result')
  651. {
  652. if (isset($packet['iq']['#']['query'][0]['#']['registered'][0]['#']))
  653. {
  654. $return_code = 1;
  655. }
  656. else
  657. {
  658. $return_code = 2;
  659. }
  660. }
  661. elseif ($this->GetInfoFromIqType($packet) == 'error')
  662. {
  663. if (isset($packet['iq']['#']['error'][0]['#']))
  664. {
  665. $return_code = "Error " . $packet['iq']['#']['error'][0]['@']['code'] . ": " . $packet['iq']['#']['error'][0]['#'];
  666. $this->AddToLog('ERROR: TransportRegistration()');
  667. }
  668. }
  669. return $return_code;
  670. }
  671. else
  672. {
  673. return 3;
  674. }
  675. }
  676. function GetvCard($jid = NULL, $id = NULL)
  677. {
  678. if (!$id)
  679. {
  680. $id = "vCard_" . md5(time() . $_SERVER['REMOTE_ADDR']);
  681. }
  682. if ($jid)
  683. {
  684. $xml = "<iq type='get' to='$jid' id='$id'>
  685. <vCard xmlns='vcard-temp'/>
  686. </iq>";
  687. $this->SendPacket($xml);
  688. sleep($this->iq_sleep_timer);
  689. $this->Listen();
  690. return $this->GetFromQueueById("iq", $id);
  691. }
  692. else
  693. {
  694. $this->AddToLog("ERROR: GetvCard() #1 - to and id are mandatory");
  695. return FALSE;
  696. }
  697. }
  698. function PrintLog()
  699. {
  700. if ($this->enable_logging)
  701. {
  702. if ($this->log_filehandler)
  703. {
  704. echo "<h2>Logging enabled, logged events have been written to the file {$this->log_filename}.</h2>\n";
  705. }
  706. else
  707. {
  708. echo "<h2>Logging enabled, logged events below:</h2>\n";
  709. echo "<pre>\n";
  710. echo (count($this->log_array) > 0) ? implode("\n\n\n", $this->log_array) : "No logged events.";
  711. echo "</pre>\n";
  712. }
  713. }
  714. }
  715. // ======================================================================
  716. // private methods
  717. // ======================================================================
  718. function _sendauth_0k($zerok_token, $zerok_sequence)
  719. {
  720. // initial hash of password
  721. $zerok_hash = mhash(MHASH_SHA1, $this->password);
  722. $zerok_hash = bin2hex($zerok_hash);
  723. // sequence 0: hash of hashed-password and token
  724. $zerok_hash = mhash(MHASH_SHA1, $zerok_hash . $zerok_token);
  725. $zerok_hash = bin2hex($zerok_hash);
  726. // repeat as often as needed
  727. for ($a = 0; $a < $zerok_sequence; $a++)
  728. {
  729. $zerok_hash = mhash(MHASH_SHA1, $zerok_hash);
  730. $zerok_hash = bin2hex($zerok_hash);
  731. }
  732. $payload = "<username>{$this->username}</username>
  733. <hash>$zerok_hash</hash>
  734. <resource>{$this->resource}</resource>";
  735. $packet = $this->SendIq(NULL, 'set', $this->auth_id, "jabber:iq:auth", $payload);
  736. // was a result returned?
  737. if ($this->GetInfoFromIqType($packet) == 'result' && $this->GetInfoFromIqId($packet) == $this->auth_id)
  738. {
  739. return TRUE;
  740. }
  741. else
  742. {
  743. $this->AddToLog("ERROR: _sendauth_0k() #1");
  744. return FALSE;
  745. }
  746. }
  747. function _sendauth_digest()
  748. {
  749. $payload = "<username>{$this->username}</username>
  750. <resource>{$this->resource}</resource>
  751. <digest>" . bin2hex(mhash(MHASH_SHA1, $this->stream_id . $this->password)) . "</digest>";
  752. $packet = $this->SendIq(NULL, 'set', $this->auth_id, "jabber:iq:auth", $payload);
  753. // was a result returned?
  754. if ($this->GetInfoFromIqType($packet) == 'result' && $this->GetInfoFromIqId($packet) == $this->auth_id)
  755. {
  756. return TRUE;
  757. }
  758. else
  759. {
  760. $this->AddToLog("ERROR: _sendauth_digest() #1");
  761. return FALSE;
  762. }
  763. }
  764. function _sendauth_plaintext()
  765. {
  766. $payload = "<username>{$this->username}</username>
  767. <password>{$this->password}</password>
  768. <resource>{$this->resource}</resource>";
  769. $packet = $this->SendIq(NULL, 'set', $this->auth_id, "jabber:iq:auth", $payload);
  770. // was a result returned?
  771. if ($this->GetInfoFromIqType($packet) == 'result' && $this->GetInfoFromIqId($packet) == $this->auth_id)
  772. {
  773. return TRUE;
  774. }
  775. else
  776. {
  777. $this->AddToLog("ERROR: _sendauth_plaintext() #1");
  778. return FALSE;
  779. }
  780. }
  781. function _listen_incoming()
  782. {
  783. unset($incoming);
  784. while ($line = $this->CONNECTOR->ReadFromSocket(4096))
  785. {
  786. $incoming .= $line;
  787. }
  788. $incoming = trim($incoming);
  789. if ($incoming != "")
  790. {
  791. $this->AddToLog("RECV: $incoming");
  792. }
  793. return $this->xmlize($incoming);
  794. }
  795. function _check_connected()
  796. {
  797. $incoming_array = $this->_listen_incoming();
  798. if (is_array($incoming_array))
  799. {
  800. if ($incoming_array["stream:stream"]['@']['from'] == $this->server
  801. && $incoming_array["stream:stream"]['@']['xmlns'] == "jabber:client"
  802. && $incoming_array["stream:stream"]['@']["xmlns:stream"] == "http://etherx.jabber.org/streams")
  803. {
  804. $this->stream_id = $incoming_array["stream:stream"]['@']['id'];
  805. return TRUE;
  806. }
  807. else
  808. {
  809. $this->AddToLog("ERROR: _check_connected() #1");
  810. return FALSE;
  811. }
  812. }
  813. else
  814. {
  815. $this->AddToLog("ERROR: _check_connected() #2");
  816. return FALSE;
  817. }
  818. }
  819. function _get_packet_type($packet = NULL)
  820. {
  821. if (is_array($packet))
  822. {
  823. reset($packet);
  824. $packet_type = key($packet);
  825. }
  826. return ($packet_type) ? $packet_type : FALSE;
  827. }
  828. function _split_incoming($incoming)
  829. {
  830. $temp = preg_split("/<(message|iq|presence|stream)/", $incoming, -1, PREG_SPLIT_DELIM_CAPTURE);
  831. $array = array();
  832. for ($a = 1; $a < count($temp); $a = $a + 2)
  833. {
  834. $array[] = "<" . $temp[$a] . $temp[($a + 1)];
  835. }
  836. return $array;
  837. }
  838. function _create_logfile()
  839. {
  840. if ($this->log_filename != '' && $this->enable_logging)
  841. {
  842. $this->log_filehandler = fopen($this->log_filename, 'w');
  843. }
  844. }
  845. function AddToLog($string)
  846. {
  847. if ($this->enable_logging)
  848. {
  849. if ($this->log_filehandler)
  850. {
  851. fwrite($this->log_filehandler, $string . "\n\n");
  852. }
  853. else
  854. {
  855. $this->log_array[] = htmlspecialchars($string);
  856. }
  857. }
  858. }
  859. function _close_logfile()
  860. {
  861. if ($this->log_filehandler)
  862. {
  863. fclose($this->log_filehandler);
  864. }
  865. }
  866. // _array_htmlspecialchars()
  867. // applies htmlspecialchars() to all values in an array
  868. function _array_htmlspecialchars($array)
  869. {
  870. if (is_array($array))
  871. {
  872. foreach ($array as $k => $v)
  873. {
  874. if (is_array($v))
  875. {
  876. $v = $this->_array_htmlspecialchars($v);
  877. }
  878. else
  879. {
  880. $v = htmlspecialchars($v);
  881. }
  882. }
  883. }
  884. return $array;
  885. }
  886. // ======================================================================
  887. // <message/> parsers
  888. // ======================================================================
  889. function GetInfoFromMessageFrom($packet = NULL)
  890. {
  891. return (is_array($packet)) ? $packet['message']['@']['from'] : FALSE;
  892. }
  893. function GetInfoFromMessageType($packet = NULL)
  894. {
  895. return (is_array($packet)) ? $packet['message']['@']['type'] : FALSE;
  896. }
  897. function GetInfoFromMessageId($packet = NULL)
  898. {
  899. return (is_array($packet)) ? $packet['message']['@']['id'] : FALSE;
  900. }
  901. function GetInfoFromMessageThread($packet = NULL)
  902. {
  903. return (is_array($packet)) ? $packet['message']['#']['thread'][0]['#'] : FALSE;
  904. }
  905. function GetInfoFromMessageSubject($packet = NULL)
  906. {
  907. return (is_array($packet)) ? $packet['message']['#']['subject'][0]['#'] : FALSE;
  908. }
  909. function GetInfoFromMessageBody($packet = NULL)
  910. {
  911. return (is_array($packet)) ? $packet['message']['#']['body'][0]['#'] : FALSE;
  912. }
  913. function GetInfoFromMessageError($packet = NULL)
  914. {
  915. $error = preg_replace("/^\/$/", "", ($packet['message']['#']['error'][0]['@']['code'] . "/" . $packet['message']['#']['error'][0]['#']));
  916. return (is_array($packet)) ? $error : FALSE;
  917. }
  918. // ======================================================================
  919. // <iq/> parsers
  920. // ======================================================================
  921. function GetInfoFromIqFrom($packet = NULL)
  922. {
  923. return (is_array($packet)) ? $packet['iq']['@']['from'] : FALSE;
  924. }
  925. function GetInfoFromIqType($packet = NULL)
  926. {
  927. return (is_array($packet)) ? $packet['iq']['@']['type'] : FALSE;
  928. }
  929. function GetInfoFromIqId($packet = NULL)
  930. {
  931. return (is_array($packet)) ? $packet['iq']['@']['id'] : FALSE;
  932. }
  933. function GetInfoFromIqKey($packet = NULL)
  934. {
  935. return (is_array($packet)) ? $packet['iq']['#']['query'][0]['#']['key'][0]['#'] : FALSE;
  936. }
  937. function GetInfoFromIqError($packet = NULL)
  938. {
  939. $error = preg_replace("/^\/$/", "", ($packet['iq']['#']['error'][0]['@']['code'] . "/" . $packet['iq']['#']['error'][0]['#']));
  940. return (is_array($packet)) ? $error : FALSE;
  941. }
  942. // ======================================================================
  943. // <presence/> parsers
  944. // ======================================================================
  945. function GetInfoFromPresenceFrom($packet = NULL)
  946. {
  947. return (is_array($packet)) ? $packet['presence']['@']['from'] : FALSE;
  948. }
  949. function GetInfoFromPresenceType($packet = NULL)
  950. {
  951. return (is_array($packet)) ? $packet['presence']['@']['type'] : FALSE;
  952. }
  953. function GetInfoFromPresenceStatus($packet = NULL)
  954. {
  955. return (is_array($packet)) ? $packet['presence']['#']['status'][0]['#'] : FALSE;
  956. }
  957. function GetInfoFromPresenceShow($packet = NULL)
  958. {
  959. return (is_array($packet)) ? $packet['presence']['#']['show'][0]['#'] : FALSE;
  960. }
  961. function GetInfoFromPresencePriority($packet = NULL)
  962. {
  963. return (is_array($packet)) ? $packet['presence']['#']['priority'][0]['#'] : FALSE;
  964. }
  965. // ======================================================================
  966. // <message/> handlers
  967. // ======================================================================
  968. function Handler_message_normal($packet)
  969. {
  970. $from = $packet['message']['@']['from'];
  971. $this->AddToLog("EVENT: Message (type normal) from $from");
  972. }
  973. function Handler_message_chat($packet)
  974. {
  975. $from = $packet['message']['@']['from'];
  976. $this->AddToLog("EVENT: Message (type chat) from $from");
  977. }
  978. function Handler_message_groupchat($packet)
  979. {
  980. $from = $packet['message']['@']['from'];
  981. $this->AddToLog("EVENT: Message (type groupchat) from $from");
  982. }
  983. function Handler_message_headline($packet)
  984. {
  985. $from = $packet['message']['@']['from'];
  986. $this->AddToLog("EVENT: Message (type headline) from $from");
  987. }
  988. function Handler_message_error($packet)
  989. {
  990. $from = $packet['message']['@']['from'];
  991. $this->AddToLog("EVENT: Message (type error) from $from");
  992. }
  993. // ======================================================================
  994. // <iq/> handlers
  995. // ======================================================================
  996. // application version updates
  997. function Handler_iq_jabber_iq_autoupdate($packet)
  998. {
  999. $from = $this->GetInfoFromIqFrom($packet);
  1000. $id = $this->GetInfoFromIqId($packet);
  1001. $this->SendError($from, $id, 501);
  1002. $this->AddToLog("EVENT: jabber:iq:autoupdate from $from");
  1003. }
  1004. // interactive server component properties
  1005. function Handler_iq_jabber_iq_agent($packet)
  1006. {
  1007. $from = $this->GetInfoFromIqFrom($packet);
  1008. $id = $this->GetInfoFromIqId($packet);
  1009. $this->SendError($from, $id, 501);
  1010. $this->AddToLog("EVENT: jabber:iq:agent from $from");
  1011. }
  1012. // method to query interactive server components
  1013. function Handler_iq_jabber_iq_agents($packet)
  1014. {
  1015. $from = $this->GetInfoFromIqFrom($packet);
  1016. $id = $this->GetInfoFromIqId($packet);
  1017. $this->SendError($from, $id, 501);
  1018. $this->AddToLog("EVENT: jabber:iq:agents from $from");
  1019. }
  1020. // simple client authentication
  1021. function Handler_iq_jabber_iq_auth($packet)
  1022. {
  1023. $from = $this->GetInfoFromIqFrom($packet);
  1024. $id = $this->GetInfoFromIqId($packet);
  1025. $this->SendError($from, $id, 501);
  1026. $this->AddToLog("EVENT: jabber:iq:auth from $from");
  1027. }
  1028. // out of band data
  1029. function Handler_iq_jabber_iq_oob($packet)
  1030. {
  1031. $from = $this->GetInfoFromIqFrom($packet);
  1032. $id = $this->GetInfoFromIqId($packet);
  1033. $this->SendError($from, $id, 501);
  1034. $this->AddToLog("EVENT: jabber:iq:oob from $from");
  1035. }
  1036. // method to store private data on the server
  1037. function Handler_iq_jabber_iq_private($packet)
  1038. {
  1039. $from = $this->GetInfoFromIqFrom($packet);
  1040. $id = $this->GetInfoFromIqId($packet);
  1041. $this->SendError($from, $id, 501);
  1042. $this->AddToLog("EVENT: jabber:iq:private from $from");
  1043. }
  1044. // method for interactive registration
  1045. function Handler_iq_jabber_iq_register($packet)
  1046. {
  1047. $from = $this->GetInfoFromIqFrom($packet);
  1048. $id = $this->GetInfoFromIqId($packet);
  1049. $this->SendError($from, $id, 501);
  1050. $this->AddToLog("EVENT: jabber:iq:register from $from");
  1051. }
  1052. // client roster management
  1053. function Handler_iq_jabber_iq_roster($packet)
  1054. {
  1055. $from = $this->GetInfoFromIqFrom($packet);
  1056. $id = $this->GetInfoFromIqId($packet);
  1057. $this->SendError($from, $id, 501);
  1058. $this->AddToLog("EVENT: jabber:iq:roster from $from");
  1059. }
  1060. // method for searching a user database
  1061. function Handler_iq_jabber_iq_search($packet)
  1062. {
  1063. $from = $this->GetInfoFromIqFrom($packet);
  1064. $id = $this->GetInfoFromIqId($packet);
  1065. $this->SendError($from, $id, 501);
  1066. $this->AddToLog("EVENT: jabber:iq:search from $from");
  1067. }
  1068. // method for requesting the current time
  1069. function Handler_iq_jabber_iq_time($packet)
  1070. {
  1071. $type = $this->GetInfoFromIqType($packet);
  1072. $from = $this->GetInfoFromIqFrom($packet);
  1073. $id = $this->GetInfoFromIqId($packet);
  1074. $id = ($id != "") ? $id : "time_" . time();
  1075. if ($type == 'get')
  1076. {
  1077. $payload = "<utc>" . gmdate("Ydm\TH:i:s") . "</utc>
  1078. <tz>" . date("T") . "</tz>
  1079. <display>" . date("Y/d/m h:i:s A") . "</display>";
  1080. $this->SendIq($from, 'result', $id, "jabber:iq:time", $payload);
  1081. }
  1082. $this->AddToLog("EVENT: jabber:iq:time (type $type) from $from");
  1083. }
  1084. // method for requesting version
  1085. function Handler_iq_jabber_iq_version($packet)
  1086. {
  1087. $type = $this->GetInfoFromIqType($packet);
  1088. $from = $this->GetInfoFromIqFrom($packet);
  1089. $id = $this->GetInfoFromIqId($packet);
  1090. $id = ($id != "") ? $id : "version_" . time();
  1091. if ($type == 'get')
  1092. {
  1093. $payload = "<name>{$this->iq_version_name}</name>
  1094. <os>{$this->iq_version_os}</os>
  1095. <version>{$this->iq_version_version}</version>";
  1096. $this->SendIq($from, 'result', $id, "jabber:iq:version", $payload);
  1097. }
  1098. $this->AddToLog("EVENT: jabber:iq:version (type $type) from $from");
  1099. }
  1100. // keepalive method, added by Nathan Fritz
  1101. function Handler_iq_($packet)
  1102. {
  1103. if ($this->keep_alive_id == $this->GetInfoFromIqId($packet))
  1104. {
  1105. $this->returned_keep_alive = TRUE;
  1106. $this->AddToLog('EVENT: Keep-Alive returned, connection alive.');
  1107. }
  1108. }
  1109. // ======================================================================
  1110. // <presence/> handlers
  1111. // ======================================================================
  1112. function Handler_presence_available($packet)
  1113. {
  1114. $from = $this->GetInfoFromPresenceFrom($packet);
  1115. $show_status = $this->GetInfoFromPresenceStatus($packet) . " / " . $this->GetInfoFromPresenceShow($packet);
  1116. $show_status = ($show_status != " / ") ? " ($addendum)" : '';
  1117. $this->AddToLog("EVENT: Presence (type: available) - $from is available $show_status");
  1118. }
  1119. function Handler_presence_unavailable($packet)
  1120. {
  1121. $from = $this->GetInfoFromPresenceFrom($packet);
  1122. $show_status = $this->GetInfoFromPresenceStatus($packet) . " / " . $this->GetInfoFromPresenceShow($packet);
  1123. $show_status = ($show_status != " / ") ? " ($addendum)" : '';
  1124. $this->AddToLog("EVENT: Presence (type: unavailable) - $from is unavailable $show_status");
  1125. }
  1126. function Handler_presence_subscribe($packet)
  1127. {
  1128. $from = $this->GetInfoFromPresenceFrom($packet);
  1129. $this->SubscriptionAcceptRequest($from);
  1130. $this->RosterUpdate();
  1131. $this->log_array[] = "<b>Presence:</b> (type: subscribe) - Subscription request from $from, was added to \$this->subscription_queue, roster updated";
  1132. }
  1133. function Handler_presence_subscribed($packet)
  1134. {
  1135. $from = $this->GetInfoFromPresenceFrom($packet);
  1136. $this->RosterUpdate();
  1137. $this->AddToLog("EVENT: Presence (type: subscribed) - Subscription allowed by $from, roster updated");
  1138. }
  1139. function Handler_presence_unsubscribe($packet)
  1140. {
  1141. $from = $this->GetInfoFromPresenceFrom($packet);
  1142. $this->SendPresence("unsubscribed", $from);
  1143. $this->RosterUpdate();
  1144. $this->AddToLog("EVENT: Presence (type: unsubscribe) - Request to unsubscribe from $from, was automatically approved, roster updated");
  1145. }
  1146. function Handler_presence_unsubscribed($packet)
  1147. {
  1148. $from = $this->GetInfoFromPresenceFrom($packet);
  1149. $this->RosterUpdate();
  1150. $this->AddToLog("EVENT: Presence (type: unsubscribed) - Unsubscribed from $from's presence");
  1151. }
  1152. // Added By Nathan Fritz
  1153. function Handler_presence_error($packet)
  1154. {
  1155. $from = $this->GetInfoFromPresenceFrom($packet);
  1156. $this->AddToLog("EVENT: Presence (type: error) - Error in $from's presence");
  1157. }
  1158. // ======================================================================
  1159. // Generic handlers
  1160. // ======================================================================
  1161. // Generic handler for unsupported requests
  1162. function Handler_NOT_IMPLEMENTED($packet)
  1163. {
  1164. $packet_type = $this->_get_packet_type($packet);
  1165. $from = call_user_func(array(&$this, "GetInfoFrom" . ucfirst($packet_type) . "From"), $packet);
  1166. $id = call_user_func(array(&$this, "GetInfoFrom" . ucfirst($packet_type) . "Id"), $packet);
  1167. $this->SendError($from, $id, 501);
  1168. $this->AddToLog("EVENT: Unrecognized <$packet_type/> from $from");
  1169. }
  1170. // ======================================================================
  1171. // Third party code
  1172. // m@d pr0ps to the coders ;)
  1173. // ======================================================================
  1174. // xmlize()
  1175. // (c) Hans Anderson / http://www.hansanderson.com/php/xml/
  1176. function xmlize($data)
  1177. {
  1178. $vals = $index = $array = array();
  1179. $parser = xml_parser_create();
  1180. xml_parser_set_option($parser, XML_OPTION_CASE_FOLDING, 0);
  1181. xml_parser_set_option($parser, XML_OPTION_SKIP_WHITE, 1);
  1182. xml_parse_into_struct($parser, $data, $vals, $index);
  1183. xml_parser_free($parser);
  1184. $i = 0;
  1185. $tagname = $vals[$i]['tag'];
  1186. $array[$tagname]['@'] = $vals[$i]['attributes'];
  1187. $array[$tagname]['#'] = $this->_xml_depth($vals, $i);
  1188. return $array;
  1189. }
  1190. // _xml_depth()
  1191. // (c) Hans Anderson / http://www.hansanderson.com/php/xml/
  1192. function _xml_depth($vals, &$i)
  1193. {
  1194. $children = array();
  1195. if ($vals[$i]['value'])
  1196. {
  1197. array_push($children, trim($vals[$i]['value']));
  1198. }
  1199. while (++$i < count($vals))
  1200. {
  1201. switch ($vals[$i]['type'])
  1202. {
  1203. case 'cdata':
  1204. array_push($children, trim($vals[$i]['value']));
  1205. break;
  1206. case 'complete':
  1207. $tagname = $vals[$i]['tag'];
  1208. $size = sizeof($children[$tagname]);
  1209. $children[$tagname][$size]['#'] = trim($vals[$i]['value']);
  1210. if ($vals[$i]['attributes'])
  1211. {
  1212. $children[$tagname][$size]['@'] = $vals[$i]['attributes'];
  1213. }
  1214. break;
  1215. case 'open':
  1216. $tagname = $vals[$i]['tag'];
  1217. $size = sizeof($children[$tagname]);
  1218. if ($vals[$i]['attributes'])
  1219. {
  1220. $children[$tagname][$size]['@'] = $vals[$i]['attributes'];
  1221. $children[$tagname][$size]['#'] = $this->_xml_depth($vals, $i);
  1222. }
  1223. else
  1224. {
  1225. $children[$tagname][$size]['#'] = $this->_xml_depth($vals, $i);
  1226. }
  1227. break;
  1228. case 'close':
  1229. return $children;
  1230. break;
  1231. }
  1232. }
  1233. return $children;
  1234. }
  1235. // TraverseXMLize()
  1236. // (c) acebone@f2s.com, a HUGE help!
  1237. function TraverseXMLize($array, $arrName = "array", $level = 0)
  1238. {
  1239. if ($level == 0)
  1240. {
  1241. echo "<pre>";
  1242. }
  1243. while (list($key, $val) = @each($array))
  1244. {
  1245. if (is_array($val))
  1246. {
  1247. $this->TraverseXMLize($val, $arrName . "[" . $key . "]", $level + 1);
  1248. }
  1249. else
  1250. {
  1251. echo '$' . $arrName . '[' . $key . '] = "' . $val . "\"\n";
  1252. }
  1253. }
  1254. if ($level == 0)
  1255. {
  1256. echo "</pre>";
  1257. }
  1258. }
  1259. }
  1260. class MakeXML extends Jabber
  1261. {
  1262. var $nodes;
  1263. function MakeXML()
  1264. {
  1265. $nodes = array();
  1266. }
  1267. function AddPacketDetails($string, $value = NULL)
  1268. {
  1269. if (preg_match("/\(([0-9]*)\)$/i", $string))
  1270. {
  1271. $string .= "/[\"#\"]";
  1272. }
  1273. $temp = @explode("/", $string);
  1274. for ($a = 0; $a < count($temp); $a++)
  1275. {
  1276. $temp[$a] = preg_replace("/^[@]{1}([a-z0-9_]*)$/i", "[\"@\"][\"\\1\"]", $temp[$a]);
  1277. $temp[$a] = preg_replace("/^([a-z0-9_]*)\(([0-9]*)\)$/i", "[\"\\1\"][\\2]", $temp[$a]);
  1278. $temp[$a] = preg_replace("/^([a-z0-9_]*)$/i", "[\"\\1\"]", $temp[$a]);
  1279. }
  1280. $node = implode("", $temp);
  1281. // Yeahyeahyeah, I know it's ugly... get over it. ;)
  1282. echo "\$this->nodes$node = \"" . htmlspecialchars($value) . "\";<br/>";
  1283. eval("\$this->nodes$node = \"" . htmlspecialchars($value) . "\";");
  1284. }
  1285. function BuildPacket($array = NULL)
  1286. {
  1287. if (!$array)
  1288. {
  1289. $array = $this->nodes;
  1290. }
  1291. if (is_array($array))
  1292. {
  1293. array_multisort($array, SORT_ASC, SORT_STRING);
  1294. foreach ($array as $key => $value)
  1295. {
  1296. if (is_array($value) && $key == "@")
  1297. {
  1298. foreach ($value as $subkey => $subvalue)
  1299. {
  1300. $subvalue = htmlspecialchars($subvalue);
  1301. $text .= " $subkey='$subvalue'";
  1302. }
  1303. $text .= ">\n";
  1304. }
  1305. elseif ($key == "#")
  1306. {
  1307. $text .= htmlspecialchars($value);
  1308. }
  1309. elseif (is_array($value))
  1310. {
  1311. for ($a = 0; $a < count($value); $a++)
  1312. {
  1313. $text .= "<$key";
  1314. if (!$this->_preg_grep_keys("/^@/", $value[$a]))
  1315. {
  1316. $text .= ">";
  1317. }
  1318. $text .= $this->BuildPacket($value[$a]);
  1319. $text .= "</$key>\n";
  1320. }
  1321. }
  1322. else
  1323. {
  1324. $value = htmlspecialchars($value);
  1325. $text .= "<$key>$value</$key>\n";
  1326. }
  1327. }
  1328. return $text;
  1329. }
  1330. }
  1331. function _preg_grep_keys($pattern, $array)
  1332. {
  1333. while (list($key, $val) = each($array))
  1334. {
  1335. if (preg_match($pattern, $key))
  1336. {
  1337. $newarray[$key] = $val;
  1338. }
  1339. }
  1340. return (is_array($newarray)) ? $newarray : FALSE;
  1341. }
  1342. }
  1343. class CJP_StandardConnector
  1344. {
  1345. var $active_socket;
  1346. function OpenSocket($server, $port)
  1347. {
  1348. if ($this->active_socket = fsockopen($server, $port))
  1349. {
  1350. socket_set_blocking($this->active_socket, 0);
  1351. socket_set_timeout($this->active_socket, 31536000);
  1352. return TRUE;
  1353. }
  1354. else
  1355. {
  1356. return FALSE;
  1357. }
  1358. }
  1359. function CloseSocket()
  1360. {
  1361. return fclose($this->active_socket);
  1362. }
  1363. function WriteToSocket($data)
  1364. {
  1365. return fwrite($this->active_socket, $data);
  1366. }
  1367. function ReadFromSocket($chunksize)
  1368. {
  1369. set_magic_quotes_runtime(0);
  1370. $buffer = fread($this->active_socket, $chunksize);
  1371. set_magic_quotes_runtime(get_magic_quotes_gpc());
  1372. return $buffer;
  1373. }
  1374. }
  1375. ?>