/*\r
\r
phpmsnclass ver 2.0s\r
+Luke Fitzgerald <lw.fitzgerald@googlemail.com>\r
\r
Based on MSN class ver 2.0 by Tommy Wu, Ricky Su\r
License: GPL\r
This class uses MSNP15.\r
\r
In addition to PHP5, the additional php modules required are:\r
-curl pcre mhash mcrypt bcmath\r
+curl pcre mcrypt bcmath\r
\r
*/\r
\r
const PROD_KEY = 'PK}_A_0N_K%O?A9S';\r
const PROD_ID = 'PROD0114ES4Z%Q5W';\r
const LOGIN_METHOD = 'SSO';\r
- \r
+\r
const OIM_SEND_URL = 'https://ows.messenger.msn.com/OimWS/oim.asmx';\r
const OIM_SEND_SOAP = 'http://messenger.live.com/ws/2006/09/oim/Store2';\r
- \r
+\r
const OIM_MAILDATA_URL = 'https://rsi.hotmail.com/rsi/rsi.asmx';\r
const OIM_MAILDATA_SOAP = 'http://www.hotmail.msn.com/ws/2004/09/oim/rsi/GetMetadata';\r
const OIM_READ_URL = 'https://rsi.hotmail.com/rsi/rsi.asmx';\r
\r
const DELMEMBER_URL = 'https://contacts.msn.com/abservice/SharingService.asmx';\r
const DELMEMBER_SOAP = 'http://www.msn.com/webservices/AddressBook/DeleteMember';\r
- \r
+\r
+ // the message length (include header) is limited (maybe since WLM 8.5 released)\r
+ // for WLM: 1664 bytes\r
+ // for YIM: 518 bytes\r
+ const MAX_MSN_MESSAGE_LEN = 1664;\r
+ const MAX_YAHOO_MESSAGE_LEN = 518;\r
+\r
private $debug;\r
private $timeout;\r
- \r
+\r
private $id;\r
private $ticket;\r
private $user = '';\r
private $port = 1863;\r
\r
private $clientid = '';\r
- \r
+\r
private $error = '';\r
\r
private $authed = false;\r
private $font_co = '333333';\r
private $font_ef = '';\r
\r
-\r
- // the message length (include header) is limited (maybe since WLM 8.5 released)\r
- // for WLM: 1664 bytes\r
- // for YIM: 518 bytes\r
- const max_msn_message_len = 1664;\r
- const max_yahoo_message_len = 518;\r
-\r
// Begin added for StatusNet\r
\r
private $aContactList = array();\r
// Check support\r
if (!function_exists('curl_init')) throw new Exception("curl module not found!\n");\r
if (!function_exists('preg_match')) throw new Exception("pcre module not found!\n");\r
- if (!function_exists('mhash')) throw new Exception("mhash module not found!\n");\r
if (!function_exists('mcrypt_cbc')) throw new Exception("mcrypt module not found!\n");\r
if (!function_exists('bcmod')) throw new Exception("bcmath module not found!\n");\r
\r
/**\r
* Signon methods\r
*/\r
- \r
+\r
/**\r
* Connect to the NS server\r
*\r
// NS: >> VER {id} MSNP9 CVR0\r
// MSNP15\r
// NS: >>> VER {id} MSNP15 CVR0\r
- $this->ns_writeln("VER $this->id ".PROTOCOL.' CVR0');\r
+ $this->ns_writeln("VER $this->id ".self::PROTOCOL.' CVR0');\r
\r
$start_tm = time();\r
- while (!socketcheck($this->NSfp)) {\r
+ while (!self::socketcheck($this->NSfp)) {\r
$data = $this->ns_readln();\r
// no data?\r
if ($data === false) {\r
// MSNP15\r
// NS: <<< VER {id} MSNP15 CVR0\r
// NS: >>> CVR {id} 0x0409 winnt 5.1 i386 MSMSGS 8.1.0178 msmsgs {user}\r
- $this->ns_writeln("CVR $this->id 0x0409 winnt 5.1 i386 MSMSGS ".BUILDVER." msmsgs $user");\r
+ $this->ns_writeln("CVR $this->id 0x0409 winnt 5.1 i386 MSMSGS ".self::BUILDVER." msmsgs $user");\r
break;\r
\r
case 'CVR':\r
// MSNP15\r
// NS: <<< CVR {id} {ver_list} {download_serve} ....\r
// NS: >>> USR {id} SSO I {user}\r
- $this->ns_writeln("USR $this->id ".LOGIN_METHOD." I $user");\r
+ $this->ns_writeln("USR $this->id ".self::LOGIN_METHOD." I $user");\r
break;\r
\r
case 'USR':\r
$this->user = $user;\r
$this->password = $password;\r
// NS: <<< USR {id} SSO S {policy} {nonce}\r
- @list(/* USR */, /* id */, /* SSO */, /* S */, $policy, $nonce,) = @explode(' ', $data);\r
+ @list(/* USR */, /* id */, /* SSO */, /* S */, $policy, $nonce) = @explode(' ', $data);\r
\r
$this->passport_policy = $policy;\r
$aTickets = $this->get_passport_ticket();\r
// NS: >>> OUT\r
$this->ns_writeln("OUT");\r
@fclose($this->NSfp);\r
- $this->error = 'Passport authenticated fail!';\r
+ $this->error = 'Passport authentication failed!';\r
return false;\r
}\r
\r
$login_code = $this->generateLoginBLOB($secret, $nonce);\r
\r
// NS: >>> USR {id} SSO S {ticket} {login_code}\r
- $this->ns_writeln("USR $this->id ".LOGIN_METHOD." S $ticket $login_code");\r
+ $this->ns_writeln("USR $this->id ".self::LOGIN_METHOD." S $ticket $login_code");\r
$this->authed = true;\r
break;\r
\r
// NS: <<< XFR {id} NS {server} 0 {server}\r
// MSNP15\r
// NS: <<< XFR {id} NS {server} U D\r
- @list(/* XFR */, /* id */, $Type, $server, /* ... */) = @explode(' ', $data);\r
+ @list(/* XFR */, /* id */, $Type, $server) = @explode(' ', $data);\r
if ($Type!='NS') break;\r
@list($ip, $port) = @explode(':', $server);\r
// this connection will close after XFR\r
// NS: >> VER {id} MSNP9 CVR0\r
// MSNP15\r
// NS: >>> VER {id} MSNP15 CVR0\r
- $this->ns_writeln("VER $this->id ".PROTOCOL.' CVR0');\r
+ $this->ns_writeln("VER $this->id ".self::PROTOCOL.' CVR0');\r
break;\r
\r
case 'GCF':\r
// return some policy data after 'USR {id} SSO I {user}' command\r
// NS: <<< GCF 0 {size}\r
- @list(/* GCF */, /* 0 */, $size,) = @explode(' ', $data);\r
+ @list(/* GCF */, /* 0 */, $size) = @explode(' ', $data);\r
// we don't need the data, just read it and drop\r
if (is_numeric($size) && $size > 0)\r
$this->ns_readdata($size);\r
* the queue handler! */\r
$this->debug_message('*** Trying to connect to MSN network');\r
\r
+ // Remove any remaining switchboard sessions\r
+ $this->switchBoardSessions = array();\r
+ $this->switchBoardSessionLookup = array();\r
+\r
while (true) {\r
// Connect\r
if (!$this->connect($this->user, $this->password)) {\r
}\r
\r
// Update contacts\r
- if ($this->UpdateContacts() === false) continue;\r
+ if ($this->UpdateContacts() === false) {\r
+ $this->signonFailure('');\r
+ continue;\r
+ }\r
\r
// Get membership lists\r
if (($this->aContactList = $this->getMembershipList()) === false) {\r
$len = strlen($str);\r
$this->ns_writeln("UUX $this->id $len");\r
$this->ns_writedata($str);\r
- if (!socketcheck($this->NSfp)) {\r
+ if (!self::socketcheck($this->NSfp)) {\r
$this->debug_message('*** Connected, waiting for commands');\r
break;\r
} else {\r
* @return void\r
*/\r
private function signonFailure($message) {\r
- $this->debug_message($message);\r
- $this->callHandler('ConnectFailed');\r
+ if(!empty($message)) {\r
+ $this->debug_message($message);\r
+ }\r
+ $this->callHandler('ConnectFailed', $message);\r
$this->NSRetryWait($this->retry_wait);\r
}\r
\r
/**\r
* NS and SB command handling methods\r
*/\r
- \r
+\r
/**\r
* Read and handle incoming command from NS\r
*\r
*/\r
private function nsReceive() {\r
// Sign in again if not signed in or socket failed\r
- if (!is_resource($this->NSfp) || socketcheck($this->NSfp)) {\r
+ if (!is_resource($this->NSfp) || self::socketcheck($this->NSfp)) {\r
$this->callHandler('Reconnect');\r
$this->NSRetryWait($this->retry_wait);\r
$this->signon();\r
$this->NSRetryWait($this->retry_wait);\r
$this->signon();\r
return;\r
- } else {\r
- switch (substr($data, 0, 3)) {\r
- case 'SBS':\r
- // after 'USR {id} OK {user} {verify} 0' response, the server will send SBS and profile to us\r
- // NS: <<< SBS 0 null\r
- break;\r
+ }\r
\r
- case 'RFS':\r
- // FIXME:\r
- // NS: <<< RFS ???\r
- // refresh ADL, so we re-send it again\r
- if (is_array($this->aADL)) {\r
- foreach ($this->aADL as $str) {\r
- $len = strlen($str);\r
- // NS: >>> ADL {id} {size}\r
- $this->ns_writeln("ADL $this->id $len");\r
- $this->ns_writedata($str);\r
- }\r
- }\r
- break;\r
+ switch (substr($data, 0, 3)) {\r
+ case 'SBS':\r
+ // after 'USR {id} OK {user} {verify} 0' response, the server will send SBS and profile to us\r
+ // NS: <<< SBS 0 null\r
+ break;\r
\r
- case 'LST':\r
- // NS: <<< LST {email} {alias} 11 0\r
- @list(/* LST */, $email, /* alias */,) = @explode(' ', $data);\r
- @list($u_name, $u_domain) = @explode('@', $email);\r
- if (!isset($this->aContactList[$u_domain][$u_name][1])) {\r
- $this->aContactList[$u_domain][$u_name][1]['Allow'] = 'Allow';\r
- $this->debug_message("*** Added to contact list: $u_name@$u_domain");\r
+ case 'RFS':\r
+ // FIXME:\r
+ // NS: <<< RFS ???\r
+ // refresh ADL, so we re-send it again\r
+ if (is_array($this->aADL)) {\r
+ foreach ($this->aADL as $str) {\r
+ $len = strlen($str);\r
+ // NS: >>> ADL {id} {size}\r
+ $this->ns_writeln("ADL $this->id $len");\r
+ $this->ns_writedata($str);\r
}\r
- break;\r
+ }\r
+ break;\r
+\r
+ case 'LST':\r
+ // NS: <<< LST {email} {alias} 11 0\r
+ @list(/* LST */, $email) = @explode(' ', $data);\r
+ @list($u_name, $u_domain) = @explode('@', $email);\r
+ if (!isset($this->aContactList[$u_domain][$u_name][1])) {\r
+ $this->aContactList[$u_domain][$u_name][1]['Allow'] = 'Allow';\r
+ $this->debug_message("*** Added to contact list: $u_name@$u_domain");\r
+ }\r
+ break;\r
\r
- case 'ADL':\r
- // randomly, we get ADL command, someone add us to their contact list for MSNP15\r
- // NS: <<< ADL 0 {size}\r
- @list(/* ADL */, /* 0 */, $size,) = @explode(' ', $data);\r
- if (is_numeric($size) && $size > 0) {\r
- $data = $this->ns_readdata($size);\r
- preg_match('#<ml><d n="([^"]+)"><c n="([^"]+)"(.*) t="(\d*)"(.*) /></d></ml>#', $data, $matches);\r
- if (is_array($matches) && count($matches) > 0) {\r
- $u_domain = $matches[1];\r
- $u_name = $matches[2];\r
- $network = $matches[4];\r
- if (isset($this->aContactList[$u_domain][$u_name][$network]))\r
- $this->debug_message("*** Someone (network: $network) added us to their list (but already in our list): $u_name@$u_domain");\r
- else {\r
- $re_login = false;\r
- $cnt = 0;\r
- foreach (array('Allow', 'Reverse') as $list) {\r
+ case 'ADL':\r
+ // randomly, we get ADL command, someone add us to their contact list for MSNP15\r
+ // NS: <<< ADL 0 {size}\r
+ @list(/* ADL */, /* 0 */, $size) = @explode(' ', $data);\r
+ if (is_numeric($size) && $size > 0) {\r
+ $data = $this->ns_readdata($size);\r
+ preg_match('#<ml><d n="([^"]+)"><c n="([^"]+)"(.*) t="(\d*)"(.*) /></d></ml>#', $data, $matches);\r
+ if (is_array($matches) && count($matches) > 0) {\r
+ $u_domain = $matches[1];\r
+ $u_name = $matches[2];\r
+ $network = $matches[4];\r
+ if (isset($this->aContactList[$u_domain][$u_name][$network]))\r
+ $this->debug_message("*** Someone (network: $network) added us to their list (but already in our list): $u_name@$u_domain");\r
+ else {\r
+ $re_login = false;\r
+ $cnt = 0;\r
+ foreach (array('Allow', 'Reverse') as $list) {\r
+ if (!$this->addMemberToList($u_name.'@'.$u_domain, $network, $list)) {\r
+ if ($re_login) {\r
+ $this->debug_message("*** Could not add $u_name@$u_domain (network: $network) to $list list");\r
+ continue;\r
+ }\r
+ $aTickets = $this->get_passport_ticket();\r
+ if (!$aTickets || !is_array($aTickets)) {\r
+ // failed to login? ignore it\r
+ $this->debug_message("*** Could not re-login, something wrong here");\r
+ $this->debug_message("*** Could not add $u_name@$u_domain (network: $network) to $list list");\r
+ continue;\r
+ }\r
+ $re_login = true;\r
+ $this->ticket = $aTickets;\r
+ $this->debug_message("**** Got new ticket, trying again");\r
if (!$this->addMemberToList($u_name.'@'.$u_domain, $network, $list)) {\r
- if ($re_login) {\r
- $this->debug_message("*** Could not add $u_name@$u_domain (network: $network) to $list list");\r
- continue;\r
- }\r
- $aTickets = $this->get_passport_ticket();\r
- if (!$aTickets || !is_array($aTickets)) {\r
- // failed to login? ignore it\r
- $this->debug_message("*** Could not re-login, something wrong here");\r
- $this->debug_message("*** Could not add $u_name@$u_domain (network: $network) to $list list");\r
- continue;\r
- }\r
- $re_login = true;\r
- $this->ticket = $aTickets;\r
- $this->debug_message("**** Got new ticket, trying again");\r
- if (!$this->addMemberToList($u_name.'@'.$u_domain, $network, $list)) {\r
- $this->debug_message("*** Could not add $u_name@$u_domain (network: $network) to $list list");\r
- continue;\r
- }\r
+ $this->debug_message("*** Could not add $u_name@$u_domain (network: $network) to $list list");\r
+ continue;\r
}\r
- $this->aContactList[$u_domain][$u_name][$network][$list] = false;\r
- $cnt++;\r
}\r
- $this->debug_message("*** Someone (network: $network) added us to their list: $u_name@$u_domain");\r
+ $this->aContactList[$u_domain][$u_name][$network][$list] = false;\r
+ $cnt++;\r
}\r
- $str = '<ml l="1"><d n="'.$u_domain.'"><c n="'.$u_name.'" l="3" t="'.$network.'" /></d></ml>';\r
- $len = strlen($str);\r
-\r
- $this->callHandler('AddedToList', array('screenname' => $u_name.'@'.$u_domain, 'network' => $network));\r
+ $this->debug_message("*** Someone (network: $network) added us to their list: $u_name@$u_domain");\r
}\r
- else\r
- $this->debug_message("*** Someone added us to their list: $data");\r
- }\r
- break;\r
+ $str = '<ml l="1"><d n="'.$u_domain.'"><c n="'.$u_name.'" l="3" t="'.$network.'" /></d></ml>';\r
+ $len = strlen($str);\r
\r
- case 'RML':\r
- // randomly, we get RML command, someome remove us to their contact list for MSNP15\r
- // NS: <<< RML 0 {size}\r
- @list(/* RML */, /* 0 */, $size,) = @explode(' ', $data);\r
- if (is_numeric($size) && $size > 0) {\r
- $data = $this->ns_readdata($size);\r
- preg_match('#<ml><d n="([^"]+)"><c n="([^"]+)"(.*) t="(\d*)"(.*) /></d></ml>#', $data, $matches);\r
- if (is_array($matches) && count($matches) > 0) {\r
- $u_domain = $matches[1];\r
- $u_name = $matches[2];\r
- $network = $matches[4];\r
- if (isset($this->aContactList[$u_domain][$u_name][$network])) {\r
- $aData = $this->aContactList[$u_domain][$u_name][$network];\r
-\r
- foreach ($aData as $list => $id)\r
- $this->delMemberFromList($id, $u_name.'@'.$u_domain, $network, $list);\r
-\r
- unset($this->aContactList[$u_domain][$u_name][$network]);\r
- $this->debug_message("*** Someone (network: $network) removed us from their list: $u_name@$u_domain");\r
- }\r
- else\r
- $this->debug_message("*** Someone (network: $network) removed us from their list (but not in our list): $u_name@$u_domain");\r
+ $this->callHandler('AddedToList', array('screenname' => $u_name.'@'.$u_domain, 'network' => $network));\r
+ }\r
+ else\r
+ $this->debug_message("*** Someone added us to their list: $data");\r
+ }\r
+ break;\r
\r
- $this->callHandler('RemovedFromList', array('screenname' => $u_name.'@'.$u_domain, 'network' => $network));\r
+ case 'RML':\r
+ // randomly, we get RML command, someome remove us to their contact list for MSNP15\r
+ // NS: <<< RML 0 {size}\r
+ @list(/* RML */, /* 0 */, $size) = @explode(' ', $data);\r
+ if (is_numeric($size) && $size > 0) {\r
+ $data = $this->ns_readdata($size);\r
+ preg_match('#<ml><d n="([^"]+)"><c n="([^"]+)"(.*) t="(\d*)"(.*) /></d></ml>#', $data, $matches);\r
+ if (is_array($matches) && count($matches) > 0) {\r
+ $u_domain = $matches[1];\r
+ $u_name = $matches[2];\r
+ $network = $matches[4];\r
+ if (isset($this->aContactList[$u_domain][$u_name][$network])) {\r
+ $aData = $this->aContactList[$u_domain][$u_name][$network];\r
+\r
+ foreach ($aData as $list => $id)\r
+ $this->delMemberFromList($id, $u_name.'@'.$u_domain, $network, $list);\r
+\r
+ unset($this->aContactList[$u_domain][$u_name][$network]);\r
+ $this->debug_message("*** Someone (network: $network) removed us from their list: $u_name@$u_domain");\r
}\r
else\r
- $this->debug_message("*** Someone removed us from their list: $data");\r
+ $this->debug_message("*** Someone (network: $network) removed us from their list (but not in our list): $u_name@$u_domain");\r
+\r
+ $this->callHandler('RemovedFromList', array('screenname' => $u_name.'@'.$u_domain, 'network' => $network));\r
}\r
- break;\r
+ else\r
+ $this->debug_message("*** Someone removed us from their list: $data");\r
+ }\r
+ break;\r
\r
- case 'MSG':\r
- // randomly, we get MSG notification from server\r
- // NS: <<< MSG Hotmail Hotmail {size}\r
- @list(/* MSG */, /* Hotmail */, /* Hotmail */, $size,) = @explode(' ', $data);\r
- if (is_numeric($size) && $size > 0) {\r
- $data = $this->ns_readdata($size);\r
- $aLines = @explode("\n", $data);\r
- $header = true;\r
- $ignore = false;\r
- $maildata = '';\r
- foreach ($aLines as $line) {\r
- $line = rtrim($line);\r
- if ($header) {\r
- if ($line === '') {\r
- $header = false;\r
- continue;\r
- }\r
- if (strncasecmp($line, 'Content-Type:', 13) == 0) {\r
- if (strpos($line, 'text/x-msmsgsinitialmdatanotification') === false && strpos($line, 'text/x-msmsgsoimnotification') === false) {\r
- // we just need text/x-msmsgsinitialmdatanotification\r
- // or text/x-msmsgsoimnotification\r
- $ignore = true;\r
- break;\r
- }\r
- }\r
+ case 'MSG':\r
+ // randomly, we get MSG notification from server\r
+ // NS: <<< MSG Hotmail Hotmail {size}\r
+ @list(/* MSG */, /* Hotmail */, /* Hotmail */, $size) = @explode(' ', $data);\r
+ if (is_numeric($size) && $size > 0) {\r
+ $data = $this->ns_readdata($size);\r
+ $aLines = @explode("\n", $data);\r
+ $header = true;\r
+ $ignore = false;\r
+ $maildata = '';\r
+ foreach ($aLines as $line) {\r
+ $line = rtrim($line);\r
+ if ($header) {\r
+ if ($line === '') {\r
+ $header = false;\r
continue;\r
}\r
- if (strncasecmp($line, 'Mail-Data:', 10) == 0) {\r
- $maildata = trim(substr($line, 10));\r
- break;\r
+ if (strncasecmp($line, 'Content-Type:', 13) == 0) {\r
+ if (strpos($line, 'text/x-msmsgsinitialmdatanotification') === false && strpos($line, 'text/x-msmsgsoimnotification') === false) {\r
+ // we just need text/x-msmsgsinitialmdatanotification\r
+ // or text/x-msmsgsoimnotification\r
+ $ignore = true;\r
+ break;\r
+ }\r
}\r
+ continue;\r
}\r
- if ($ignore) {\r
- $this->debug_message("*** Ignoring MSG for: $line");\r
- break;\r
- }\r
- if ($maildata == '') {\r
- $this->debug_message("*** Ignoring MSG not for OIM");\r
+ if (strncasecmp($line, 'Mail-Data:', 10) == 0) {\r
+ $maildata = trim(substr($line, 10));\r
break;\r
}\r
- $re_login = false;\r
- if (strcasecmp($maildata, 'too-large') == 0) {\r
- $this->debug_message("*** Large mail-data, need to get the data via SOAP");\r
+ }\r
+ if ($ignore) {\r
+ $this->debug_message("*** Ignoring MSG for: $line");\r
+ break;\r
+ }\r
+ if ($maildata == '') {\r
+ $this->debug_message("*** Ignoring MSG not for OIM");\r
+ break;\r
+ }\r
+ $re_login = false;\r
+ if (strcasecmp($maildata, 'too-large') == 0) {\r
+ $this->debug_message("*** Large mail-data, need to get the data via SOAP");\r
+ $maildata = $this->getOIM_maildata();\r
+ if ($maildata === false) {\r
+ $this->debug_message("*** Could not get mail-data via SOAP");\r
+\r
+ // maybe we need to re-login again\r
+ $aTickets = $this->get_passport_ticket();\r
+ if (!$aTickets || !is_array($aTickets)) {\r
+ // failed to login? ignore it\r
+ $this->debug_message("*** Could not re-login, something wrong here, ignoring this OIM");\r
+ break;\r
+ }\r
+ $re_login = true;\r
+ $this->ticket = $aTickets;\r
+ $this->debug_message("*** Got new ticket, trying again");\r
$maildata = $this->getOIM_maildata();\r
if ($maildata === false) {\r
- $this->debug_message("*** Could not get mail-data via SOAP");\r
-\r
- // maybe we need to re-login again\r
- $aTickets = $this->get_passport_ticket();\r
- if (!$aTickets || !is_array($aTickets)) {\r
- // failed to login? ignore it\r
- $this->debug_message("*** Could not re-login, something wrong here, ignoring this OIM");\r
- break;\r
- }\r
- $re_login = true;\r
- $this->ticket = $aTickets;\r
- $this->debug_message("*** Got new ticket, trying again");\r
- $maildata = $this->getOIM_maildata();\r
- if ($maildata === false) {\r
- $this->debug_message("*** Could not get mail-data via SOAP, and re-login already attempted, ignoring this OIM");\r
- break;\r
- }\r
+ $this->debug_message("*** Could not get mail-data via SOAP, and re-login already attempted, ignoring this OIM");\r
+ break;\r
}\r
}\r
- // could be a lots of <M>...</M>, so we can't use preg_match here\r
- $p = $maildata;\r
- $aOIMs = array();\r
- while (1) {\r
- $start = strpos($p, '<M>');\r
- $end = strpos($p, '</M>');\r
- if ($start === false || $end === false || $start > $end) break;\r
- $end += 4;\r
- $sOIM = substr($p, $start, $end - $start);\r
- $aOIMs[] = $sOIM;\r
- $p = substr($p, $end);\r
+ }\r
+ // could be a lots of <M>...</M>, so we can't use preg_match here\r
+ $p = $maildata;\r
+ $aOIMs = array();\r
+ while (1) {\r
+ $start = strpos($p, '<M>');\r
+ $end = strpos($p, '</M>');\r
+ if ($start === false || $end === false || $start > $end) break;\r
+ $end += 4;\r
+ $sOIM = substr($p, $start, $end - $start);\r
+ $aOIMs[] = $sOIM;\r
+ $p = substr($p, $end);\r
+ }\r
+ if (count($aOIMs) == 0) {\r
+ $this->debug_message("*** Ignoring empty OIM");\r
+ break;\r
+ }\r
+ foreach ($aOIMs as $maildata) {\r
+ // T: 11 for MSN, 13 for Yahoo\r
+ // S: 6 for MSN, 7 for Yahoo\r
+ // RT: the datetime received by server\r
+ // RS: already read or not\r
+ // SZ: size of message\r
+ // E: sender\r
+ // I: msgid\r
+ // F: always 00000000-0000-0000-0000-000000000009\r
+ // N: sender alias\r
+ preg_match('#<T>(.*)</T>#', $maildata, $matches);\r
+ if (count($matches) == 0) {\r
+ $this->debug_message("*** Ignoring OIM maildata without <T>type</T>");\r
+ continue;\r
}\r
- if (count($aOIMs) == 0) {\r
- $this->debug_message("*** Ignoring empty OIM");\r
- break;\r
+ $oim_type = $matches[1];\r
+ if ($oim_type = 13)\r
+ $network = 32;\r
+ else\r
+ $network = 1;\r
+ preg_match('#<E>(.*)</E>#', $maildata, $matches);\r
+ if (count($matches) == 0) {\r
+ $this->debug_message("*** Ignoring OIM maildata without <E>sender</E>");\r
+ continue;\r
}\r
- foreach ($aOIMs as $maildata) {\r
- // T: 11 for MSN, 13 for Yahoo\r
- // S: 6 for MSN, 7 for Yahoo\r
- // RT: the datetime received by server\r
- // RS: already read or not\r
- // SZ: size of message\r
- // E: sender\r
- // I: msgid\r
- // F: always 00000000-0000-0000-0000-000000000009\r
- // N: sender alias\r
- preg_match('#<T>(.*)</T>#', $maildata, $matches);\r
- if (count($matches) == 0) {\r
- $this->debug_message("*** Ignoring OIM maildata without <T>type</T>");\r
- continue;\r
- }\r
- $oim_type = $matches[1];\r
- if ($oim_type = 13)\r
- $network = 32;\r
- else\r
- $network = 1;\r
- preg_match('#<E>(.*)</E>#', $maildata, $matches);\r
- if (count($matches) == 0) {\r
- $this->debug_message("*** Ignoring OIM maildata without <E>sender</E>");\r
+ $oim_sender = $matches[1];\r
+ preg_match('#<I>(.*)</I>#', $maildata, $matches);\r
+ if (count($matches) == 0) {\r
+ $this->debug_message("*** Ignoring OIM maildata without <I>msgid</I>");\r
+ continue;\r
+ }\r
+ $oim_msgid = $matches[1];\r
+ preg_match('#<SZ>(.*)</SZ>#', $maildata, $matches);\r
+ $oim_size = (count($matches) == 0) ? 0 : $matches[1];\r
+ preg_match('#<RT>(.*)</RT>#', $maildata, $matches);\r
+ $oim_time = (count($matches) == 0) ? 0 : $matches[1];\r
+ $this->debug_message("*** OIM received from $oim_sender, Time: $oim_time, MSGID: $oim_msgid, size: $oim_size");\r
+ $sMsg = $this->getOIM_message($oim_msgid);\r
+ if ($sMsg === false) {\r
+ $this->debug_message("*** Could not get OIM, msgid = $oim_msgid");\r
+ if ($re_login) {\r
+ $this->debug_message("*** Could not get OIM via SOAP, and re-login already attempted, ignoring this OIM");\r
continue;\r
}\r
- $oim_sender = $matches[1];\r
- preg_match('#<I>(.*)</I>#', $maildata, $matches);\r
- if (count($matches) == 0) {\r
- $this->debug_message("*** Ignoring OIM maildata without <I>msgid</I>");\r
+ $aTickets = $this->get_passport_ticket();\r
+ if (!$aTickets || !is_array($aTickets)) {\r
+ // failed to login? ignore it\r
+ $this->debug_message("*** Could not re-login, something wrong here, ignoring this OIM");\r
continue;\r
}\r
- $oim_msgid = $matches[1];\r
- preg_match('#<SZ>(.*)</SZ>#', $maildata, $matches);\r
- $oim_size = (count($matches) == 0) ? 0 : $matches[1];\r
- preg_match('#<RT>(.*)</RT>#', $maildata, $matches);\r
- $oim_time = (count($matches) == 0) ? 0 : $matches[1];\r
- $this->debug_message("*** OIM received from $oim_sender, Time: $oim_time, MSGID: $oim_msgid, size: $oim_size");\r
+ $re_login = true;\r
+ $this->ticket = $aTickets;\r
+ $this->debug_message("*** get new ticket, try it again");\r
$sMsg = $this->getOIM_message($oim_msgid);\r
if ($sMsg === false) {\r
- $this->debug_message("*** Could not get OIM, msgid = $oim_msgid");\r
- if ($re_login) {\r
- $this->debug_message("*** Could not get OIM via SOAP, and re-login already attempted, ignoring this OIM");\r
- continue;\r
- }\r
- $aTickets = $this->get_passport_ticket();\r
- if (!$aTickets || !is_array($aTickets)) {\r
- // failed to login? ignore it\r
- $this->debug_message("*** Could not re-login, something wrong here, ignoring this OIM");\r
- continue;\r
- }\r
- $re_login = true;\r
- $this->ticket = $aTickets;\r
- $this->debug_message("*** get new ticket, try it again");\r
- $sMsg = $this->getOIM_message($oim_msgid);\r
- if ($sMsg === false) {\r
- $this->debug_message("*** Could not get OIM via SOAP, and re-login already attempted, ignoring this OIM");\r
- continue;\r
- }\r
+ $this->debug_message("*** Could not get OIM via SOAP, and re-login already attempted, ignoring this OIM");\r
+ continue;\r
}\r
- $this->debug_message("*** MSG (Offline) from $oim_sender (network: $network): $sMsg");\r
- $this->callHandler('IMin', array('sender' => $oim_sender, 'message' => $sMsg, 'network' => $network, 'offline' => true));\r
}\r
+ $this->debug_message("*** MSG (Offline) from $oim_sender (network: $network): $sMsg");\r
+ $this->callHandler('IMin', array('sender' => $oim_sender, 'message' => $sMsg, 'network' => $network, 'offline' => true));\r
}\r
- break;\r
+ }\r
+ break;\r
\r
- case 'UBM':\r
- // randomly, we get UBM, this is the message from other network, like Yahoo!\r
- // NS: <<< UBM {email} $network $type {size}\r
- @list(/* UBM */, $from_email, $network, $type, $size,) = @explode(' ', $data);\r
- if (is_numeric($size) && $size > 0) {\r
- $data = $this->ns_readdata($size);\r
- $aLines = @explode("\n", $data);\r
- $header = true;\r
- $ignore = false;\r
- $sMsg = '';\r
- foreach ($aLines as $line) {\r
- $line = rtrim($line);\r
- if ($header) {\r
- if ($line === '') {\r
- $header = false;\r
- continue;\r
- }\r
- if (strncasecmp($line, 'TypingUser:', 11) == 0) {\r
- $ignore = true;\r
- break;\r
- }\r
+ case 'UBM':\r
+ // randomly, we get UBM, this is the message from other network, like Yahoo!\r
+ // NS: <<< UBM {email} $network $type {size}\r
+ @list(/* UBM */, $from_email, $network, $type, $size) = @explode(' ', $data);\r
+ if (is_numeric($size) && $size > 0) {\r
+ $data = $this->ns_readdata($size);\r
+ $aLines = @explode("\n", $data);\r
+ $header = true;\r
+ $ignore = false;\r
+ $sMsg = '';\r
+ foreach ($aLines as $line) {\r
+ $line = rtrim($line);\r
+ if ($header) {\r
+ if ($line === '') {\r
+ $header = false;\r
continue;\r
}\r
- $aSubLines = @explode("\r", $line);\r
- foreach ($aSubLines as $str) {\r
- if ($sMsg !== '')\r
- $sMsg .= "\n";\r
- $sMsg .= $str;\r
+ if (strncasecmp($line, 'TypingUser:', 11) == 0) {\r
+ $ignore = true;\r
+ break;\r
}\r
+ continue;\r
}\r
- if ($ignore) {\r
- $this->debug_message("*** Ignoring message from $from_email: $line");\r
- break;\r
+ $aSubLines = @explode("\r", $line);\r
+ foreach ($aSubLines as $str) {\r
+ if ($sMsg !== '')\r
+ $sMsg .= "\n";\r
+ $sMsg .= $str;\r
}\r
- $this->debug_message("*** MSG from $from_email (network: $network): $sMsg");\r
- $this->callHandler('IMin', array('sender' => $from_email, 'message' => $sMsg, 'network' => $network, 'offline' => false));\r
}\r
- break;\r
+ if ($ignore) {\r
+ $this->debug_message("*** Ignoring message from $from_email: $line");\r
+ break;\r
+ }\r
+ $this->debug_message("*** MSG from $from_email (network: $network): $sMsg");\r
+ $this->callHandler('IMin', array('sender' => $from_email, 'message' => $sMsg, 'network' => $network, 'offline' => false));\r
+ }\r
+ break;\r
\r
- case 'UBX':\r
- // randomly, we get UBX notification from server\r
- // NS: <<< UBX email {network} {size}\r
- @list(/* UBX */, /* email */, /* network */, $size,) = @explode(' ', $data);\r
- // we don't need the notification data, so just ignore it\r
- if (is_numeric($size) && $size > 0)\r
- $this->ns_readdata($size);\r
- break;\r
+ case 'UBX':\r
+ // randomly, we get UBX notification from server\r
+ // NS: <<< UBX email {network} {size}\r
+ @list(/* UBX */, /* email */, /* network */, $size) = @explode(' ', $data);\r
+ // we don't need the notification data, so just ignore it\r
+ if (is_numeric($size) && $size > 0)\r
+ $this->ns_readdata($size);\r
+ break;\r
\r
- case 'CHL':\r
- // randomly, we'll get challenge from server\r
- // NS: <<< CHL 0 {code}\r
- @list(/* CHL */, /* 0 */, $chl_code,) = @explode(' ', $data);\r
- $fingerprint = $this->getChallenge($chl_code);\r
- // NS: >>> QRY {id} {product_id} 32\r
- // NS: >>> fingerprint\r
- $this->ns_writeln("QRY $this->id ".PROD_ID.' 32');\r
- $this->ns_writedata($fingerprint);\r
- $this->ns_writeln("CHG $this->id NLN $this->clientid");\r
- if ($this->PhotoStickerFile !== false)\r
- $this->ns_writeln("CHG $this->id NLN $this->clientid ".rawurlencode($this->MsnObj($this->PhotoStickerFile)));\r
- break;\r
- case 'CHG':\r
- // NS: <<< CHG {id} {status} {code}\r
- // ignore it\r
- // change our status to online first\r
- break;\r
+ case 'CHL':\r
+ // randomly, we'll get challenge from server\r
+ // NS: <<< CHL 0 {code}\r
+ @list(/* CHL */, /* 0 */, $chl_code) = @explode(' ', $data);\r
+ $fingerprint = $this->getChallenge($chl_code);\r
+ // NS: >>> QRY {id} {product_id} 32\r
+ // NS: >>> fingerprint\r
+ $this->ns_writeln("QRY $this->id ".self::PROD_ID.' 32');\r
+ $this->ns_writedata($fingerprint);\r
+ $this->ns_writeln("CHG $this->id NLN $this->clientid");\r
+ if ($this->PhotoStickerFile !== false)\r
+ $this->ns_writeln("CHG $this->id NLN $this->clientid ".rawurlencode($this->MsnObj($this->PhotoStickerFile)));\r
+ break;\r
+ case 'CHG':\r
+ // NS: <<< CHG {id} {status} {code}\r
+ // ignore it\r
+ // change our status to online first\r
+ break;\r
\r
- case 'XFR':\r
- // sometimes, NS will redirect to another NS\r
- // MSNP9\r
- // NS: <<< XFR {id} NS {server} 0 {server}\r
- // MSNP15\r
- // NS: <<< XFR {id} NS {server} U D\r
- // for normal switchboard XFR\r
- // NS: <<< XFR {id} SB {server} CKI {cki} U messenger.msn.com 0\r
- @list(/* XFR */, /* {id} */, $server_type, $server, /* CKI */, $cki_code, /* ... */) = @explode(' ', $data);\r
- @list($ip, $port) = @explode(':', $server);\r
- if ($server_type != 'SB') {\r
- // maybe exit?\r
- // this connection will close after XFR\r
- $this->nsLogout();\r
- continue;\r
- }\r
+ case 'XFR':\r
+ // sometimes, NS will redirect to another NS\r
+ // MSNP9\r
+ // NS: <<< XFR {id} NS {server} 0 {server}\r
+ // MSNP15\r
+ // NS: <<< XFR {id} NS {server} U D\r
+ // for normal switchboard XFR\r
+ // NS: <<< XFR {id} SB {server} CKI {cki} U messenger.msn.com 0\r
+ @list(/* XFR */, /* {id} */, $server_type, $server, /* CKI */, $cki_code) = @explode(' ', $data);\r
+ @list($ip, $port) = @explode(':', $server);\r
+ if ($server_type != 'SB') {\r
+ // maybe exit?\r
+ // this connection will close after XFR\r
+ $this->nsLogout();\r
+ continue;\r
+ }\r
\r
- $this->debug_message("NS: <<< XFR SB");\r
- $user = array_shift($this->waitingForXFR);\r
- $bSBresult = $this->switchboard_control($ip, $port, $cki_code, $User, $Message);\r
- /*\r
- $bSBresult = $this->switchboard_control($ip, $port, $cki_code, $aMSNUsers[$nCurrentUser], $sMessage);\r
- if ($bSBresult === false) {\r
- // error for switchboard\r
- $this->debug_message("!!! error for sending message to ".$aMSNUsers[$nCurrentUser]);\r
- $aOfflineUsers[] = $aMSNUsers[$nCurrentUser];\r
- }*/\r
- break;\r
- case 'QNG':\r
- // NS: <<< QNG {time}\r
- @list(/* QNG */, $ping_wait) = @explode(' ', $data);\r
- $this->callHandler('Pong', $ping_wait);\r
- break;\r
+ $this->debug_message("NS: <<< XFR SB");\r
+ $session = array_shift($this->waitingForXFR);\r
+ $this->connectToSBSession('Active', $ip, $port, $session['to'], array('cki' => $cki_code));\r
+ break;\r
+ case 'QNG':\r
+ // NS: <<< QNG {time}\r
+ @list(/* QNG */, $ping_wait) = @explode(' ', $data);\r
+ $this->callHandler('Pong', $ping_wait);\r
+ break;\r
\r
- case 'RNG':\r
- if ($this->PhotoStickerFile !== false)\r
- $this->ns_writeln("CHG $this->id NLN $this->clientid ".rawurlencode($this->MsnObj($this->PhotoStickerFile)));\r
- else\r
- $this->ns_writeln("CHG $this->id NLN $this->clientid");\r
- // someone is trying to talk to us\r
- // NS: <<< RNG {session_id} {server} {auth_type} {ticket} {email} {alias} U {client} 0\r
- $this->debug_message("NS: <<< RNG $data");\r
- @list(/* RNG */, $sid, $server, /* auth_type */, $ticket, $email, $name, ) = @explode(' ', $data);\r
- @list($sb_ip, $sb_port) = @explode(':', $server);\r
- $this->debug_message("*** RING from $email, $sb_ip:$sb_port");\r
- $this->addContact($email, 1, $email, true);\r
- $this->connectToSBSession('Passive', $sb_ip, $sb_port, $email, array('sid' => $sid, 'ticket' => $ticket));\r
- break;\r
- case 'OUT':\r
- // force logout from NS\r
- // NS: <<< OUT xxx\r
- $this->debug_message("*** LOGOUT from NS");\r
- return $this->nsLogout();\r
+ case 'RNG':\r
+ if ($this->PhotoStickerFile !== false)\r
+ $this->ns_writeln("CHG $this->id NLN $this->clientid ".rawurlencode($this->MsnObj($this->PhotoStickerFile)));\r
+ else\r
+ $this->ns_writeln("CHG $this->id NLN $this->clientid");\r
+ // someone is trying to talk to us\r
+ // NS: <<< RNG {session_id} {server} {auth_type} {ticket} {email} {alias} U {client} 0\r
+ $this->debug_message("NS: <<< RNG $data");\r
+ @list(/* RNG */, $sid, $server, /* auth_type */, $ticket, $email, $name) = @explode(' ', $data);\r
+ @list($sb_ip, $sb_port) = @explode(':', $server);\r
+ $this->debug_message("*** RING from $email, $sb_ip:$sb_port");\r
+ $this->addContact($email, 1, $email, true);\r
+ $this->connectToSBSession('Passive', $sb_ip, $sb_port, $email, array('sid' => $sid, 'ticket' => $ticket));\r
+ break;\r
\r
- default:\r
- $code = substr($data,0,3);\r
- if (is_numeric($code)) {\r
- $this->error = "Error code: $code, please check the detail information from: http://msnpiki.msnfanatic.com/index.php/Reference:Error_List";\r
- $this->debug_message("*** NS: $this->error");\r
+ case 'NLN':\r
+ // NS: <<< NLN {status} {email} {networkid} {nickname} {clientid} {dpobj}\r
+ @list(/* NLN */, $status, $email, $network, $nickname) = @explode(' ', $data);\r
+ $this->callHandler('StatusChange', array('screenname' => $email, 'status' => $status, 'network' => $network, 'nickname' => $nickname));\r
+ break;\r
\r
- return $this->nsLogout();\r
- }\r
- break;\r
- }\r
+ case 'OUT':\r
+ // force logout from NS\r
+ // NS: <<< OUT xxx\r
+ $this->debug_message("*** LOGOUT from NS");\r
+ return $this->nsLogout();\r
+\r
+ default:\r
+ $code = substr($data,0,3);\r
+ if (is_numeric($code)) {\r
+ $this->error = "Error code: $code, please check the detail information from: http://msnpiki.msnfanatic.com/index.php/Reference:Error_List";\r
+ $this->debug_message("*** NS: $this->error");\r
+\r
+ return $this->nsLogout();\r
+ }\r
+ break;\r
}\r
}\r
\r
// SB: <<< IRO {id} {rooster} {roostercount} {email} {alias} {clientid}\r
@list(/* IRO */, /* id */, $cur_num, $total, $email, $alias, $clientid) = @explode(' ', $data);\r
$this->debug_message("*** $email joined session");\r
- $session['joined'] = true;\r
+ if ($email == $session['to']) {\r
+ $session['joined'] = true;\r
+ $this->callHandler('SessionReady', array('to' => $email));\r
+ }\r
break;\r
case 'BYE':\r
$this->debug_message("*** Quit for BYE");\r
- $this->endSBSession();\r
+ $this->endSBSession($socket);\r
break;\r
case 'USR':\r
// SB: <<< USR {id} OK {user} {alias}\r
// we don't need the data, just ignore it\r
// request user to join this switchboard\r
// SB: >>> CAL {id} {user}\r
- $this->sb_writeln($socket, $id, "CAL $this->id $user");\r
+ $this->sb_writeln($socket, $id, "CAL $id ".$session['to']);\r
break;\r
case 'CAL':\r
// SB: <<< CAL {id} RINGING {?}\r
case 'JOI':\r
// SB: <<< JOI {user} {alias} {clientid?}\r
// someone join us\r
- // we don't need the data, just ignore it\r
- // no more user here\r
- $session['joined'] = true;\r
+ @list(/* JOI */, $email) = @explode(' ', $data);\r
+ if ($email == $session['to']) {\r
+ $session['joined'] = true;\r
+ $this->callHandler('SessionReady', array('to' => $email));\r
+ }\r
break;\r
case 'MSG':\r
// SB: <<< MSG {email} {alias} {len}\r
- @list(/* MSG */, $from_email, /* alias */, $len, ) = @explode(' ', $data);\r
+ @list(/* MSG */, $from_email, /* alias */, $len) = @explode(' ', $data);\r
$len = trim($len);\r
$data = $this->sb_readdata($socket, $len);\r
$aLines = @explode("\n", $data);\r
$footer = pack("L", 0);\r
$message = "MIME-Version: 1.0\r\nContent-Type: application/x-msnmsgrp2p\r\nP2P-Dest: $from_email\r\n\r\n$hdr$footer";\r
$len = strlen($message);\r
- $this->sb_writeln($socket, $id, "MSG $this->id D $len");\r
+ $this->sb_writeln($socket, $id, "MSG $id D $len");\r
$this->sb_writedata($socket, $message);\r
$this->debug_message("*** p2p: send display picture acknowledgement for $hdr_SessionID");\r
$this->debug_message("*** p2p: Invite ACK message:\n".$this->dump_binary($message));\r
"MIME-Version: 1.0\r\n".\r
"Content-Type: application/x-msnmsgrp2p\r\n".\r
"P2P-Dest: $from_email\r\n\r\n$hdr$MessagePayload$footer";\r
- $this->sb_writeln($socket, $id, "MSG $this->id D ".strlen($message));\r
+ $this->sb_writeln($socket, $id, "MSG $id D ".strlen($message));\r
$this->sb_writedata($socket, $message);\r
$this->debug_message("*** p2p: dump 200 ok message:\n".$this->dump_binary($message));\r
$this->sb_readln($socket); // Read ACK;\r
"MIME-Version: 1.0\r\n".\r
"Content-Type: application/x-msnmsgrp2p\r\n".\r
"P2P-Dest: $from_email\r\n\r\n$hdr".pack('L', 0)."$footer";\r
- $this->sb_writeln($socket, $id, "MSG $this->id D ".strlen($message));\r
+ $this->sb_writeln($socket, $id, "MSG $id D ".strlen($message));\r
$this->sb_writedata($socket, $message);\r
$this->debug_message("*** p2p: dump send Data preparation message:\n".$this->dump_binary($message));\r
$this->debug_message("*** p2p: Data Prepare Hdr:\n".$this->dump_binary($hdr));\r
"MIME-Version: 1.0\r\n".\r
"Content-Type: application/x-msnmsgrp2p\r\n".\r
"P2P-Dest: $from_email\r\n\r\n$hdr$FileContent$footer";\r
- $this->sb_writeln($socket, $id, "MSG $this->id D ".strlen($message));\r
+ $this->sb_writeln($socket, $id, "MSG $id D ".strlen($message));\r
$this->sb_writedata($socket, $message);\r
$this->debug_message("*** p2p: dump send Data Content message $Offset / $FileSize :\n".$this->dump_binary($message));\r
$this->debug_message("*** p2p: Data Content Hdr:\n".$this->dump_binary($hdr));\r
break;\r
}\r
$this->debug_message("*** MSG from $from_email: $sMsg");\r
- $this->callHandler('IMin', array('sender' => $from_email, 'message' => $sMsg, 'network' => $network, 'offline' => false));\r
+ $this->callHandler('IMin', array('sender' => $from_email, 'message' => $sMsg, 'network' => 1, 'offline' => false));\r
break;\r
case '217':\r
- $this->debug_message("*** User $user is offline. Trying OIM.");\r
+ $this->debug_message('*** User '.$session['to'].' is offline. Trying OIM.');\r
$session['offline'] = true;\r
break;\r
default:\r
if (is_numeric($code)) {\r
$this->error = "Error code: $code, please check the detail information from: http://msnpiki.msnfanatic.com/index.php/Reference:Error_List";\r
$this->debug_message("*** SB: $this->error");\r
- $sessionEnd=true;\r
}\r
break;\r
}\r
/**\r
* Switchboard related methods\r
*/\r
- \r
+\r
/**\r
* Send a request for a switchboard session\r
*\r
'offline' => false,\r
'XFRReqTime' => time()\r
);\r
- $this->waitingForXFR[] = &$this->switchBoardSessions[$to];\r
+ $this->waitingForXFR[$to] = &$this->switchBoardSessions[$to];\r
}\r
\r
/**\r
$this->switchBoardSessionLookup[$to] = $socket;\r
\r
// Store the socket in the sessions array\r
- $intsocket = (int) $socket;\r
$this->switchBoardSessions[$to] = array(\r
'to' => $to,\r
'socket' => $socket,\r
);\r
\r
// Change the index of the session to the socket\r
+ $intsocket = (int) $socket;\r
$this->switchBoardSessions[$intsocket] = $this->switchBoardSessions[$to];\r
unset($this->switchBoardSessions[$to]);\r
\r
$this->sb_writeln($socket, $id, "ANS $id $this->user $ticket $sid");\r
}\r
}\r
- \r
+\r
/**\r
* Called when we want to end a switchboard session\r
* or a switchboard session ends\r
* @param boolean $killsession Whether to delete the session\r
* @return void\r
*/\r
- private function endSBSession($socket, $killsession = false) {\r
- if (!socketcheck($socket)) {\r
+ private function endSBSession($socket) {\r
+ if (!self::socketcheck($socket)) {\r
$this->sb_writeln($socket, $fake = 0, 'OUT');\r
}\r
@fclose($socket);\r
*/\r
private function sendMessageViaSB($to, $message) {\r
$socket = $this->switchBoardSessionLookup[$to];\r
- if (socketcheck($socket)) {\r
- return false;\r
- }\r
-\r
- if (!$this->switchBoardSessions[$to]['joined']) {\r
- // If our participant has not joined the session yet we can't message them!\r
+ if (self::socketcheck($socket)) {\r
return false;\r
}\r
\r
- $intsocket = (int) $socket;\r
- $id = &$this->switchBoardSessions[$intsocket]['id'];\r
+ $id = &$this->switchBoardSessions[(int) $socket]['id'];\r
\r
- $aMessage = $this->getMessage($Message);\r
- //CheckEmotion...\r
- $MsnObjDefine=$this->GetMsnObjDefine($aMessage);\r
+ $aMessage = $this->getMessage($message);\r
+ // CheckEmotion...\r
+ $MsnObjDefine = $this->GetMsnObjDefine($aMessage);\r
if ($MsnObjDefine !== '') {\r
- $SendString="MIME-Version: 1.0\r\nContent-Type: text/x-mms-emoticon\r\n\r\n$MsnObjDefine";\r
+ $SendString = "MIME-Version: 1.0\r\nContent-Type: text/x-mms-emoticon\r\n\r\n$MsnObjDefine";\r
$len = strlen($SendString);\r
- // TODO handle failure during write to socket\r
- $this->sb_writeln($socket, $id, "MSG $id N $len");\r
- $this->sb_writedata($socket, $SendString);\r
+\r
+ if ($this->sb_writeln($socket, $id, "MSG $id N $len") === false ||\r
+ $this->sb_writedata($socket, $SendString) === false) {\r
+ $this->endSBSession($socket);\r
+ return false;\r
+ }\r
}\r
$len = strlen($aMessage);\r
- // TODO handle failure during write to socket\r
- $this->sb_writeln($socket, $id, "MSG $id N $len");\r
- $this->sb_writedata($socket, $aMessage);\r
\r
- // Don't close the SB session, we might as well leave it open\r
+ if ($this->sb_writeln($socket, $id, "MSG $id N $len") === false ||\r
+ $this->sb_writedata($socket, $aMessage) === false) {\r
+ $this->endSBSession($socket);\r
+ return false;\r
+ }\r
\r
+ // Don't close the SB session, we might as well leave it open\r
return true;\r
}\r
\r
private function sendOtherNetworkMessage($to, $message, $network) {\r
$message = $this->getMessage($message, $network);\r
$len = strlen($message);\r
- // TODO Introduce error checking for message sending\r
- $this->ns_writeln("UUM $this->id $to $network 1 $len");\r
- $this->ns_writedata($Message);\r
+ if ($this->ns_writeln("UUM $this->id $to $network 1 $len") === false ||\r
+ $this->ns_writedata($Message) === false) {\r
+ return false;\r
+ }\r
$this->debug_message("*** Sent to $to (network: $network):\n$Message");\r
return true;\r
}\r
* where network is 1 for MSN, 32 for Yahoo\r
* and 'Offline' for offline messages\r
* @param string $message Message\r
+ * @param boolean &$waitForSession Boolean passed by reference,\r
+ * if set to true on return, message\r
+ * did not fail to send but is\r
+ * waiting for a valid session\r
+ *\r
+ * @return boolean true on success\r
*/\r
- public function sendMessage($to, $message) {\r
+ public function sendMessage($to, $message, &$waitForSession) {\r
if ($message != '') {\r
- list($name, $host, $network) = explode('@', $to);\r
- $network = $network == '' ? 1 : $network;\r
- $recipient = $name.$host;\r
+ $toParts = explode('@', $to);\r
+ if(count($toParts) < 3) {\r
+ list($name, $host) = $toParts;\r
+ $network = 1;\r
+ } else {\r
+ list($name, $host, $network) = $toParts;\r
+ }\r
+\r
+ $recipient = $name.'@'.$host;\r
\r
if ($network === 1) {\r
- if (!isset($this->switchBoardSessionLookup[$recipient]) && (!isset($this->switchBoardSessions[$recipient])\r
- || time() - $this->switchBoardSessions[$recipient]['XFRReqTime'] > $this->XFRReqTimeout)) {\r
- $this->debug_message("*** No existing SB session or request has timed out");\r
- $this->reqSBSession($recipient);\r
+ if (!isset($this->switchBoardSessionLookup[$recipient])) {\r
+ if (!isset($this->switchBoardSessions[$recipient]) || time() - $this->switchBoardSessions[$recipient]['XFRReqTime'] > $this->XFRReqTimeout) {\r
+ $this->debug_message("*** No existing SB session or request has timed out");\r
+ $this->reqSBSession($recipient);\r
+ }\r
+\r
+ $waitForSession = true;\r
return false;\r
} else {\r
- $socket = $this->switchBoardSessionLookup[$to];\r
- if ($this->switchBoardSessions[(int) $socket]['offline']) {\r
+ $socket = $this->switchBoardSessionLookup[$recipient];\r
+ $intsocket = (int) $socket;\r
+ if ($this->switchBoardSessions[$intsocket]['offline']) {\r
$this->debug_message("*** Contact ($recipient) offline, sending OIM");\r
$this->endSBSession($socket);\r
+ $waitForSession = false;\r
return $this->sendMessage($recipient.'@Offline', $message);\r
} else {\r
+ if ($this->switchBoardSessions[$intsocket]['joined'] !== true) {\r
+ $this->debug_message("*** Recipient has not joined session, returning false");\r
+ $waitForSession = true;\r
+ return false;\r
+ }\r
+\r
$this->debug_message("*** Attempting to send message to $recipient using existing SB session");\r
\r
if ($this->sendMessageViaSB($recipient, $message)) {\r
$this->debug_message('*** Message sent successfully');\r
return true;\r
- } else {\r
- $this->debug_message('*** Message sending failed, requesting new SB session');\r
- $this->reqSBSession($to);\r
- return false;\r
}\r
+\r
+ $waitForSession = false;\r
+ return false;\r
}\r
}\r
} elseif ($network == 'Offline') {\r
continue;\r
}\r
}\r
+ return true;\r
} else {\r
// Other network\r
return $this->sendOtherNetworkMessage($recipient, $message, $network);\r
/**\r
* OIM methods\r
*/\r
- \r
+\r
/**\r
* Get OIM mail data\r
*\r
</soap:Envelope>';\r
\r
$header_array = array(\r
- 'SOAPAction: '.OIM_MAILDATA_SOAP,\r
+ 'SOAPAction: '.self::OIM_MAILDATA_SOAP,\r
'Content-Type: text/xml; charset=utf-8',\r
- 'User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; Messenger '.BUILDVER.')'\r
+ 'User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; Messenger '.self::BUILDVER.')'\r
);\r
\r
- $this->debug_message('*** URL: '.OIM_MAILDATA_URL);\r
+ $this->debug_message('*** URL: '.self::OIM_MAILDATA_URL);\r
$this->debug_message("*** Sending SOAP:\n$XML");\r
$curl = curl_init();\r
- curl_setopt($curl, CURLOPT_URL, OIM_MAILDATA_URL);\r
+ curl_setopt($curl, CURLOPT_URL, self::OIM_MAILDATA_URL);\r
curl_setopt($curl, CURLOPT_HTTPHEADER, $header_array);\r
curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);\r
curl_setopt($curl, CURLOPT_FOLLOWLOCATION, 1);\r
</soap:Envelope>';\r
\r
$header_array = array(\r
- 'SOAPAction: '.OIM_READ_SOAP,\r
+ 'SOAPAction: '.self::OIM_READ_SOAP,\r
'Content-Type: text/xml; charset=utf-8',\r
- 'User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; Messenger '.BUILDVER.')'\r
+ 'User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; Messenger '.self::BUILDVER.')'\r
);\r
\r
- $this->debug_message('*** URL: '.OIM_READ_URL);\r
+ $this->debug_message('*** URL: '.self::OIM_READ_URL);\r
$this->debug_message("*** Sending SOAP:\n$XML");\r
$curl = curl_init();\r
- curl_setopt($curl, CURLOPT_URL, OIM_READ_URL);\r
+ curl_setopt($curl, CURLOPT_URL, self::OIM_READ_URL);\r
curl_setopt($curl, CURLOPT_HTTPHEADER, $header_array);\r
curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);\r
curl_setopt($curl, CURLOPT_FOLLOWLOCATION, 1);\r
</soap:Envelope>';\r
\r
$header_array = array(\r
- 'SOAPAction: '.OIM_DEL_SOAP,\r
+ 'SOAPAction: '.self::OIM_DEL_SOAP,\r
'Content-Type: text/xml; charset=utf-8',\r
- 'User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; Messenger '.BUILDVER.')'\r
+ 'User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; Messenger '.self::BUILDVER.')'\r
);\r
\r
- $this->debug_message('*** URL: '.OIM_DEL_URL);\r
+ $this->debug_message('*** URL: '.self::OIM_DEL_URL);\r
$this->debug_message("*** Sending SOAP:\n$XML");\r
$curl = curl_init();\r
- curl_setopt($curl, CURLOPT_URL, OIM_DEL_URL);\r
+ curl_setopt($curl, CURLOPT_URL, self::OIM_DEL_URL);\r
curl_setopt($curl, CURLOPT_HTTPHEADER, $header_array);\r
curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);\r
curl_setopt($curl, CURLOPT_FOLLOWLOCATION, 1);\r
$this->debug_message("*** OIM ($msgid) deleted");\r
return $sMsg;\r
}\r
- \r
+\r
/**\r
* Send offline message\r
*\r
xml:lang="zh-TW"\r
proxy="MSNMSGR"\r
xmlns="http://messenger.msn.com/ws/2004/09/oim/"\r
- msnpVer="'.PROTOCOL.'"\r
- buildVer="'.BUILDVER.'"/>\r
+ msnpVer="'.self::PROTOCOL.'"\r
+ buildVer="'.self::BUILDVER.'"/>\r
<To memberName="'.$to.'" xmlns="http://messenger.msn.com/ws/2004/09/oim/"/>\r
<Ticket passport="'.htmlspecialchars($this->ticket['oim_ticket']).'"\r
- appid="'.PROD_ID.'"\r
+ appid="'.self::PROD_ID.'"\r
lockkey="'.$lockkey.'"\r
xmlns="http://messenger.msn.com/ws/2004/09/oim/"/>\r
<Sequence xmlns="http://schemas.xmlsoap.org/ws/2003/03/rm">\r
</soap:Envelope>';\r
\r
$header_array = array(\r
- 'SOAPAction: '.OIM_SEND_SOAP,\r
+ 'SOAPAction: '.self::OIM_SEND_SOAP,\r
'Content-Type: text/xml',\r
- 'User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; Messenger '.BUILDVER.')'\r
+ 'User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; Messenger '.self::BUILDVER.')'\r
);\r
\r
- $this->debug_message('*** URL: '.OIM_SEND_URL);\r
+ $this->debug_message('*** URL: '.self::OIM_SEND_URL);\r
$this->debug_message("*** Sending SOAP:\n$XML");\r
$curl = curl_init();\r
- curl_setopt($curl, CURLOPT_URL, OIM_SEND_URL);\r
+ curl_setopt($curl, CURLOPT_URL, self::OIM_SEND_URL);\r
curl_setopt($curl, CURLOPT_HTTPHEADER, $header_array);\r
curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);\r
curl_setopt($curl, CURLOPT_FOLLOWLOCATION, 1);\r
//<faultstring>Exception of type 'System.Web.Services.Protocols.SoapException' was thrown.</faultstring>\r
preg_match("#<faultstring>(.*)</faultstring>#", $data, $matches);\r
if (count($matches) > 0)\r
- $err_msg = $matches[1];\r
+ $err_msg = $matches[1];\r
else\r
- $err_msg = '';\r
+ $err_msg = '';\r
$this->debug_message("*** OIM failed for $to");\r
$this->debug_message("*** OIM Error code: $err_code");\r
$this->debug_message("*** OIM Error Message: $err_msg");\r
}\r
return array('challenge' => $challenge, 'auth_policy' => $auth_policy);\r
}\r
- \r
+\r
/**\r
* Contact / Membership list methods\r
*/\r
- \r
+\r
/**\r
* Fetch contact list\r
*\r
$str = '<ml l="1"><d n="'.$u_domain.'"><c n="'.$u_name.'" l="'.$l.'" t="'.$network.'" /></d></ml>';\r
$len = strlen($str);\r
// NS: >>> ADL {id} {size}\r
- //TODO introduce error checking\r
$this->ns_writeln("ADL $this->id $len");\r
$this->ns_writedata($str);\r
}\r
</soap:Envelope>';\r
\r
$header_array = array(\r
- 'SOAPAction: '.DELMEMBER_SOAP,\r
+ 'SOAPAction: '.self::DELMEMBER_SOAP,\r
'Content-Type: text/xml; charset=utf-8',\r
'User-Agent: MSN Explorer/9.0 (MSN 8.0; TmstmpExt)'\r
);\r
\r
- $this->debug_message('*** URL: '.DELMEMBER_URL);\r
+ $this->debug_message('*** URL: '.self::DELMEMBER_URL);\r
$this->debug_message("*** Sending SOAP:\n$XML");\r
$curl = curl_init();\r
- curl_setopt($curl, CURLOPT_URL, DELMEMBER_URL);\r
+ curl_setopt($curl, CURLOPT_URL, self::DELMEMBER_URL);\r
curl_setopt($curl, CURLOPT_HTTPHEADER, $header_array);\r
curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);\r
curl_setopt($curl, CURLOPT_FOLLOWLOCATION, 1);\r
</soap:Body>\r
</soap:Envelope>';\r
$header_array = array(\r
- 'SOAPAction: '.ADDMEMBER_SOAP,\r
+ 'SOAPAction: '.self::ADDMEMBER_SOAP,\r
'Content-Type: text/xml; charset=utf-8',\r
'User-Agent: MSN Explorer/9.0 (MSN 8.0; TmstmpExt)'\r
);\r
\r
- $this->debug_message('*** URL: '.ADDMEMBER_URL);\r
+ $this->debug_message('*** URL: '.self::ADDMEMBER_URL);\r
$this->debug_message("*** Sending SOAP:\n$XML");\r
$curl = curl_init();\r
- curl_setopt($curl, CURLOPT_URL, ADDMEMBER_URL);\r
+ curl_setopt($curl, CURLOPT_URL, self::ADDMEMBER_URL);\r
curl_setopt($curl, CURLOPT_HTTPHEADER, $header_array);\r
curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);\r
curl_setopt($curl, CURLOPT_FOLLOWLOCATION, 1);\r
</soap:Body>\r
</soap:Envelope>';\r
$header_array = array(\r
- 'SOAPAction: '.MEMBERSHIP_SOAP,\r
+ 'SOAPAction: '.self::MEMBERSHIP_SOAP,\r
'Content-Type: text/xml; charset=utf-8',\r
'User-Agent: MSN Explorer/9.0 (MSN 8.0; TmstmpExt)'\r
);\r
- $this->debug_message('*** URL: '.MEMBERSHIP_URL);\r
+ $this->debug_message('*** URL: '.self::MEMBERSHIP_URL);\r
$this->debug_message("*** Sending SOAP:\n$XML");\r
$curl = curl_init();\r
- curl_setopt($curl, CURLOPT_URL, MEMBERSHIP_URL);\r
+ curl_setopt($curl, CURLOPT_URL, self::MEMBERSHIP_URL);\r
curl_setopt($curl, CURLOPT_HTTPHEADER, $header_array);\r
curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);\r
curl_setopt($curl, CURLOPT_FOLLOWLOCATION, 1);\r
$http_code = curl_getinfo($curl, CURLINFO_HTTP_CODE);\r
curl_close($curl);\r
$this->debug_message("*** Get Result:\n$data");\r
- \r
+\r
if ($http_code != 200) return false;\r
$p = $data;\r
$aMemberships = array();\r
}\r
return $aContactList;\r
}\r
- \r
+\r
/**\r
* MsnObj related methods\r
*/\r
- \r
+\r
/**\r
*\r
* @param $FilePath 圖檔路徑\r
}\r
return $DefineString;\r
}\r
- \r
+\r
/**\r
* Socket methods\r
*/\r
- \r
+\r
/**\r
* Read data of specified size from NS socket\r
- * \r
+ *\r
* @param integer $size Size to read\r
* @return string Data read\r
*/\r
\r
/**\r
* Read line from the NS socket\r
- * \r
+ *\r
* @return string Data read\r
*/\r
private function ns_readln() {\r
\r
/**\r
* Write line to NS socket\r
- * \r
+ *\r
* Also increments id\r
- * \r
+ *\r
* @param string $data Line to write to socket\r
- * @return void\r
+ * @return mixed Bytes written or false on failure\r
*/\r
private function ns_writeln($data) {\r
- @fwrite($this->NSfp, $data."\r\n");\r
- $this->debug_message("NS: >>> $data");\r
- $this->id++;\r
+ $result = @fwrite($this->NSfp, $data."\r\n");\r
+ if ($result !== false) {\r
+ $this->debug_message("NS: >>> $data");\r
+ $this->id++;\r
+ }\r
+ return $result;\r
}\r
\r
/**\r
* Write data to NS socket\r
- * \r
+ *\r
* @param string $data Data to write to socket\r
- * @return void\r
+ * @return mixed Bytes written or false on failure\r
*/\r
private function ns_writedata($data) {\r
- @fwrite($this->NSfp, $data);\r
- $this->debug_message("NS: >>> $data");\r
+ $result = @fwrite($this->NSfp, $data);\r
+ if ($result !== false) {\r
+ $this->debug_message("NS: >>> $data");\r
+ }\r
+ return $result;\r
}\r
\r
/**\r
* Read data of specified size from given SB socket\r
- * \r
+ *\r
* @param resource $socket SB socket\r
* @param integer $size Size to read\r
* @return string Data read\r
\r
/**\r
* Read line from given SB socket\r
- * \r
+ *\r
* @param resource $socket SB Socket\r
* @return string Line read\r
*/\r
\r
/**\r
* Write line to given SB socket\r
- * \r
+ *\r
* Also increments id\r
- * \r
+ *\r
* @param resource $socket SB socket\r
* @param integer $id Reference to SB id\r
* @param string $data Line to write\r
- * @return void\r
+ * @return mixed Bytes written or false on error\r
*/\r
private function sb_writeln($socket, &$id, $data) {\r
- @fwrite($socket, $data."\r\n");\r
- $this->debug_message("SB: >>> $data");\r
- $id++;\r
+ $result = @fwrite($socket, $data."\r\n");\r
+ if ($result !== false) {\r
+ $this->debug_message("SB: >>> $data");\r
+ $id++;\r
+ }\r
+ return $result;\r
}\r
\r
/**\r
* Write data to given SB socket\r
- * \r
+ *\r
* @param resource $socket SB socket\r
* @param $data Data to write to socket\r
- * @return void\r
+ * @return mixed Bytes written or false on error\r
*/\r
private function sb_writedata($socket, $data) {\r
- @fwrite($socket, $data);\r
- $this->debug_message("SB: >>> $data");\r
+ $result = @fwrite($socket, $data);\r
+ if ($result !== false) {\r
+ $this->debug_message("SB: >>> $data");\r
+ }\r
+ return $result;\r
}\r
\r
/**\r
$info = stream_get_meta_data($socket);\r
return $info['eof'];\r
}\r
- \r
+\r
/**\r
* Key generation methods\r
*/\r
- \r
+\r
private function derive_key($key, $magic) {\r
- $hash1 = mhash(MHASH_SHA1, $magic, $key);\r
- $hash2 = mhash(MHASH_SHA1, $hash1.$magic, $key);\r
- $hash3 = mhash(MHASH_SHA1, $hash1, $key);\r
- $hash4 = mhash(MHASH_SHA1, $hash3.$magic, $key);\r
+ $hash1 = $this->mhash_sha1($magic, $key);\r
+ $hash2 = $this->mhash_sha1($hash1.$magic, $key);\r
+ $hash3 = $this->mhash_sha1($hash1, $key);\r
+ $hash4 = $this->mhash_sha1($hash3.$magic, $key);\r
return $hash2.substr($hash4, 0, 4);\r
}\r
\r
$key3 = $this->derive_key($key1, 'WS-SecureConversationSESSION KEY ENCRYPTION');\r
\r
// get hash of challenge using key2\r
- $hash = mhash(MHASH_SHA1, $challenge, $key2);\r
+ $hash = $this->mhash_sha1($challenge, $key2);\r
\r
// get 8 bytes random data\r
$iv = substr(base64_encode(rand(1000,9999).rand(1000,9999)), 2, 8);\r
\r
return base64_encode($blob);\r
}\r
- \r
+\r
/**\r
* Generate challenge response\r
*\r
// MSNP15\r
// http://msnpiki.msnfanatic.com/index.php/MSNP11:Challenges\r
// Step 1: The MD5 Hash\r
- $md5Hash = md5($code.PROD_KEY);\r
+ $md5Hash = md5($code.self::PROD_KEY);\r
$aMD5 = @explode("\0", chunk_split($md5Hash, 8, "\0"));\r
for ($i = 0; $i < 4; $i++) {\r
$aMD5[$i] = implode('', array_reverse(@explode("\0", chunk_split($aMD5[$i], 2, "\0"))));\r
}\r
\r
// Step 2: A new string\r
- $chl_id = $code.PROD_ID;\r
+ $chl_id = $code.self::PROD_ID;\r
$chl_id .= str_repeat('0', 8 - (strlen($chl_id) % 8));\r
\r
$aID = @explode("\0", substr(chunk_split($chl_id, 4, "\0"), 0, -1));\r
// $key = bcadd(bcmul($high, 0x100000000), $low);\r
\r
// Step 4: Using the key\r
- $md5Hash = md5($code.PROD_KEY);\r
+ $md5Hash = md5($code.self::PROD_KEY);\r
$aHash = @explode("\0", chunk_split($md5Hash, 8, "\0"));\r
\r
$hash = '';\r
\r
return $hash;\r
}\r
- \r
+\r
/**\r
* Utility methods\r
*/\r
- \r
+\r
private function Array2SoapVar($Array, $ReturnSoapVarObj = true, $TypeName = null, $TypeNameSpace = null) {\r
$ArrayString = '';\r
foreach($Array as $Key => $Val) {\r
$Attrib = '';\r
if (is_array($Val[':'])) {\r
foreach ($Val[':'] as $AttribName => $AttribVal)\r
- $Attrib .= " $AttribName = '$AttribVal'";\r
+ $Attrib .= " $AttribName = '$AttribVal'";\r
}\r
if ($Key{0} == '!') {\r
//List Type Define\r
if ($ReturnSoapVarObj) return new SoapVar($ArrayString, XSD_ANYXML, $TypeName, $TypeNameSpace);\r
return $ArrayString;\r
}\r
- \r
+\r
private function linetoArray($lines) {\r
$lines = str_replace("\r", '', $lines);\r
$lines = explode("\n", $lines);\r
}\r
return $Data;\r
}\r
- \r
+\r
/**\r
* Get Passport ticket\r
*\r
$password = htmlspecialchars($this->password);\r
\r
if ($url === '')\r
- $passport_url = PASSPORT_URL;\r
+ $passport_url = self::PASSPORT_URL;\r
else\r
$passport_url = $url;\r
\r
$this->ABAuthHeader = new SoapHeader('http://www.msn.com/webservices/AddressBook', 'ABAuthHeader', $this->Array2SoapVar($ABAuthHeaderArray));\r
return $aTickets;\r
}\r
- \r
+\r
/**\r
* Generate the data to send a message\r
*\r
$msg_header = "MIME-Version: 1.0\r\nContent-Type: text/plain; charset=UTF-8\r\nX-MMS-IM-Format: FN=$this->font_fn; EF=$this->font_ef; CO=$this->font_co; CS=0; PF=22\r\n\r\n";\r
$msg_header_len = strlen($msg_header);\r
if ($network == 1)\r
- $maxlen = $this->max_msn_message_len - $msg_header_len;\r
+ $maxlen = self::MAX_MSN_MESSAGE_LEN - $msg_header_len;\r
else\r
- $maxlen = $this->max_yahoo_message_len - $msg_header_len;\r
+ $maxlen = self::MAX_YAHOO_MESSAGE_LEN - $msg_header_len;\r
$sMessage = str_replace("\r", '', $sMessage);\r
$msg = substr($sMessage, 0, $maxlen);\r
return $msg_header.$msg;\r
}\r
- \r
+\r
/**\r
* Sleep for the given number of seconds\r
*\r
$this->debug_message("*** Sleeping for $wait seconds before retrying");\r
sleep($wait);\r
}\r
- \r
+\r
/**\r
* Sends a ping command\r
*\r
// NS: >>> PNG\r
$this->ns_writeln("PNG");\r
}\r
- \r
+\r
/**\r
* Methods to add / call callbacks\r
*/\r
* Registers a user handler\r
*\r
* Handler List\r
- * IMIn, Pong, ConnectFailed, Reconnect,\r
- * AddedToList, RemovedFromList\r
+ * IMIn, SessionReady, Pong, ConnectFailed, Reconnect,\r
+ * AddedToList, RemovedFromList, StatusChange\r
*\r
* @param string $event Event name\r
* @param string $handler User function to call\r
return false;\r
}\r
}\r
- \r
+\r
/**\r
* Debugging methods\r
*/\r
- \r
+\r
/**\r
* Print message if debugging is enabled\r
- * \r
+ *\r
* @param string $str Message to print\r
*/\r
private function debug_message($str) {\r
if (!$this->debug) return;\r
echo $str."\n";\r
}\r
- \r
+\r
/**\r
* Dump binary data\r
- * \r
+ *\r
* @param string $str Data string\r
* @return Binary data\r
*/\r
$buf .= "$h_str $a_str\n";\r
return $buf;\r
}\r
+\r
+ function mhash_sha1($data, $key)\r
+ {\r
+ if (extension_loaded("mhash"))\r
+ return mhash(MHASH_SHA1, $data, $key);\r
+\r
+ if (function_exists("hash_hmac"))\r
+ return hash_hmac('sha1', $data, $key, true);\r
+\r
+ // RFC 2104 HMAC implementation for php. Hacked by Lance Rushing\r
+ $b = 64;\r
+ if (strlen($key) > $b)\r
+ $key = pack("H*", sha1($key));\r
+ $key = str_pad($key, $b, chr(0x00));\r
+ $ipad = str_pad("", $b, chr(0x36));\r
+ $opad = str_pad("", $b, chr(0x5c));\r
+ $k_ipad = $key ^ $ipad ;\r
+ $k_opad = $key ^ $opad;\r
+\r
+ $sha1_value = sha1($k_opad . pack("H*", sha1($k_ipad . $data)));\r
+\r
+ $hash_data = '';\r
+ $str = join('',explode('\x', $sha1_value));\r
+ $len = strlen($str);\r
+ for ($i = 0; $i < $len; $i += 2)\r
+ $hash_data .= chr(hexdec(substr($str, $i, 2)));\r
+ return $hash_data;\r
+ }\r
}\r