From 150a1abecb060337a07ad430f4ac268fa77bfe9a Mon Sep 17 00:00:00 2001 From: Mikael Nordfeldth Date: Mon, 5 May 2014 23:02:17 +0200 Subject: [PATCH] MSN probably doesn't work, and we don't like it anyway --- plugins/Msn/MsnPlugin.php | 209 -- plugins/Msn/README | 32 - plugins/Msn/classes/msn_waiting_message.php | 87 - plugins/Msn/extlib/phpmsnclass/msn.class.php | 3239 ----------------- plugins/Msn/extlib/phpmsnclass/msnbot.php | 63 - .../phpmsnclass/soap/msnab_datatypes.xsd | 832 ----- .../phpmsnclass/soap/msnab_servicetypes.xsd | 567 --- .../soap/msnab_sharingservice.wsdl | 532 --- plugins/Msn/lib/msnmanager.php | 276 -- plugins/Msn/locale/Msn.pot | 53 - plugins/Msn/locale/ar/LC_MESSAGES/Msn.po | 54 - plugins/Msn/locale/br/LC_MESSAGES/Msn.po | 51 - plugins/Msn/locale/ca/LC_MESSAGES/Msn.po | 51 - plugins/Msn/locale/de/LC_MESSAGES/Msn.po | 54 - plugins/Msn/locale/el/LC_MESSAGES/Msn.po | 51 - plugins/Msn/locale/es/LC_MESSAGES/Msn.po | 54 - plugins/Msn/locale/eu/LC_MESSAGES/Msn.po | 53 - plugins/Msn/locale/fr/LC_MESSAGES/Msn.po | 55 - plugins/Msn/locale/gl/LC_MESSAGES/Msn.po | 53 - plugins/Msn/locale/ia/LC_MESSAGES/Msn.po | 54 - plugins/Msn/locale/it/LC_MESSAGES/Msn.po | 51 - plugins/Msn/locale/mk/LC_MESSAGES/Msn.po | 53 - plugins/Msn/locale/nl/LC_MESSAGES/Msn.po | 54 - plugins/Msn/locale/pt/LC_MESSAGES/Msn.po | 51 - plugins/Msn/locale/sv/LC_MESSAGES/Msn.po | 54 - plugins/Msn/locale/tl/LC_MESSAGES/Msn.po | 53 - plugins/Msn/locale/uk/LC_MESSAGES/Msn.po | 53 - 27 files changed, 6789 deletions(-) delete mode 100644 plugins/Msn/MsnPlugin.php delete mode 100644 plugins/Msn/README delete mode 100644 plugins/Msn/classes/msn_waiting_message.php delete mode 100644 plugins/Msn/extlib/phpmsnclass/msn.class.php delete mode 100755 plugins/Msn/extlib/phpmsnclass/msnbot.php delete mode 100644 plugins/Msn/extlib/phpmsnclass/soap/msnab_datatypes.xsd delete mode 100644 plugins/Msn/extlib/phpmsnclass/soap/msnab_servicetypes.xsd delete mode 100644 plugins/Msn/extlib/phpmsnclass/soap/msnab_sharingservice.wsdl delete mode 100644 plugins/Msn/lib/msnmanager.php delete mode 100644 plugins/Msn/locale/Msn.pot delete mode 100644 plugins/Msn/locale/ar/LC_MESSAGES/Msn.po delete mode 100644 plugins/Msn/locale/br/LC_MESSAGES/Msn.po delete mode 100644 plugins/Msn/locale/ca/LC_MESSAGES/Msn.po delete mode 100644 plugins/Msn/locale/de/LC_MESSAGES/Msn.po delete mode 100644 plugins/Msn/locale/el/LC_MESSAGES/Msn.po delete mode 100644 plugins/Msn/locale/es/LC_MESSAGES/Msn.po delete mode 100644 plugins/Msn/locale/eu/LC_MESSAGES/Msn.po delete mode 100644 plugins/Msn/locale/fr/LC_MESSAGES/Msn.po delete mode 100644 plugins/Msn/locale/gl/LC_MESSAGES/Msn.po delete mode 100644 plugins/Msn/locale/ia/LC_MESSAGES/Msn.po delete mode 100644 plugins/Msn/locale/it/LC_MESSAGES/Msn.po delete mode 100644 plugins/Msn/locale/mk/LC_MESSAGES/Msn.po delete mode 100644 plugins/Msn/locale/nl/LC_MESSAGES/Msn.po delete mode 100644 plugins/Msn/locale/pt/LC_MESSAGES/Msn.po delete mode 100644 plugins/Msn/locale/sv/LC_MESSAGES/Msn.po delete mode 100644 plugins/Msn/locale/tl/LC_MESSAGES/Msn.po delete mode 100644 plugins/Msn/locale/uk/LC_MESSAGES/Msn.po diff --git a/plugins/Msn/MsnPlugin.php b/plugins/Msn/MsnPlugin.php deleted file mode 100644 index 11bade8034..0000000000 --- a/plugins/Msn/MsnPlugin.php +++ /dev/null @@ -1,209 +0,0 @@ -. - * - * @category IM - * @package StatusNet - * @author Luke Fitzgerald - * @copyright 2010 StatusNet, Inc. - * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html AGPL 3.0 - * @link http://status.net/ - */ - -if (!defined('STATUSNET')) { - // This check helps protect against security problems; - // your code file can't be executed directly from the web. - exit(1); -} -// We bundle the phpmsnclass library... -set_include_path(get_include_path() . PATH_SEPARATOR . dirname(__FILE__) . '/extlib/phpmsnclass'); - -/** - * Plugin for MSN - * - * @category Plugin - * @package StatusNet - * @author Luke Fitzgerald - * @copyright 2010 StatusNet, Inc. - * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html AGPL 3.0 - * @link http://status.net/ - */ -class MsnPlugin extends ImPlugin { - public $user = null; - public $password = null; - public $nickname = null; - public $transport = 'msn'; - - /** - * Get the internationalized/translated display name of this IM service - * - * @return string Name of service - */ - public function getDisplayName() { - // TRANS: Display name of the MSN instant messaging service. - return _m('MSN'); - } - - /** - * Normalize a screenname for comparison - * - * @param string $screenname screenname to normalize - * @return string an equivalent screenname in normalized form - */ - public function normalize($screenname) { - $screenname = str_replace(" ","", $screenname); - return strtolower($screenname); - } - - /** - * Get the screenname of the daemon that sends and receives messages - * - * @return string Screenname - */ - public function daemonScreenname() { - return $this->user; - } - - /** - * Validate (ensure the validity of) a screenname - * - * @param string $screenname screenname to validate - * @return boolean - */ - public function validate($screenname) { - return Validate::email($screenname, common_config('email', 'check_domain')); - } - - /** - * Load related modules when needed - * - * @param string $cls Name of the class to be loaded - * @return boolean hook value; true means continue processing, false means stop. - */ - public function onAutoload($cls) { - $dir = dirname(__FILE__); - - switch ($cls) { - case 'MSN': - require_once(INSTALLDIR.'/plugins/Msn/extlib/phpmsnclass/msn.class.php'); - return false; - } - - return parent::onAutoload($cls); - } - - /* - * Start manager on daemon start - * - * @return boolean - */ - public function onStartImDaemonIoManagers(&$classes) { - parent::onStartImDaemonIoManagers($classes); - $classes[] = new MsnManager($this); // handles sending/receiving - return true; - } - - /** - * Ensure the database table is present - * - */ - public function onCheckSchema() { - $schema = Schema::get(); - - // For storing messages while sessions become ready - $schema->ensureTable('msn_waiting_message', Msn_waiting_message::schemaGet()); - return true; - } - - /** - * Get a microid URI for the given screenname - * - * @param string $screenname - * @return string microid URI - */ - public function microiduri($screenname) { - return 'msnim:' . $screenname; - } - - /** - * Send a message to a given screenname - * - * @param string $screenname Screenname to send to - * @param string $body Text to send - * @return boolean success value - */ - public function sendMessage($screenname, $body) { - $this->enqueueOutgoingRaw(array('to' => $screenname, 'message' => $body)); - return true; - } - - /** - * Accept a queued input message. - * - * @param array $data Data - * @return true if processing completed, false if message should be reprocessed - */ - public function receiveRawMessage($data) { - $this->handleIncoming($data['sender'], $data['message']); - return true; - } - - /** - * Initialize plugin - * - * @return boolean - */ - public function initialize() { - if (!isset($this->user)) { - // TRANS: Exception thrown when configuration for the MSN plugin is incomplete. - throw new Exception(_m('Must specify a user.')); - } - if (!isset($this->password)) { - // TRANS: Exception thrown when configuration for the MSN plugin is incomplete. - throw new Exception(_m('Must specify a password.')); - } - if (!isset($this->nickname)) { - // TRANS: Exception thrown when configuration for the MSN plugin is incomplete. - throw new Exception(_m('Must specify a nickname.')); - } - - return true; - } - - /** - * Get plugin information - * - * @param array $versions array to insert information into - * @return void - */ - public function onPluginVersion(&$versions) { - $versions[] = array( - 'name' => 'MSN', - 'version' => GNUSOCIAL_VERSION, - 'author' => 'Luke Fitzgerald', - 'homepage' => 'http://status.net/wiki/Plugin:MSN', - 'rawdescription' => - // TRANS: Plugin description. - _m('The MSN plugin allows users to send and receive notices over the MSN network.') - ); - return true; - } -} diff --git a/plugins/Msn/README b/plugins/Msn/README deleted file mode 100644 index a56bacd64c..0000000000 --- a/plugins/Msn/README +++ /dev/null @@ -1,32 +0,0 @@ -The MSN plugin allows users to send and receive notices over the MSN network. - -Required PHP extensions: -curl pcre mhash mcrypt bcmath - -Installation -============ -add "addPlugin('msn', - array('setting'=>'value', 'setting2'=>'value2', ...);" -to the bottom of your config.php - -scripts/imdaemon.php included with StatusNet must be running. It will be started -by the plugin along with their other daemons when you run -scripts/startdaemons.sh. See the StatusNet README for more about queuing and -daemons. - -Settings -======== -user*: username (screenname) to use when logging into MSN -password*: password for that user -nickname*: nickname for the bot - -* required -default values are in (parenthesis) - -Example -======= -addPlugin('msn', array( - 'user' => '...', - 'password' => '...', - 'nickname' => '...' -)); diff --git a/plugins/Msn/classes/msn_waiting_message.php b/plugins/Msn/classes/msn_waiting_message.php deleted file mode 100644 index cfb69def00..0000000000 --- a/plugins/Msn/classes/msn_waiting_message.php +++ /dev/null @@ -1,87 +0,0 @@ - array( - 'id' => array('type' => 'serial', 'not null' => true, 'description' => 'Unique ID for entry'), - 'screenname' => array('type' => 'varchar', 'length' => 255, 'description' => 'from screenname'), - 'message' => array('type' => 'text', 'not null' => true, 'description' => 'MSN message text'), - 'claimed' => array('type' => 'datetime', 'description' => 'date this irc message was claimed'), - 'created' => array('type' => 'datetime', 'not null' => true, 'description' => 'date this record was created'), - 'modified' => array('type' => 'timestamp', 'not null' => true, 'description' => 'date this record was modified'), - ), - 'primary key' => array('id'), - 'indexes' => array( - 'msn_waiting_message_prioritise_idx' => array('screenname'), - ), - ); - } - - /** - * @param string $screenname screenname or array of screennames to pull from - * If not specified, checks all queues in the system. - */ - public static function top($screenname = null) { - $wm = new Msn_waiting_message(); - if ($screenname) { - if (is_array($screenname)) { - // @fixme use safer escaping - $list = implode("','", array_map('addslashes', $screenname)); - $wm->whereAdd("screenname in ('$list')"); - } else { - $wm->screenname = $screenname; - } - } - $wm->orderBy('created'); - $wm->whereAdd('claimed is null'); - - $wm->limit(1); - - $cnt = $wm->find(true); - - if ($cnt) { - // XXX: potential race condition - // can we force it to only update if claimed is still null - // (or old)? - common_log(LOG_INFO, 'claiming msn waiting message id = ' . $wm->id); - $orig = clone($wm); - $wm->claimed = common_sql_now(); - $result = $wm->update($orig); - if ($result) { - common_log(LOG_INFO, 'claim succeeded.'); - return $wm; - } else { - common_log(LOG_INFO, 'claim failed.'); - } - } - $wm = null; - return null; - } - - /** - * Release a claimed item. - */ - public function releaseClaim() { - // DB_DataObject doesn't let us save nulls right now - $sql = sprintf("UPDATE msn_waiting_message SET claimed=NULL WHERE id=%d", $this->id); - $this->query($sql); - - $this->claimed = null; - $this->encache(); - } -} diff --git a/plugins/Msn/extlib/phpmsnclass/msn.class.php b/plugins/Msn/extlib/phpmsnclass/msn.class.php deleted file mode 100644 index 5675eb5c2f..0000000000 --- a/plugins/Msn/extlib/phpmsnclass/msn.class.php +++ /dev/null @@ -1,3239 +0,0 @@ - - -Based on MSN class ver 2.0 by Tommy Wu, Ricky Su -License: GPL - -Documentation on the MSN protocol can be found at: http://msnpiki.msnfanatic.com/index.php/Main_Page - -This class uses MSNP15. - -In addition to PHP5, the additional php modules required are: -curl pcre mcrypt bcmath - -*/ - -class MSN { - const PROTOCOL = 'MSNP15'; - const PASSPORT_URL = 'https://login.live.com/RST.srf'; - const BUILDVER = '8.1.0178'; - const PROD_KEY = 'PK}_A_0N_K%O?A9S'; - const PROD_ID = 'PROD0114ES4Z%Q5W'; - const LOGIN_METHOD = 'SSO'; - - const OIM_SEND_URL = 'https://ows.messenger.msn.com/OimWS/oim.asmx'; - const OIM_SEND_SOAP = 'http://messenger.live.com/ws/2006/09/oim/Store2'; - - const OIM_MAILDATA_URL = 'https://rsi.hotmail.com/rsi/rsi.asmx'; - const OIM_MAILDATA_SOAP = 'http://www.hotmail.msn.com/ws/2004/09/oim/rsi/GetMetadata'; - const OIM_READ_URL = 'https://rsi.hotmail.com/rsi/rsi.asmx'; - const OIM_READ_SOAP = 'http://www.hotmail.msn.com/ws/2004/09/oim/rsi/GetMessage'; - const OIM_DEL_URL = 'https://rsi.hotmail.com/rsi/rsi.asmx'; - const OIM_DEL_SOAP = 'http://www.hotmail.msn.com/ws/2004/09/oim/rsi/DeleteMessages'; - - const MEMBERSHIP_URL = 'https://contacts.msn.com/abservice/SharingService.asmx'; - const MEMBERSHIP_SOAP = 'http://www.msn.com/webservices/AddressBook/FindMembership'; - - const ADDMEMBER_URL = 'https://contacts.msn.com/abservice/SharingService.asmx'; - const ADDMEMBER_SOAP = 'http://www.msn.com/webservices/AddressBook/AddMember'; - - const DELMEMBER_URL = 'https://contacts.msn.com/abservice/SharingService.asmx'; - const DELMEMBER_SOAP = 'http://www.msn.com/webservices/AddressBook/DeleteMember'; - - // the message length (include header) is limited (maybe since WLM 8.5 released) - // for WLM: 1664 bytes - // for YIM: 518 bytes - const MAX_MSN_MESSAGE_LEN = 1664; - const MAX_YAHOO_MESSAGE_LEN = 518; - - private $debug; - private $timeout; - - private $id; - private $ticket; - private $user = ''; - private $password = ''; - private $NSfp = false; - private $passport_policy = ''; - private $alias; - private $psm; - private $retry_wait; - private $update_pending; - private $PhotoStickerFile = false; - private $Emotions = false; - private $XFRReqTimeout = 60; - private $SBStreamTimeout = 2; - private $MsnObjArray = array(); - private $MsnObjMap = array(); - private $ABAuthHeader; - private $ABService; - private $Contacts; - - private $server = 'messenger.hotmail.com'; - private $port = 1863; - - private $clientid = ''; - - private $error = ''; - - private $authed = false; - - private $oim_try = 3; - - private $font_fn = 'Arial'; - private $font_co = '333333'; - private $font_ef = ''; - - // Begin added for StatusNet - - private $aContactList = array(); - private $aADL = array(); - - /** - * Holds session information indexed by screenname if - * session has no socket or socket if socket present - * - * @var array - */ - private $switchBoardSessions = array(); - - /** - * Holds sockets indexed by screenname - * - * @var array - */ - private $switchBoardSessionLookup = array(); - - /** - * Holds references to sessions waiting for XFR - * - * @var array - */ - private $waitingForXFR = array(); - - /** - * Event Handler Functions - */ - private $myEventHandlers = array(); - - // End added for StatusNet - - /** - * Constructor method - * - * @param array $Configs Array of configuration options - * 'user' - Username - * 'password' - Password - * 'alias' - Bot nickname - * 'psm' - Bot personal status message - * 'retry_wait' - Time to wait before trying to reconnect - * 'update_pending' - Whether to update pending contacts - * 'PhotoSticker' - Photo file to use (?) - * 'debug' - Enable/Disable debugging mode - * @param integer $timeout Connection timeout - * @param integer $client_id Client id (hexadecimal) - * @return MSN - */ - public function __construct ($Configs = array(), $timeout = 15, $client_id = 0x7000800C) { - $this->user = $Configs['user']; - $this->password = $Configs['password']; - $this->alias = isset($Configs['alias']) ? $Configs['alias'] : ''; - $this->psm = isset($Configs['psm']) ? $Configs['psm'] : ''; - $this->retry_wait = isset($Configs['retry_wait']) ? $Configs['retry_wait'] : 30; - $this->update_pending = isset($Configs['update_pending']) ? $Configs['update_pending'] : true; - $this->PhotoStickerFile=isset($Configs['PhotoSticker']) ? $Configs['PhotoSticker'] : false; - - if ($this->Emotions = isset($Configs['Emotions']) ? $Configs['Emotions']:false) { - foreach($this->Emotions as $EmotionFilePath) - $this->MsnObj($EmotionFilePath,$Type=2); - } - $this->debug = isset($Configs['debug']) ? $Configs['debug'] : false; - $this->timeout = $timeout; - - // Check support - if (!function_exists('curl_init')) throw new Exception("curl module not found!\n"); - if (!function_exists('preg_match')) throw new Exception("pcre module not found!\n"); - if (!function_exists('mcrypt_cbc')) throw new Exception("mcrypt module not found!\n"); - if (!function_exists('bcmod')) throw new Exception("bcmath module not found!\n"); - - /* - http://msnpiki.msnfanatic.com/index.php/Client_ID - Client ID for MSN: - normal MSN 8.1 clientid is: - 01110110 01001100 11000000 00101100 - = 0x764CC02C - - we just use following: - * 0x04: Your client can send/receive Ink (GIF format) - * 0x08: Your client can send/recieve Ink (ISF format) - * 0x8000: This means you support Winks receiving (If not set the official Client will warn with 'contact has an older client and is not capable of receiving Winks') - * 0x70000000: This is the value for MSNC7 (WL Msgr 8.1) - = 0x7000800C; - */ - $this->clientid = $client_id; - $this->ABService = new SoapClient(realpath(dirname(__FILE__)).'/soap/msnab_sharingservice.wsdl', array('trace' => 1)); - } - - /** - * Signon methods - */ - - /** - * Connect to the NS server - * - * @param String $user Username - * @param String $password Password - * @param String $redirect_server Redirect server - * @param Integer $redirect_port Redirect port - * @return Boolean Returns true if successful - */ - private function connect($user, $password, $redirect_server = '', $redirect_port = 1863) { - $this->id = 1; - if ($redirect_server === '') { - $this->NSfp = @fsockopen($this->server, $this->port, $errno, $errstr, $this->timeout); - if (!$this->NSfp) { - $this->error = "!!! Could not connect to $this->server:$this->port, error => $errno, $errstr"; - return false; - } - } - else { - $this->NSfp = @fsockopen($redirect_server, $redirect_port, $errno, $errstr, $this->timeout); - if (!$this->NSfp) { - $this->error = "!!! Could not connect to $redirect_server:$redirect_port, error => $errno, $errstr"; - return false; - } - } - $this->authed = false; - // MSNP9 - // NS: >> VER {id} MSNP9 CVR0 - // MSNP15 - // NS: >>> VER {id} MSNP15 CVR0 - $this->ns_writeln("VER $this->id ".self::PROTOCOL.' CVR0'); - - $start_tm = time(); - while (!self::socketcheck($this->NSfp)) { - $data = $this->ns_readln(); - // no data? - if ($data === false) { - // logout now - // NS: >>> OUT - $this->ns_writeln("OUT"); - @fclose($this->NSfp); - $this->error = 'Timeout, maybe protocol changed!'; - return false; - } - - $code = substr($data, 0, 3); - $start_tm = time(); - - switch ($code) { - case 'VER': - // MSNP9 - // NS: <<< VER {id} MSNP9 CVR0 - // NS: >>> CVR {id} 0x0409 winnt 5.1 i386 MSMSGS 6.0.0602 msmsgs {user} - // MSNP15 - // NS: <<< VER {id} MSNP15 CVR0 - // NS: >>> CVR {id} 0x0409 winnt 5.1 i386 MSMSGS 8.1.0178 msmsgs {user} - $this->ns_writeln("CVR $this->id 0x0409 winnt 5.1 i386 MSMSGS ".self::BUILDVER." msmsgs $user"); - break; - - case 'CVR': - // MSNP9 - // NS: <<< CVR {id} {ver_list} {download_serve} .... - // NS: >>> USR {id} TWN I {user} - // MSNP15 - // NS: <<< CVR {id} {ver_list} {download_serve} .... - // NS: >>> USR {id} SSO I {user} - $this->ns_writeln("USR $this->id ".self::LOGIN_METHOD." I $user"); - break; - - case 'USR': - // already login for passport site, finish the login process now. - // NS: <<< USR {id} OK {user} {verify} 0 - if ($this->authed) return true; - // max. 16 digits for password - if (strlen($password) > 16) - $password = substr($password, 0, 16); - - $this->user = $user; - $this->password = $password; - // NS: <<< USR {id} SSO S {policy} {nonce} - @list(/* USR */, /* id */, /* SSO */, /* S */, $policy, $nonce) = @explode(' ', $data); - - $this->passport_policy = $policy; - $aTickets = $this->get_passport_ticket(); - if (!$aTickets || !is_array($aTickets)) { - // logout now - // NS: >>> OUT - $this->ns_writeln("OUT"); - @fclose($this->NSfp); - $this->error = 'Passport authentication failed!'; - return false; - } - - $ticket = $aTickets['ticket']; - $secret = $aTickets['secret']; - $this->ticket = $aTickets; - $login_code = $this->generateLoginBLOB($secret, $nonce); - - // NS: >>> USR {id} SSO S {ticket} {login_code} - $this->ns_writeln("USR $this->id ".self::LOGIN_METHOD." S $ticket $login_code"); - $this->authed = true; - break; - - case 'XFR': - // main login server will redirect to anther NS after USR command - // MSNP9 - // NS: <<< XFR {id} NS {server} 0 {server} - // MSNP15 - // NS: <<< XFR {id} NS {server} U D - @list(/* XFR */, /* id */, $Type, $server) = @explode(' ', $data); - if ($Type!='NS') break; - @list($ip, $port) = @explode(':', $server); - // this connection will close after XFR - @fclose($this->NSfp); - - $this->NSfp = @fsockopen($ip, $port, $errno, $errstr, $this->timeout); - if (!$this->NSfp) { - $this->error = "Can't connect to $ip:$port, error => $errno, $errstr"; - return false; - } - - // MSNP9 - // NS: >> VER {id} MSNP9 CVR0 - // MSNP15 - // NS: >>> VER {id} MSNP15 CVR0 - $this->ns_writeln("VER $this->id ".self::PROTOCOL.' CVR0'); - break; - - case 'GCF': - // return some policy data after 'USR {id} SSO I {user}' command - // NS: <<< GCF 0 {size} - @list(/* GCF */, /* 0 */, $size) = @explode(' ', $data); - // we don't need the data, just read it and drop - if (is_numeric($size) && $size > 0) - $this->ns_readdata($size); - break; - - default: - // we'll quit if got any error - if (is_numeric($code)) { - // logout now - // NS: >>> OUT - $this->ns_writeln("OUT"); - @fclose($this->NSfp); - $this->error = "Error code: $code, please check the detail information from: http://msnpiki.msnfanatic.com/index.php/Reference:Error_List"; - return false; - } - // unknown response from server, just ignore it - break; - } - } - // never goto here - } - - /** - * Sign onto the NS server and retrieve the address book - * - * @return void - */ - public function signon() { - /* FIXME Don't implement the signon as a loop or we could hang - * the queue handler! */ - $this->debug_message('*** Trying to connect to MSN network'); - - // Remove any remaining switchboard sessions - $this->switchBoardSessions = array(); - $this->switchBoardSessionLookup = array(); - - while (true) { - // Connect - if (!$this->connect($this->user, $this->password)) { - $this->signonFailure("!!! Could not connect to server: $this->error"); - continue; - } - - // Update contacts - if ($this->UpdateContacts() === false) { - $this->signonFailure(''); - continue; - } - - // Get membership lists - if (($this->aContactList = $this->getMembershipList()) === false) { - $this->signonFailure('!!! Get membership list failed'); - continue; - } - - if ($this->update_pending) { - if (is_array($this->aContactList)) { - $pending = 'Pending'; - foreach ($this->aContactList as $u_domain => $aUserList) { - foreach ($aUserList as $u_name => $aNetworks) { - foreach ($aNetworks as $network => $aData) { - if (isset($aData[$pending])) { - // pending list - $cnt = 0; - foreach (array('Allow', 'Reverse') as $list) { - if (isset($aData[$list])) - $cnt++; - else { - if ($this->addMemberToList($u_name.'@'.$u_domain, $network, $list)) { - $this->aContactList[$u_domain][$u_name][$network][$list] = false; - $cnt++; - } - } - } - if ($cnt >= 2) { - $id = $aData[$pending]; - // we can delete it from pending now - if ($this->delMemberFromList($id, $u_name.'@'.$u_domain, $network, $pending)) - unset($this->aContactList[$u_domain][$u_name][$network][$pending]); - } - } - else { - // sync list - foreach (array('Allow', 'Reverse') as $list) { - if (!isset($aData[$list])) { - if ($this->addMemberToList($u_name.'@'.$u_domain, $network, $list)) - $this->aContactList[$u_domain][$u_name][$network][$list] = false; - } - } - } - } - } - } - } - } - $n = 0; - $sList = ''; - $len = 0; - if (is_array($this->aContactList)) { - foreach ($this->aContactList as $u_domain => $aUserList) { - $str = ''; - $len += strlen($str); - if ($len > 7400) { - $this->aADL[$n] = ''.$sList.''; - $n++; - $sList = ''; - $len = strlen($str); - } - $sList .= $str; - foreach ($aUserList as $u_name => $aNetworks) { - foreach ($aNetworks as $network => $status) { - $str = ''; - $len += strlen($str); - // max: 7500, but is 19, - // so we use 7475 - if ($len > 7475) { - $sList .= ''; - $this->aADL[$n] = ''.$sList.''; - $n++; - $sList = ''.$str; - $len = strlen($sList); - } - else - $sList .= $str; - } - } - $sList .= ''; - } - } - $this->aADL[$n] = ''.$sList.''; - // NS: >>> BLP {id} BL - $this->ns_writeln("BLP $this->id BL"); - foreach ($this->aADL as $str) { - $len = strlen($str); - // NS: >>> ADL {id} {size} - $this->ns_writeln("ADL $this->id $len"); - $this->ns_writedata($str); - } - // NS: >>> PRP {id} MFN name - if ($this->alias == '') $this->alias = $user; - $aliasname = rawurlencode($this->alias); - $this->ns_writeln("PRP $this->id MFN $aliasname"); - //設定個人大頭貼 - //$MsnObj=$this->PhotoStckObj(); - // NS: >>> CHG {id} {status} {clientid} {msnobj} - $this->ns_writeln("CHG $this->id NLN $this->clientid"); - if ($this->PhotoStickerFile !== false) - $this->ns_writeln("CHG $this->id NLN $this->clientid ".rawurlencode($this->MsnObj($this->PhotoStickerFile))); - // NS: >>> UUX {id} length - $str = ''.htmlspecialchars($this->psm).''; - $len = strlen($str); - $this->ns_writeln("UUX $this->id $len"); - $this->ns_writedata($str); - if (!self::socketcheck($this->NSfp)) { - $this->debug_message('*** Connected, waiting for commands'); - break; - } else { - $this->NSRetryWait($this->retry_wait); - } - } - } - - /** - * Called if there is an error during signon - * - * @param string $message Error message to log - * @return void - */ - private function signonFailure($message) { - if(!empty($message)) { - $this->debug_message($message); - } - $this->callHandler('ConnectFailed', $message); - $this->NSRetryWait($this->retry_wait); - } - - /** - * Log out and close the NS connection - * - * @return void - */ - private function nsLogout() { - if (is_resource($this->NSfp) && !feof($this->NSfp)) { - // logout now - // NS: >>> OUT - $this->ns_writeln("OUT"); - fclose($this->NSfp); - $this->NSfp = false; - $this->debug_message("*** Logged out"); - } - } - - /** - * NS and SB command handling methods - */ - - /** - * Read and handle incoming command from NS - * - * @return void - */ - private function nsReceive() { - // Sign in again if not signed in or socket failed - if (!is_resource($this->NSfp) || self::socketcheck($this->NSfp)) { - $this->callHandler('Reconnect'); - $this->NSRetryWait($this->retry_wait); - $this->signon(); - return; - } - - $data = $this->ns_readln(); - if ($data === false) { - // There was no data / an error when reading from the socket so reconnect - $this->callHandler('Reconnect'); - $this->NSRetryWait($this->retry_wait); - $this->signon(); - return; - } - - switch (substr($data, 0, 3)) { - case 'SBS': - // after 'USR {id} OK {user} {verify} 0' response, the server will send SBS and profile to us - // NS: <<< SBS 0 null - break; - - case 'RFS': - // FIXME: - // NS: <<< RFS ??? - // refresh ADL, so we re-send it again - if (is_array($this->aADL)) { - foreach ($this->aADL as $str) { - $len = strlen($str); - // NS: >>> ADL {id} {size} - $this->ns_writeln("ADL $this->id $len"); - $this->ns_writedata($str); - } - } - break; - - case 'LST': - // NS: <<< LST {email} {alias} 11 0 - @list(/* LST */, $email) = @explode(' ', $data); - @list($u_name, $u_domain) = @explode('@', $email); - if (!isset($this->aContactList[$u_domain][$u_name][1])) { - $this->aContactList[$u_domain][$u_name][1]['Allow'] = 'Allow'; - $this->debug_message("*** Added to contact list: $u_name@$u_domain"); - } - break; - - case 'ADL': - // randomly, we get ADL command, someone add us to their contact list for MSNP15 - // NS: <<< ADL 0 {size} - @list(/* ADL */, /* 0 */, $size) = @explode(' ', $data); - if (is_numeric($size) && $size > 0) { - $data = $this->ns_readdata($size); - preg_match('##', $data, $matches); - if (is_array($matches) && count($matches) > 0) { - $u_domain = $matches[1]; - $u_name = $matches[2]; - $network = $matches[4]; - if (isset($this->aContactList[$u_domain][$u_name][$network])) - $this->debug_message("*** Someone (network: $network) added us to their list (but already in our list): $u_name@$u_domain"); - else { - $re_login = false; - $cnt = 0; - foreach (array('Allow', 'Reverse') as $list) { - if (!$this->addMemberToList($u_name.'@'.$u_domain, $network, $list)) { - if ($re_login) { - $this->debug_message("*** Could not add $u_name@$u_domain (network: $network) to $list list"); - continue; - } - $aTickets = $this->get_passport_ticket(); - if (!$aTickets || !is_array($aTickets)) { - // failed to login? ignore it - $this->debug_message("*** Could not re-login, something wrong here"); - $this->debug_message("*** Could not add $u_name@$u_domain (network: $network) to $list list"); - continue; - } - $re_login = true; - $this->ticket = $aTickets; - $this->debug_message("**** Got new ticket, trying again"); - if (!$this->addMemberToList($u_name.'@'.$u_domain, $network, $list)) { - $this->debug_message("*** Could not add $u_name@$u_domain (network: $network) to $list list"); - continue; - } - } - $this->aContactList[$u_domain][$u_name][$network][$list] = false; - $cnt++; - } - $this->debug_message("*** Someone (network: $network) added us to their list: $u_name@$u_domain"); - } - $str = ''; - $len = strlen($str); - - $this->callHandler('AddedToList', array('screenname' => $u_name.'@'.$u_domain, 'network' => $network)); - } - else - $this->debug_message("*** Someone added us to their list: $data"); - } - break; - - case 'RML': - // randomly, we get RML command, someome remove us to their contact list for MSNP15 - // NS: <<< RML 0 {size} - @list(/* RML */, /* 0 */, $size) = @explode(' ', $data); - if (is_numeric($size) && $size > 0) { - $data = $this->ns_readdata($size); - preg_match('##', $data, $matches); - if (is_array($matches) && count($matches) > 0) { - $u_domain = $matches[1]; - $u_name = $matches[2]; - $network = $matches[4]; - if (isset($this->aContactList[$u_domain][$u_name][$network])) { - $aData = $this->aContactList[$u_domain][$u_name][$network]; - - foreach ($aData as $list => $id) - $this->delMemberFromList($id, $u_name.'@'.$u_domain, $network, $list); - - unset($this->aContactList[$u_domain][$u_name][$network]); - $this->debug_message("*** Someone (network: $network) removed us from their list: $u_name@$u_domain"); - } - else - $this->debug_message("*** Someone (network: $network) removed us from their list (but not in our list): $u_name@$u_domain"); - - $this->callHandler('RemovedFromList', array('screenname' => $u_name.'@'.$u_domain, 'network' => $network)); - } - else - $this->debug_message("*** Someone removed us from their list: $data"); - } - break; - - case 'MSG': - // randomly, we get MSG notification from server - // NS: <<< MSG Hotmail Hotmail {size} - @list(/* MSG */, /* Hotmail */, /* Hotmail */, $size) = @explode(' ', $data); - if (is_numeric($size) && $size > 0) { - $data = $this->ns_readdata($size); - $aLines = @explode("\n", $data); - $header = true; - $ignore = false; - $maildata = ''; - foreach ($aLines as $line) { - $line = rtrim($line); - if ($header) { - if ($line === '') { - $header = false; - continue; - } - if (strncasecmp($line, 'Content-Type:', 13) == 0) { - if (strpos($line, 'text/x-msmsgsinitialmdatanotification') === false && strpos($line, 'text/x-msmsgsoimnotification') === false) { - // we just need text/x-msmsgsinitialmdatanotification - // or text/x-msmsgsoimnotification - $ignore = true; - break; - } - } - continue; - } - if (strncasecmp($line, 'Mail-Data:', 10) == 0) { - $maildata = trim(substr($line, 10)); - break; - } - } - if ($ignore) { - $this->debug_message("*** Ignoring MSG for: $line"); - break; - } - if ($maildata == '') { - $this->debug_message("*** Ignoring MSG not for OIM"); - break; - } - $re_login = false; - if (strcasecmp($maildata, 'too-large') == 0) { - $this->debug_message("*** Large mail-data, need to get the data via SOAP"); - $maildata = $this->getOIM_maildata(); - if ($maildata === false) { - $this->debug_message("*** Could not get mail-data via SOAP"); - - // maybe we need to re-login again - $aTickets = $this->get_passport_ticket(); - if (!$aTickets || !is_array($aTickets)) { - // failed to login? ignore it - $this->debug_message("*** Could not re-login, something wrong here, ignoring this OIM"); - break; - } - $re_login = true; - $this->ticket = $aTickets; - $this->debug_message("*** Got new ticket, trying again"); - $maildata = $this->getOIM_maildata(); - if ($maildata === false) { - $this->debug_message("*** Could not get mail-data via SOAP, and re-login already attempted, ignoring this OIM"); - break; - } - } - } - // could be a lots of ..., so we can't use preg_match here - $p = $maildata; - $aOIMs = array(); - while (1) { - $start = strpos($p, ''); - $end = strpos($p, ''); - if ($start === false || $end === false || $start > $end) break; - $end += 4; - $sOIM = substr($p, $start, $end - $start); - $aOIMs[] = $sOIM; - $p = substr($p, $end); - } - if (count($aOIMs) == 0) { - $this->debug_message("*** Ignoring empty OIM"); - break; - } - foreach ($aOIMs as $maildata) { - // T: 11 for MSN, 13 for Yahoo - // S: 6 for MSN, 7 for Yahoo - // RT: the datetime received by server - // RS: already read or not - // SZ: size of message - // E: sender - // I: msgid - // F: always 00000000-0000-0000-0000-000000000009 - // N: sender alias - preg_match('#(.*)#', $maildata, $matches); - if (count($matches) == 0) { - $this->debug_message("*** Ignoring OIM maildata without type"); - continue; - } - $oim_type = $matches[1]; - if ($oim_type = 13) - $network = 32; - else - $network = 1; - preg_match('#(.*)#', $maildata, $matches); - if (count($matches) == 0) { - $this->debug_message("*** Ignoring OIM maildata without sender"); - continue; - } - $oim_sender = $matches[1]; - preg_match('#(.*)#', $maildata, $matches); - if (count($matches) == 0) { - $this->debug_message("*** Ignoring OIM maildata without msgid"); - continue; - } - $oim_msgid = $matches[1]; - preg_match('#(.*)#', $maildata, $matches); - $oim_size = (count($matches) == 0) ? 0 : $matches[1]; - preg_match('#(.*)#', $maildata, $matches); - $oim_time = (count($matches) == 0) ? 0 : $matches[1]; - $this->debug_message("*** OIM received from $oim_sender, Time: $oim_time, MSGID: $oim_msgid, size: $oim_size"); - $sMsg = $this->getOIM_message($oim_msgid); - if ($sMsg === false) { - $this->debug_message("*** Could not get OIM, msgid = $oim_msgid"); - if ($re_login) { - $this->debug_message("*** Could not get OIM via SOAP, and re-login already attempted, ignoring this OIM"); - continue; - } - $aTickets = $this->get_passport_ticket(); - if (!$aTickets || !is_array($aTickets)) { - // failed to login? ignore it - $this->debug_message("*** Could not re-login, something wrong here, ignoring this OIM"); - continue; - } - $re_login = true; - $this->ticket = $aTickets; - $this->debug_message("*** get new ticket, try it again"); - $sMsg = $this->getOIM_message($oim_msgid); - if ($sMsg === false) { - $this->debug_message("*** Could not get OIM via SOAP, and re-login already attempted, ignoring this OIM"); - continue; - } - } - $this->debug_message("*** MSG (Offline) from $oim_sender (network: $network): $sMsg"); - $this->callHandler('IMin', array('sender' => $oim_sender, 'message' => $sMsg, 'network' => $network, 'offline' => true)); - } - } - break; - - case 'UBM': - // randomly, we get UBM, this is the message from other network, like Yahoo! - // NS: <<< UBM {email} $network $type {size} - @list(/* UBM */, $from_email, $network, $type, $size) = @explode(' ', $data); - if (is_numeric($size) && $size > 0) { - $data = $this->ns_readdata($size); - $aLines = @explode("\n", $data); - $header = true; - $ignore = false; - $sMsg = ''; - foreach ($aLines as $line) { - $line = rtrim($line); - if ($header) { - if ($line === '') { - $header = false; - continue; - } - if (strncasecmp($line, 'TypingUser:', 11) == 0) { - $ignore = true; - break; - } - continue; - } - $aSubLines = @explode("\r", $line); - foreach ($aSubLines as $str) { - if ($sMsg !== '') - $sMsg .= "\n"; - $sMsg .= $str; - } - } - if ($ignore) { - $this->debug_message("*** Ignoring message from $from_email: $line"); - break; - } - $this->debug_message("*** MSG from $from_email (network: $network): $sMsg"); - $this->callHandler('IMin', array('sender' => $from_email, 'message' => $sMsg, 'network' => $network, 'offline' => false)); - } - break; - - case 'UBX': - // randomly, we get UBX notification from server - // NS: <<< UBX email {network} {size} - @list(/* UBX */, /* email */, /* network */, $size) = @explode(' ', $data); - // we don't need the notification data, so just ignore it - if (is_numeric($size) && $size > 0) - $this->ns_readdata($size); - break; - - case 'CHL': - // randomly, we'll get challenge from server - // NS: <<< CHL 0 {code} - @list(/* CHL */, /* 0 */, $chl_code) = @explode(' ', $data); - $fingerprint = $this->getChallenge($chl_code); - // NS: >>> QRY {id} {product_id} 32 - // NS: >>> fingerprint - $this->ns_writeln("QRY $this->id ".self::PROD_ID.' 32'); - $this->ns_writedata($fingerprint); - $this->ns_writeln("CHG $this->id NLN $this->clientid"); - if ($this->PhotoStickerFile !== false) - $this->ns_writeln("CHG $this->id NLN $this->clientid ".rawurlencode($this->MsnObj($this->PhotoStickerFile))); - break; - case 'CHG': - // NS: <<< CHG {id} {status} {code} - // ignore it - // change our status to online first - break; - - case 'XFR': - // sometimes, NS will redirect to another NS - // MSNP9 - // NS: <<< XFR {id} NS {server} 0 {server} - // MSNP15 - // NS: <<< XFR {id} NS {server} U D - // for normal switchboard XFR - // NS: <<< XFR {id} SB {server} CKI {cki} U messenger.msn.com 0 - @list(/* XFR */, /* {id} */, $server_type, $server, /* CKI */, $cki_code) = @explode(' ', $data); - @list($ip, $port) = @explode(':', $server); - if ($server_type != 'SB') { - // maybe exit? - // this connection will close after XFR - $this->nsLogout(); - continue; - } - - $this->debug_message("NS: <<< XFR SB"); - $session = array_shift($this->waitingForXFR); - $this->connectToSBSession('Active', $ip, $port, $session['to'], array('cki' => $cki_code)); - break; - case 'QNG': - // NS: <<< QNG {time} - @list(/* QNG */, $ping_wait) = @explode(' ', $data); - $this->callHandler('Pong', $ping_wait); - break; - - case 'RNG': - if ($this->PhotoStickerFile !== false) - $this->ns_writeln("CHG $this->id NLN $this->clientid ".rawurlencode($this->MsnObj($this->PhotoStickerFile))); - else - $this->ns_writeln("CHG $this->id NLN $this->clientid"); - // someone is trying to talk to us - // NS: <<< RNG {session_id} {server} {auth_type} {ticket} {email} {alias} U {client} 0 - $this->debug_message("NS: <<< RNG $data"); - @list(/* RNG */, $sid, $server, /* auth_type */, $ticket, $email, $name) = @explode(' ', $data); - @list($sb_ip, $sb_port) = @explode(':', $server); - $this->debug_message("*** RING from $email, $sb_ip:$sb_port"); - $this->addContact($email, 1, $email, true); - $this->connectToSBSession('Passive', $sb_ip, $sb_port, $email, array('sid' => $sid, 'ticket' => $ticket)); - break; - - case 'NLN': - // NS: <<< NLN {status} {email} {networkid} {nickname} {clientid} {dpobj} - @list(/* NLN */, $status, $email, $network, $nickname) = @explode(' ', $data); - $this->callHandler('StatusChange', array('screenname' => $email, 'status' => $status, 'network' => $network, 'nickname' => $nickname)); - break; - - case 'OUT': - // force logout from NS - // NS: <<< OUT xxx - $this->debug_message("*** LOGOUT from NS"); - return $this->nsLogout(); - - default: - $code = substr($data,0,3); - if (is_numeric($code)) { - $this->error = "Error code: $code, please check the detail information from: http://msnpiki.msnfanatic.com/index.php/Reference:Error_List"; - $this->debug_message("*** NS: $this->error"); - - return $this->nsLogout(); - } - break; - } - } - - /** - * Read and handle incoming command/message from - * a switchboard session socket - */ - private function sbReceive($socket) { - $intsocket = (int) $socket; - $session = &$this->switchBoardSessions[$intsocket]; - - if (feof($socket)) { - // Unset session lookup value - unset($this->switchBoardSessionLookup[$session['to']]); - - // Unset session itself - unset($this->switchBoardSessions[$intsocket]); - return; - } - - $id = &$session['id']; - - $data = $this->sb_readln($socket); - $code = substr($data, 0, 3); - switch($code) { - case 'IRO': - // SB: <<< IRO {id} {rooster} {roostercount} {email} {alias} {clientid} - @list(/* IRO */, /* id */, $cur_num, $total, $email, $alias, $clientid) = @explode(' ', $data); - $this->debug_message("*** $email joined session"); - if ($email == $session['to']) { - $session['joined'] = true; - $this->callHandler('SessionReady', array('to' => $email)); - } - break; - case 'BYE': - $this->debug_message("*** Quit for BYE"); - $this->endSBSession($socket); - break; - case 'USR': - // SB: <<< USR {id} OK {user} {alias} - // we don't need the data, just ignore it - // request user to join this switchboard - // SB: >>> CAL {id} {user} - $this->sb_writeln($socket, $id, "CAL $id ".$session['to']); - break; - case 'CAL': - // SB: <<< CAL {id} RINGING {?} - // we don't need this, just ignore, and wait for other response - $session['id']++; - break; - case 'JOI': - // SB: <<< JOI {user} {alias} {clientid?} - // someone join us - @list(/* JOI */, $email) = @explode(' ', $data); - if ($email == $session['to']) { - $session['joined'] = true; - $this->callHandler('SessionReady', array('to' => $email)); - } - break; - case 'MSG': - // SB: <<< MSG {email} {alias} {len} - @list(/* MSG */, $from_email, /* alias */, $len) = @explode(' ', $data); - $len = trim($len); - $data = $this->sb_readdata($socket, $len); - $aLines = @explode("\n", $data); - $header = true; - $ignore = false; - $is_p2p = false; - $sMsg = ''; - foreach ($aLines as $line) { - $line = rtrim($line); - if ($header) { - if ($line === '') { - $header = false; - continue; - } - if (strncasecmp($line, 'TypingUser:', 11) == 0) { - // typing notification, just ignore - $ignore = true; - break; - } - if (strncasecmp($line, 'Chunk:', 6) == 0) { - // we don't handle any split message, just ignore - $ignore = true; - break; - } - if (strncasecmp($line, 'Content-Type: application/x-msnmsgrp2p', 38) == 0) { - // p2p message, ignore it, but we need to send acknowledgement for it... - $is_p2p = true; - $p = strstr($data, "\n\n"); - $sMsg = ''; - if ($p === false) { - $p = strstr($data, "\r\n\r\n"); - if ($p !== false) - $sMsg = substr($p, 4); - } - else - $sMsg = substr($p, 2); - break; - } - if (strncasecmp($line, 'Content-Type: application/x-', 28) == 0) { - // ignore all application/x-... message - // for example: - // application/x-ms-ink => ink message - $ignore = true; - break; - } - if (strncasecmp($line, 'Content-Type: text/x-', 21) == 0) { - // ignore all text/x-... message - // for example: - // text/x-msnmsgr-datacast => nudge, voice clip.... - // text/x-mms-animemoticon => customized animemotion word - $ignore = true; - break; - } - continue; - } - if ($sMsg !== '') - $sMsg .= "\n"; - $sMsg .= $line; - } - if ($ignore) { - $this->debug_message("*** Ignoring SB data from $from_email: $line"); - break; - } - if ($is_p2p) { - // we will ignore any p2p message after sending acknowledgement - $ignore = true; - $len = strlen($sMsg); - $this->debug_message("*** p2p message from $from_email, size $len"); - // header = 48 bytes - // content >= 0 bytes - // footer = 4 bytes - // so it need to >= 52 bytes - /*if ($len < 52) { - $this->debug_message("*** p2p: size error, less than 52!"); - break; - }*/ - $aDwords = @unpack("V12dword", $sMsg); - if (!is_array($aDwords)) { - $this->debug_message("*** p2p: header unpack error!"); - break; - } - $this->debug_message("*** p2p: dump received message:\n".$this->dump_binary($sMsg)); - $hdr_SessionID = $aDwords['dword1']; - $hdr_Identifier = $aDwords['dword2']; - $hdr_DataOffsetLow = $aDwords['dword3']; - $hdr_DataOffsetHigh = $aDwords['dword4']; - $hdr_TotalDataSizeLow = $aDwords['dword5']; - $hdr_TotalDataSizeHigh = $aDwords['dword6']; - $hdr_MessageLength = $aDwords['dword7']; - $hdr_Flag = $aDwords['dword8']; - $hdr_AckID = $aDwords['dword9']; - $hdr_AckUID = $aDwords['dword10']; - $hdr_AckSizeLow = $aDwords['dword11']; - $hdr_AckSizeHigh = $aDwords['dword12']; - $this->debug_message("*** p2p: header SessionID = $hdr_SessionID"); - $this->debug_message("*** p2p: header Inentifier = $hdr_Identifier"); - $this->debug_message("*** p2p: header Data Offset Low = $hdr_DataOffsetLow"); - $this->debug_message("*** p2p: header Data Offset High = $hdr_DataOffsetHigh"); - $this->debug_message("*** p2p: header Total Data Size Low = $hdr_TotalDataSizeLow"); - $this->debug_message("*** p2p: header Total Data Size High = $hdr_TotalDataSizeHigh"); - $this->debug_message("*** p2p: header MessageLength = $hdr_MessageLength"); - $this->debug_message("*** p2p: header Flag = $hdr_Flag"); - $this->debug_message("*** p2p: header AckID = $hdr_AckID"); - $this->debug_message("*** p2p: header AckUID = $hdr_AckUID"); - $this->debug_message("*** p2p: header AckSize Low = $hdr_AckSizeLow"); - $this->debug_message("*** p2p: header AckSize High = $hdr_AckSizeHigh"); - if ($hdr_Flag == 2) { - //This is an ACK from SB ignore.... - $this->debug_message("*** p2p: //This is an ACK from SB ignore....:\n"); - break; - } - $MsgBody = $this->linetoArray(substr($sMsg, 48, -4)); - $this->debug_message("*** p2p: body".print_r($MsgBody, true)); - if (($MsgBody['EUF-GUID']=='{A4268EEC-FEC5-49E5-95C3-F126696BDBF6}')&&($PictureFilePath=$this->GetPictureFilePath($MsgBody['Context']))) { - while (true) { - if ($this->sb_readln($socket) === false) break; - } - $this->debug_message("*** p2p: Inv hdr:\n".$this->dump_binary(substr($sMsg, 0, 48))); - preg_match('/{([0-9A-F\-]*)}/i', $MsgBody['Via'], $Matches); - $BranchGUID = $Matches[1]; - //it's an invite to send a display picture. - $new_id = ~$hdr_Identifier; - $hdr = pack( - "LLLLLLLLLLLL", $hdr_SessionID, - $new_id, - 0, 0, - $hdr_TotalDataSizeLow, $hdr_TotalDataSizeHigh, - 0, - 2, - $hdr_Identifier, - $hdr_AckID, - $hdr_TotalDataSizeLow, $hdr_TotalDataSizeHigh - ); - $footer = pack("L", 0); - $message = "MIME-Version: 1.0\r\nContent-Type: application/x-msnmsgrp2p\r\nP2P-Dest: $from_email\r\n\r\n$hdr$footer"; - $len = strlen($message); - $this->sb_writeln($socket, $id, "MSG $id D $len"); - $this->sb_writedata($socket, $message); - $this->debug_message("*** p2p: send display picture acknowledgement for $hdr_SessionID"); - $this->debug_message("*** p2p: Invite ACK message:\n".$this->dump_binary($message)); - $this->sb_readln($socket); // Read ACK; - $this->debug_message("*** p2p: Invite ACK Hdr:\n".$this->dump_binary($hdr)); - $new_id -= 3; - //Send 200 OK message - $MessageContent="SessionID: ".$MsgBody['SessionID']."\r\n\r\n".pack("C", 0); - $MessagePayload= - "MSNSLP/1.0 200 OK\r\n". - "To: \r\n". - "From: user.">\r\n". - "Via: ".$MsgBody['Via']."\r\n". - "CSeq: ".($MsgBody['CSeq']+1)."\r\n". - "Call-ID: ".$MsgBody['Call-ID']."\r\n". - "Max-Forwards: 0\r\n". - "Content-Type: application/x-msnmsgr-sessionreqbody\r\n". - "Content-Length: ".strlen($MessageContent)."\r\n\r\n". - $MessageContent; - $hdr_TotalDataSizeLow=strlen($MessagePayload); - $hdr_TotalDataSizeHigh=0; - $hdr = pack( - "LLLLLLLLLLLL", $hdr_SessionID, - $new_id, - 0, 0, - $hdr_TotalDataSizeLow, $hdr_TotalDataSizeHigh, - strlen($MessagePayload), - 0, - rand(), - 0, - 0, 0 - ); - - $message = - "MIME-Version: 1.0\r\n". - "Content-Type: application/x-msnmsgrp2p\r\n". - "P2P-Dest: $from_email\r\n\r\n$hdr$MessagePayload$footer"; - $this->sb_writeln($socket, $id, "MSG $id D ".strlen($message)); - $this->sb_writedata($socket, $message); - $this->debug_message("*** p2p: dump 200 ok message:\n".$this->dump_binary($message)); - $this->sb_readln($socket); // Read ACK; - - $this->debug_message("*** p2p: 200 ok:\n".$this->dump_binary($hdr)); - // send data preparation message - // send 4 null bytes as data - $hdr_TotalDataSizeLow = 4; - $hdr_TotalDataSizeHigh = 0 ; - $new_id++; - $hdr = pack( - "LLLLLLLLLLLL", - $MsgBody['SessionID'], - $new_id, - 0, 0, - $hdr_TotalDataSizeLow, $hdr_TotalDataSizeHigh, - $hdr_TotalDataSizeLow, - 0, - rand(), - 0, - 0, 0 - ); - $message = - "MIME-Version: 1.0\r\n". - "Content-Type: application/x-msnmsgrp2p\r\n". - "P2P-Dest: $from_email\r\n\r\n$hdr".pack('L', 0)."$footer"; - $this->sb_writeln($socket, $id, "MSG $id D ".strlen($message)); - $this->sb_writedata($socket, $message); - $this->debug_message("*** p2p: dump send Data preparation message:\n".$this->dump_binary($message)); - $this->debug_message("*** p2p: Data Prepare Hdr:\n".$this->dump_binary($hdr)); - $this->sb_readln($socket); // Read ACK; - - // send Data Content.. - $footer=pack('N',1); - $new_id++; - $FileSize=filesize($PictureFilePath); - if ($hTitle=fopen($PictureFilePath,'rb')) { - $Offset = 0; - //$new_id++; - while (!feof($hTitle)) { - $FileContent = fread($hTitle, 1024); - $FileContentSize = strlen($FileContent); - $hdr = pack( - "LLLLLLLLLLLL", - $MsgBody['SessionID'], - $new_id, - $Offset, 0, - $FileSize, 0, - $FileContentSize, - 0x20, - rand(), - 0, - 0, 0 - ); - $message = - "MIME-Version: 1.0\r\n". - "Content-Type: application/x-msnmsgrp2p\r\n". - "P2P-Dest: $from_email\r\n\r\n$hdr$FileContent$footer"; - $this->sb_writeln($socket, $id, "MSG $id D ".strlen($message)); - $this->sb_writedata($socket, $message); - $this->debug_message("*** p2p: dump send Data Content message $Offset / $FileSize :\n".$this->dump_binary($message)); - $this->debug_message("*** p2p: Data Content Hdr:\n".$this->dump_binary($hdr)); - //$this->SB_readln($socket);//Read ACK; - $Offset += $FileContentSize; - } - } - //Send Bye - /* - $MessageContent="\r\n".pack("C", 0); - $MessagePayload= - "BYE MSNMSGR:MSNSLP/1.0\r\n". - "To: \r\n". - "From: user.">\r\n". - "Via: MSNSLP/1.0/TLP ;branch={".$BranchGUID."}\r\n". - "CSeq: 0\r\n". - "Call-ID: ".$MsgBody['Call-ID']."\r\n". - "Max-Forwards: 0\r\n". - "Content-Type: application/x-msnmsgr-sessionclosebody\r\n". - "Content-Length: ".strlen($MessageContent)."\r\n\r\n".$MessageContent; - $footer=pack('N',0); - $hdr_TotalDataSizeLow=strlen($MessagePayload); - $hdr_TotalDataSizeHigh=0; - $new_id++; - $hdr = pack("LLLLLLLLLLLL", - 0, - $new_id, - 0, 0, - $hdr_TotalDataSizeLow, $hdr_TotalDataSizeHigh, - 0, - 0, - rand(), - 0, - 0,0); - $message = - "MIME-Version: 1.0\r\n". - "Content-Type: application/x-msnmsgrp2p\r\n". - "P2P-Dest: $from_email\r\n\r\n$hdr$MessagePayload$footer"; - $this->sb_writeln($socket, $id, "MSG $id D ".strlen($message)); - $id++; - $this->sb_writedata($socket, $message); - $this->debug_message("*** p2p: dump send BYE message :\n".$this->dump_binary($message)); - */ - break; - } - //TODO: - //if ($hdr_Flag == 2) { - // just send ACK... - // $this->sb_writeln($socket, $id, "ACK $id"); - // break; - //} - if ($hdr_SessionID == 4) { - // ignore? - $this->debug_message("*** p2p: ignore flag 4"); - break; - } - $finished = false; - if ($hdr_TotalDataSizeHigh == 0) { - // only 32 bites size - if (($hdr_MessageLength + $hdr_DataOffsetLow) == $hdr_TotalDataSizeLow) - $finished = true; - } - else { - // we won't accept any file transfer - // so I think we won't get any message size need to use 64 bits - // 64 bits size here, can't count directly... - $totalsize = base_convert(sprintf("%X%08X", $hdr_TotalDataSizeHigh, $hdr_TotalDataSizeLow), 16, 10); - $dataoffset = base_convert(sprintf("%X%08X", $hdr_DataOffsetHigh, $hdr_DataOffsetLow), 16, 10); - $messagelength = base_convert(sprintf("%X", $hdr_MessageLength), 16, 10); - $now_size = bcadd($dataoffset, $messagelength); - if (bccomp($now_size, $totalsize) >= 0) - $finished = true; - } - if (!$finished) { - // ignore not finished split packet - $this->debug_message("*** p2p: ignore split packet, not finished"); - break; - } - //$new_id = ~$hdr_Identifier; - /* - $new_id++; - $hdr = pack("LLLLLLLLLLLL", $hdr_SessionID, - $new_id, - 0, 0, - $hdr_TotalDataSizeLow, $hdr_TotalDataSizeHigh, - 0, - 2, - $hdr_Identifier, - $hdr_AckID, - $hdr_TotalDataSizeLow, $hdr_TotalDataSizeHigh); - $footer = pack("L", 0); - $message = "MIME-Version: 1.0\r\nContent-Type: application/x-msnmsgrp2p\r\nP2P-Dest: $from_email\r\n\r\n$hdr$footer"; - $len = strlen($message); - $this->sb_writeln($socket, $id, "MSG $id D $len"); - $id++; - $this->sb_writedata($socket, $message); - $this->debug_message("*** p2p: send acknowledgement for $hdr_SessionID"); - $this->debug_message("*** p2p: dump sent message:\n".$this->dump_binary($hdr.$footer)); - */ - break; - } - $this->debug_message("*** MSG from $from_email: $sMsg"); - $this->callHandler('IMin', array('sender' => $from_email, 'message' => $sMsg, 'network' => 1, 'offline' => false)); - break; - case '217': - $this->debug_message('*** User '.$session['to'].' is offline. Trying OIM.'); - $session['offline'] = true; - break; - default: - if (is_numeric($code)) { - $this->error = "Error code: $code, please check the detail information from: http://msnpiki.msnfanatic.com/index.php/Reference:Error_List"; - $this->debug_message("*** SB: $this->error"); - } - break; - } - } - - /** - * Checks for new data and calls appropriate methods - * - * This method is usually called in an infinite loop to keep checking for new data - * - * @return void - */ - public function receive() { - // First, get an array of sockets that have data that is ready to be read - $ready = array(); - $ready = $this->getSockets(); - $numrdy = stream_select($ready, $w = NULL, $x = NULL, NULL); - - // Now that we've waited for something, go through the $ready - // array and read appropriately - - foreach ($ready as $socket) { - if ($socket == $this->NSfp) { - $this->nsReceive(); - } else { - $this->sbReceive($socket); - } - } - } - - /** - * Switchboard related methods - */ - - /** - * Send a request for a switchboard session - * - * @param string $to Target email for switchboard session - */ - private function reqSBSession($to) { - $this->debug_message("*** Request SB for $to"); - $this->ns_writeln("XFR $this->id SB"); - - // Add to the queue of those waiting for a switchboard session reponse - $this->switchBoardSessions[$to] = array( - 'to' => $to, - 'socket' => NULL, - 'id' => 1, - 'joined' => false, - 'offline' => false, - 'XFRReqTime' => time() - ); - $this->waitingForXFR[$to] = &$this->switchBoardSessions[$to]; - } - - /** - * Following an XFR or RNG, connect to the switchboard session - * - * @param string $mode Mode, either 'Active' (in the case of XFR) or 'Passive' (in the case of RNG) - * @param string $ip IP of Switchboard - * @param integer $port Port of Switchboard - * @param string $to User on other end of Switchboard - * @param array $param Array of parameters - 'cki', 'ticket', 'sid' - * @return boolean true if successful - */ - private function connectToSBSession($mode, $ip, $port, $to, $param) { - $this->debug_message("*** SB: Trying to connect to switchboard server $ip:$port"); - - $socket = @fsockopen($ip, $port, $errno, $errstr, $this->timeout); - if (!$socket) { - $this->debug_message("*** SB: Can't connect to $ip:$port, error => $errno, $errstr"); - return false; - } - - // Store the socket in the lookup array - $this->switchBoardSessionLookup[$to] = $socket; - - // Store the socket in the sessions array - $this->switchBoardSessions[$to] = array( - 'to' => $to, - 'socket' => $socket, - 'id' => 1, - 'joined' => false, - 'offline' => false, - 'XFRReqTime' => time() - ); - - // Change the index of the session to the socket - $intsocket = (int) $socket; - $this->switchBoardSessions[$intsocket] = $this->switchBoardSessions[$to]; - unset($this->switchBoardSessions[$to]); - - $id = &$this->switchBoardSessions[$intsocket]['id']; - - if ($mode == 'Active') { - $cki_code = $param['cki']; - - // SB: >>> USR {id} {user} {cki} - $this->sb_writeln($socket, $id, "USR $id $this->user $cki_code"); - } else { - // Passive - $ticket = $param['ticket']; - $sid = $param['sid']; - - // SB: >>> ANS {id} {user} {ticket} {session_id} - $this->sb_writeln($socket, $id, "ANS $id $this->user $ticket $sid"); - } - } - - /** - * Called when we want to end a switchboard session - * or a switchboard session ends - * - * @param resource $socket Socket - * @param boolean $killsession Whether to delete the session - * @return void - */ - private function endSBSession($socket) { - if (!self::socketcheck($socket)) { - $this->sb_writeln($socket, $fake = 0, 'OUT'); - } - @fclose($socket); - - // Unset session lookup value - $intsocket = (int) $socket; - unset($this->switchBoardSessionLookup[$this->switchBoardSessions[$intsocket]['to']]); - - // Unset session itself - unset($this->switchBoardSessions[$intsocket]); - } - - /** - * Send a message via an existing SB session - * - * @param string $to Recipient for message - * @param string $message Message - * @return boolean true on success - */ - private function sendMessageViaSB($to, $message) { - $socket = $this->switchBoardSessionLookup[$to]; - if (self::socketcheck($socket)) { - return false; - } - - $id = &$this->switchBoardSessions[(int) $socket]['id']; - - $aMessage = $this->getMessage($message); - // CheckEmotion... - $MsnObjDefine = $this->GetMsnObjDefine($aMessage); - if ($MsnObjDefine !== '') { - $SendString = "MIME-Version: 1.0\r\nContent-Type: text/x-mms-emoticon\r\n\r\n$MsnObjDefine"; - $len = strlen($SendString); - - if ($this->sb_writeln($socket, $id, "MSG $id N $len") === false || - $this->sb_writedata($socket, $SendString) === false) { - $this->endSBSession($socket); - return false; - } - } - $len = strlen($aMessage); - - if ($this->sb_writeln($socket, $id, "MSG $id N $len") === false || - $this->sb_writedata($socket, $aMessage) === false) { - $this->endSBSession($socket); - return false; - } - - // Don't close the SB session, we might as well leave it open - return true; - } - - /** - * Send a message to a user on another network - * - * @param string $to Intended recipient - * @param string $message Message - * @param integer $network Network - * @return void - */ - private function sendOtherNetworkMessage($to, $message, $network) { - $message = $this->getMessage($message, $network); - $len = strlen($message); - if ($this->ns_writeln("UUM $this->id $to $network 1 $len") === false || - $this->ns_writedata($Message) === false) { - return false; - } - $this->debug_message("*** Sent to $to (network: $network):\n$Message"); - return true; - } - - /** - * Send a message - * - * @param string $to To address in form user@host.com(@network) - * where network is 1 for MSN, 32 for Yahoo - * and 'Offline' for offline messages - * @param string $message Message - * @param boolean &$waitForSession Boolean passed by reference, - * if set to true on return, message - * did not fail to send but is - * waiting for a valid session - * - * @return boolean true on success - */ - public function sendMessage($to, $message, &$waitForSession) { - if ($message != '') { - $toParts = explode('@', $to); - if(count($toParts) < 3) { - list($name, $host) = $toParts; - $network = 1; - } else { - list($name, $host, $network) = $toParts; - } - - $recipient = $name.'@'.$host; - - if ($network === 1) { - if (!isset($this->switchBoardSessionLookup[$recipient])) { - if (!isset($this->switchBoardSessions[$recipient]) || time() - $this->switchBoardSessions[$recipient]['XFRReqTime'] > $this->XFRReqTimeout) { - $this->debug_message("*** No existing SB session or request has timed out"); - $this->reqSBSession($recipient); - } - - $waitForSession = true; - return false; - } else { - $socket = $this->switchBoardSessionLookup[$recipient]; - $intsocket = (int) $socket; - if ($this->switchBoardSessions[$intsocket]['offline']) { - $this->debug_message("*** Contact ($recipient) offline, sending OIM"); - $this->endSBSession($socket); - $waitForSession = false; - return $this->sendMessage($recipient.'@Offline', $message); - } else { - if ($this->switchBoardSessions[$intsocket]['joined'] !== true) { - $this->debug_message("*** Recipient has not joined session, returning false"); - $waitForSession = true; - return false; - } - - $this->debug_message("*** Attempting to send message to $recipient using existing SB session"); - - if ($this->sendMessageViaSB($recipient, $message)) { - $this->debug_message('*** Message sent successfully'); - return true; - } - - $waitForSession = false; - return false; - } - } - } elseif ($network == 'Offline') { - //Send OIM - //FIXME: 修正Send OIM - $lockkey = ''; - $re_login = false; - for ($i = 0; $i < $this->oim_try; $i++) { - if (($oim_result = $this->sendOIM($recipient, $message, $lockkey)) === true) break; - if (is_array($oim_result) && $oim_result['challenge'] !== false) { - // need challenge lockkey - $this->debug_message("*** Need challenge code for ".$oim_result['challenge']); - $lockkey = $this->getChallenge($oim_result['challenge']); - continue; - } - if ($oim_result === false || $oim_result['auth_policy'] !== false) { - if ($re_login) { - $this->debug_message("*** Can't send OIM, but we already re-logged-in again, so returning false"); - return false; - } - $this->debug_message("*** Can't send OIM, maybe ticket expired, trying to login again"); - - // Maybe we need to re-login again - if (!$this->get_passport_ticket()) { - $this->debug_message("*** Can't re-login, something went wrong here, returning false"); - return false; - } - $this->debug_message("*** Getting new ticket and trying again"); - continue; - } - } - return true; - } else { - // Other network - return $this->sendOtherNetworkMessage($recipient, $message, $network); - } - } - return true; - } - - /** - * OIM methods - */ - - /** - * Get OIM mail data - * - * @return string mail data or false on failure - */ - function getOIM_maildata() { - preg_match('#t=(.*)&p=(.*)#', $this->ticket['web_ticket'], $matches); - if (count($matches) == 0) { - $this->debug_message('*** No web ticket?'); - return false; - } - $t = htmlspecialchars($matches[1]); - $p = htmlspecialchars($matches[2]); - $XML = ' - - - - '.$t.' -

'.$p.'

-
-
- - - -
'; - - $header_array = array( - 'SOAPAction: '.self::OIM_MAILDATA_SOAP, - 'Content-Type: text/xml; charset=utf-8', - 'User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; Messenger '.self::BUILDVER.')' - ); - - $this->debug_message('*** URL: '.self::OIM_MAILDATA_URL); - $this->debug_message("*** Sending SOAP:\n$XML"); - $curl = curl_init(); - curl_setopt($curl, CURLOPT_URL, self::OIM_MAILDATA_URL); - curl_setopt($curl, CURLOPT_HTTPHEADER, $header_array); - curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1); - curl_setopt($curl, CURLOPT_FOLLOWLOCATION, 1); - curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, 0); - if ($this->debug) curl_setopt($curl, CURLOPT_HEADER, 1); - curl_setopt($curl, CURLOPT_POST, 1); - curl_setopt($curl, CURLOPT_POSTFIELDS, $XML); - $data = curl_exec($curl); - $http_code = curl_getinfo($curl, CURLINFO_HTTP_CODE); - curl_close($curl); - $this->debug_message("*** Get Result:\n$data"); - - if ($http_code != 200) { - $this->debug_message("*** Could not get OIM maildata! http code: $http_code"); - return false; - } - - // See #XML_Data - preg_match('#]*)>(.*)#', $data, $matches); - if (count($matches) == 0) { - $this->debug_message('*** Could not get OIM maildata'); - return false; - } - return $matches[2]; - } - - /** - * Fetch OIM message with given id - * - * @param string $msgid - * @return string Message or false on failure - */ - function getOIM_message($msgid) { - preg_match('#t=(.*)&p=(.*)#', $this->ticket['web_ticket'], $matches); - if (count($matches) == 0) { - $this->debug_message('*** No web ticket?'); - return false; - } - $t = htmlspecialchars($matches[1]); - $p = htmlspecialchars($matches[2]); - - // read OIM - $XML = ' - - - - '.$t.' -

'.$p.'

-
-
- - - '.$msgid.' - false - - -
'; - - $header_array = array( - 'SOAPAction: '.self::OIM_READ_SOAP, - 'Content-Type: text/xml; charset=utf-8', - 'User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; Messenger '.self::BUILDVER.')' - ); - - $this->debug_message('*** URL: '.self::OIM_READ_URL); - $this->debug_message("*** Sending SOAP:\n$XML"); - $curl = curl_init(); - curl_setopt($curl, CURLOPT_URL, self::OIM_READ_URL); - curl_setopt($curl, CURLOPT_HTTPHEADER, $header_array); - curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1); - curl_setopt($curl, CURLOPT_FOLLOWLOCATION, 1); - curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, 0); - if ($this->debug) curl_setopt($curl, CURLOPT_HEADER, 1); - curl_setopt($curl, CURLOPT_POST, 1); - curl_setopt($curl, CURLOPT_POSTFIELDS, $XML); - $data = curl_exec($curl); - $http_code = curl_getinfo($curl, CURLINFO_HTTP_CODE); - curl_close($curl); - $this->debug_message("*** Get Result:\n$data"); - - if ($http_code != 200) { - $this->debug_message("*** Can't get OIM: $msgid, http code = $http_code"); - return false; - } - - // why can't use preg_match('#(.*)#', $data, $matches)? - // multi-lines? - $start = strpos($data, ''); - $end = strpos($data, ''); - if ($start === false || $end === false || $start > $end) { - $this->debug_message("*** Can't get OIM: $msgid"); - return false; - } - $lines = substr($data, $start + 18, $end - $start); - $aLines = @explode("\n", $lines); - $header = true; - $ignore = false; - $sOIM = ''; - foreach ($aLines as $line) { - $line = rtrim($line); - if ($header) { - if ($line === '') { - $header = false; - continue; - } - continue; - } - // stop at empty lines - if ($line === '') break; - $sOIM .= $line; - } - $sMsg = base64_decode($sOIM); - //$this->debug_message("*** we get OIM ($msgid): $sMsg"); - - // delete OIM - $XML = ' - - - - '.$t.' -

'.$p.'

-
-
- - - - '.$msgid.' - - - -
'; - - $header_array = array( - 'SOAPAction: '.self::OIM_DEL_SOAP, - 'Content-Type: text/xml; charset=utf-8', - 'User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; Messenger '.self::BUILDVER.')' - ); - - $this->debug_message('*** URL: '.self::OIM_DEL_URL); - $this->debug_message("*** Sending SOAP:\n$XML"); - $curl = curl_init(); - curl_setopt($curl, CURLOPT_URL, self::OIM_DEL_URL); - curl_setopt($curl, CURLOPT_HTTPHEADER, $header_array); - curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1); - curl_setopt($curl, CURLOPT_FOLLOWLOCATION, 1); - curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, 0); - if ($this->debug) curl_setopt($curl, CURLOPT_HEADER, 1); - curl_setopt($curl, CURLOPT_POST, 1); - curl_setopt($curl, CURLOPT_POSTFIELDS, $XML); - $data = curl_exec($curl); - $http_code = curl_getinfo($curl, CURLINFO_HTTP_CODE); - curl_close($curl); - $this->debug_message("*** Get Result:\n$data"); - - if ($http_code != 200) - $this->debug_message("*** Could not delete OIM: $msgid, http code = $http_code"); - else - $this->debug_message("*** OIM ($msgid) deleted"); - return $sMsg; - } - - /** - * Send offline message - * - * @param string $to Intended recipient - * @param string $sMessage Message - * @param string $lockkey Lock key - * @return mixed true on success or error data - */ - private function sendOIM($to, $sMessage, $lockkey) { - $XML = ' - - - - - - - http://messenger.msn.com - 1 - - - - text - MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: base64 -X-OIM-Message-Type: OfflineMessage -X-OIM-Run-Id: {DAB68CFA-38C9-449B-945E-38AFA51E50A7} -X-OIM-Sequence-Num: 1 - -'.chunk_split(base64_encode($sMessage)).' - - -'; - - $header_array = array( - 'SOAPAction: '.self::OIM_SEND_SOAP, - 'Content-Type: text/xml', - 'User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; Messenger '.self::BUILDVER.')' - ); - - $this->debug_message('*** URL: '.self::OIM_SEND_URL); - $this->debug_message("*** Sending SOAP:\n$XML"); - $curl = curl_init(); - curl_setopt($curl, CURLOPT_URL, self::OIM_SEND_URL); - curl_setopt($curl, CURLOPT_HTTPHEADER, $header_array); - curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1); - curl_setopt($curl, CURLOPT_FOLLOWLOCATION, 1); - curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, 0); - if ($this->debug) curl_setopt($curl, CURLOPT_HEADER, 1); - curl_setopt($curl, CURLOPT_POST, 1); - curl_setopt($curl, CURLOPT_POSTFIELDS, $XML); - $data = curl_exec($curl); - $http_code = curl_getinfo($curl, CURLINFO_HTTP_CODE); - curl_close($curl); - $this->debug_message("*** Get Result:\n$data"); - - if ($http_code == 200) { - $this->debug_message("*** OIM sent for $to"); - return true; - } - - $challenge = false; - $auth_policy = false; - // the lockkey is invalid, authenticated fail, we need challenge it again - // 364763969 - preg_match("#(.*)#", $data, $matches); - if (count($matches) != 0) { - // yes, we get new LockKeyChallenge - $challenge = $matches[2]; - $this->debug_message("*** OIM need new challenge ($challenge) for $to"); - } - // auth policy error - // MBI_SSL - preg_match("#(.*)#", $data, $matches); - if (count($matches) != 0) { - $auth_policy = $matches[2]; - $this->debug_message("*** OIM need new auth policy ($auth_policy) for $to"); - } - if ($auth_policy === false && $challenge === false) { - //q0:AuthenticationFailed - preg_match("#(.*)#", $data, $matches); - if (count($matches) == 0) { - // no error, we assume the OIM is sent - $this->debug_message("*** OIM sent for $to"); - return true; - } - $err_code = $matches[2]; - //Exception of type 'System.Web.Services.Protocols.SoapException' was thrown. - preg_match("#(.*)#", $data, $matches); - if (count($matches) > 0) - $err_msg = $matches[1]; - else - $err_msg = ''; - $this->debug_message("*** OIM failed for $to"); - $this->debug_message("*** OIM Error code: $err_code"); - $this->debug_message("*** OIM Error Message: $err_msg"); - return false; - } - return array('challenge' => $challenge, 'auth_policy' => $auth_policy); - } - - /** - * Contact / Membership list methods - */ - - /** - * Fetch contact list - * - * @return boolean true on success - */ - private function UpdateContacts() { - $ABApplicationHeaderArray = array( - 'ABApplicationHeader' => array( - ':' => array('xmlns' => 'http://www.msn.com/webservices/AddressBook'), - 'ApplicationId' => 'CFE80F9D-180F-4399-82AB-413F33A1FA11', - 'IsMigration' => false, - 'PartnerScenario' => 'ContactSave' - ) - ); - - $ABApplicationHeader = new SoapHeader('http://www.msn.com/webservices/AddressBook', 'ABApplicationHeader', $this->Array2SoapVar($ABApplicationHeaderArray)); - $ABFindAllArray = array( - 'ABFindAll' => array( - ':' => array('xmlns'=>'http://www.msn.com/webservices/AddressBook'), - 'abId' => '00000000-0000-0000-0000-000000000000', - 'abView' => 'Full', - 'lastChange' => '0001-01-01T00:00:00.0000000-08:00', - ) - ); - $ABFindAll = new SoapParam($this->Array2SoapVar($ABFindAllArray), 'ABFindAll'); - $this->ABService->__setSoapHeaders(array($ABApplicationHeader, $this->ABAuthHeader)); - $this->Contacts = array(); - try { - $this->debug_message('*** Updating Contacts...'); - $Result = $this->ABService->ABFindAll($ABFindAll); - $this->debug_message("*** Result:\n".print_r($Result, true)."\n".$this->ABService->__getLastResponse()); - foreach($Result->ABFindAllResult->contacts->Contact as $Contact) - $this->Contacts[$Contact->contactInfo->passportName] = $Contact; - } catch(Exception $e) { - $this->debug_message("*** Update Contacts Error \nRequest:".$this->ABService->__getLastRequest()."\nError:".$e->getMessage()); - return false; - } - return true; - } - - /** - * Add contact - * - * @param string $email - * @param integer $network - * @param string $display - * @param boolean $sendADL - * @return boolean true on success - */ - private function addContact($email, $network, $display = '', $sendADL = false) { - if ($network != 1) return true; - if (isset($this->Contacts[$email])) return true; - - $ABContactAddArray = array( - 'ABContactAdd' => array( - ':' => array('xmlns' => 'http://www.msn.com/webservices/AddressBook'), - 'abId' => '00000000-0000-0000-0000-000000000000', - 'contacts' => array( - 'Contact' => array( - ':' => array('xmlns' => 'http://www.msn.com/webservices/AddressBook'), - 'contactInfo' => array( - 'contactType' => 'LivePending', - 'passportName' => $email, - 'isMessengerUser' => true, - 'MessengerMemberInfo' => array( - 'DisplayName' => $email - ) - ) - ) - ), - 'options' => array( - 'EnableAllowListManagement' => true - ) - ) - ); - $ABContactAdd = new SoapParam($this->Array2SoapVar($ABContactAddArray), 'ABContactAdd'); - try { - $this->debug_message("*** Adding Contact $email..."); - $this->ABService->ABContactAdd($ABContactAdd); - } catch(Exception $e) { - $this->debug_message("*** Add Contact Error \nRequest:".$this->ABService->__getLastRequest()."\nError:".$e->getMessage()); - return false; - } - if ($sendADL && !feof($this->NSfp)) { - @list($u_name, $u_domain) = @explode('@', $email); - foreach (array('1', '2') as $l) { - $str = ''; - $len = strlen($str); - // NS: >>> ADL {id} {size} - $this->ns_writeln("ADL $this->id $len"); - $this->ns_writedata($str); - } - } - $this->UpdateContacts(); - return true; - } - - /** - * Remove contact from list - * - * @param integer $memberID - * @param string $email - * @param integer $network - * @param string $list - */ - function delMemberFromList($memberID, $email, $network, $list) { - if ($network != 1 && $network != 32) return true; - if ($memberID === false) return true; - $user = $email; - $ticket = htmlspecialchars($this->ticket['contact_ticket']); - if ($network == 1) - $XML = ' - - - - 996CDE1E-AA53-4477-B943-2BE802EA6166 - false - ContactMsgrAPI - - - false - '.$ticket.' - - - - - - 0 - Messenger - - - - - '.$list.' - - - Passport - '.$memberID.' - Accepted - - - - - - -'; - else - $XML = ' - - - - 996CDE1E-AA53-4477-B943-2BE802EA6166 - false - ContactMsgrAPI - - - false - '.$ticket.' - - - - - - 0 - Messenger - - - - - '.$list.' - - - Email - '.$memberID.' - Accepted - - - - - - -'; - - $header_array = array( - 'SOAPAction: '.self::DELMEMBER_SOAP, - 'Content-Type: text/xml; charset=utf-8', - 'User-Agent: MSN Explorer/9.0 (MSN 8.0; TmstmpExt)' - ); - - $this->debug_message('*** URL: '.self::DELMEMBER_URL); - $this->debug_message("*** Sending SOAP:\n$XML"); - $curl = curl_init(); - curl_setopt($curl, CURLOPT_URL, self::DELMEMBER_URL); - curl_setopt($curl, CURLOPT_HTTPHEADER, $header_array); - curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1); - curl_setopt($curl, CURLOPT_FOLLOWLOCATION, 1); - curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, 0); - if ($this->debug) curl_setopt($curl, CURLOPT_HEADER, 1); - curl_setopt($curl, CURLOPT_POST, 1); - curl_setopt($curl, CURLOPT_POSTFIELDS, $XML); - $data = curl_exec($curl); - $http_code = curl_getinfo($curl, CURLINFO_HTTP_CODE); - curl_close($curl); - $this->debug_message("*** Get Result:\n$data"); - - if ($http_code != 200) { - preg_match('#(.*)(.*)#', $data, $matches); - if (count($matches) == 0) { - $this->debug_message("*** Could not delete member (network: $network) $email ($memberID) from $list list"); - return false; - } - $faultcode = trim($matches[1]); - $faultstring = trim($matches[2]); - if (strcasecmp($faultcode, 'soap:Client') || stripos($faultstring, 'Member does not exist') === false) { - $this->debug_message("*** Could not delete member (network: $network) $email ($memberID) from $list list, error code: $faultcode, $faultstring"); - return false; - } - $this->debug_message("*** Could not delete member (network: $network) $email ($memberID) from $list list, not present in list"); - return true; - } - $this->debug_message("*** Member successfully deleted (network: $network) $email ($memberID) from $list list"); - return true; - } - - /** - * Add contact to list - * - * @param string $email - * @param integer $network - * @param string $list - */ - function addMemberToList($email, $network, $list) { - if ($network != 1 && $network != 32) return true; - $ticket = htmlspecialchars($this->ticket['contact_ticket']); - $user = $email; - - if ($network == 1) - $XML = ' - - - - 996CDE1E-AA53-4477-B943-2BE802EA6166 - false - ContactMsgrAPI - - - false - '.$ticket.' - - - - - - 0 - Messenger - - - - - '.$list.' - - - Passport - Accepted - '.$user.' - - - - - - -'; - else - $XML = ' - - - - 996CDE1E-AA53-4477-B943-2BE802EA6166 - false - ContactMsgrAPI - - - false - '.$ticket.' - - - - - - 0 - Messenger - - - - - '.$list.' - - - Email - Accepted - '.$user.' - - - MSN.IM.BuddyType - 32:YAHOO - - - - - - - - -'; - $header_array = array( - 'SOAPAction: '.self::ADDMEMBER_SOAP, - 'Content-Type: text/xml; charset=utf-8', - 'User-Agent: MSN Explorer/9.0 (MSN 8.0; TmstmpExt)' - ); - - $this->debug_message('*** URL: '.self::ADDMEMBER_URL); - $this->debug_message("*** Sending SOAP:\n$XML"); - $curl = curl_init(); - curl_setopt($curl, CURLOPT_URL, self::ADDMEMBER_URL); - curl_setopt($curl, CURLOPT_HTTPHEADER, $header_array); - curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1); - curl_setopt($curl, CURLOPT_FOLLOWLOCATION, 1); - curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, 0); - if ($this->debug) curl_setopt($curl, CURLOPT_HEADER, 1); - curl_setopt($curl, CURLOPT_POST, 1); - curl_setopt($curl, CURLOPT_POSTFIELDS, $XML); - $data = curl_exec($curl); - $http_code = curl_getinfo($curl, CURLINFO_HTTP_CODE); - curl_close($curl); - $this->debug_message("*** Get Result:\n$data"); - - if ($http_code != 200) { - preg_match('#(.*)(.*)#', $data, $matches); - if (count($matches) == 0) { - $this->debug_message("*** Could not add member (network: $network) $email to $list list"); - return false; - } - $faultcode = trim($matches[1]); - $faultstring = trim($matches[2]); - if (strcasecmp($faultcode, 'soap:Client') || stripos($faultstring, 'Member already exists') === false) { - $this->debug_message("*** Could not add member (network: $network) $email to $list list, error code: $faultcode, $faultstring"); - return false; - } - $this->debug_message("*** Could not add member (network: $network) $email to $list list, already present"); - return true; - } - $this->debug_message("*** Member successfully added (network: $network) $email to $list list"); - return true; - } - - /** - * Get membership lists - * - * @param mixed $returnData Membership list or false on failure - */ - function getMembershipList($returnData = false) { - $ticket = htmlspecialchars($this->ticket['contact_ticket']); - $XML = ' - - - - 996CDE1E-AA53-4477-B943-2BE802EA6166 - false - Initial - - - false - '.$ticket.' - - - - - - - Messenger - Invitation - SocialNetwork - Space - Profile - - - - -'; - $header_array = array( - 'SOAPAction: '.self::MEMBERSHIP_SOAP, - 'Content-Type: text/xml; charset=utf-8', - 'User-Agent: MSN Explorer/9.0 (MSN 8.0; TmstmpExt)' - ); - $this->debug_message('*** URL: '.self::MEMBERSHIP_URL); - $this->debug_message("*** Sending SOAP:\n$XML"); - $curl = curl_init(); - curl_setopt($curl, CURLOPT_URL, self::MEMBERSHIP_URL); - curl_setopt($curl, CURLOPT_HTTPHEADER, $header_array); - curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1); - curl_setopt($curl, CURLOPT_FOLLOWLOCATION, 1); - curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, 0); - if ($this->debug) curl_setopt($curl, CURLOPT_HEADER, 1); - curl_setopt($curl, CURLOPT_POST, 1); - curl_setopt($curl, CURLOPT_POSTFIELDS, $XML); - $data = curl_exec($curl); - $http_code = curl_getinfo($curl, CURLINFO_HTTP_CODE); - curl_close($curl); - $this->debug_message("*** Get Result:\n$data"); - - if ($http_code != 200) return false; - $p = $data; - $aMemberships = array(); - while (1) { - //$this->debug_message("search p = $p"); - $start = strpos($p, ''); - $end = strpos($p, ''); - if ($start === false || $end === false || $start > $end) break; - //$this->debug_message("start = $start, end = $end"); - $end += 13; - $sMembership = substr($p, $start, $end - $start); - $aMemberships[] = $sMembership; - //$this->debug_message("add sMembership = $sMembership"); - $p = substr($p, $end); - } - //$this->debug_message("aMemberships = ".var_export($aMemberships, true)); - - $aContactList = array(); - foreach ($aMemberships as $sMembership) { - //$this->debug_message("sMembership = $sMembership"); - if (isset($matches)) unset($matches); - preg_match('#(.*)#', $sMembership, $matches); - if (count($matches) == 0) continue; - $sMemberRole = $matches[1]; - //$this->debug_message("MemberRole = $sMemberRole"); - if ($sMemberRole != 'Allow' && $sMemberRole != 'Reverse' && $sMemberRole != 'Pending') continue; - $p = $sMembership; - if (isset($aMembers)) unset($aMembers); - $aMembers = array(); - while (1) { - //$this->debug_message("search p = $p"); - $start = strpos($p, 'debug_message("add sMember = $sMember"); - $p = substr($p, $end); - } - //$this->debug_message("aMembers = ".var_export($aMembers, true)); - foreach ($aMembers as $sMember) { - //$this->debug_message("sMember = $sMember"); - if (isset($matches)) unset($matches); - preg_match('##', $sMember, $matches); - if (count($matches) == 0) continue; - $sMemberType = $matches[1]; - //$this->debug_message("MemberType = $sMemberType"); - $network = -1; - preg_match('#(.*)#', $sMember, $matches); - if (count($matches) == 0) continue; - $id = $matches[1]; - if ($sMemberType == 'PassportMember') { - if (strpos($sMember, 'Passport') === false) continue; - $network = 1; - preg_match('#(.*)#', $sMember, $matches); - } - else if ($sMemberType == 'EmailMember') { - if (strpos($sMember, 'Email') === false) continue; - // Value is 32: or 32:YAHOO - preg_match('#MSN.IM.BuddyType(.*):(.*)#', $sMember, $matches); - if (count($matches) == 0) continue; - if ($matches[1] != 32) continue; - $network = 32; - preg_match('#(.*)#', $sMember, $matches); - } - if ($network == -1) continue; - if (count($matches) > 0) { - $email = $matches[1]; - @list($u_name, $u_domain) = @explode('@', $email); - if ($u_domain == NULL) continue; - $aContactList[$u_domain][$u_name][$network][$sMemberRole] = $id; - $this->debug_message("*** Adding new contact (network: $network, status: $sMemberRole): $u_name@$u_domain ($id)"); - } - } - } - return $aContactList; - } - - /** - * MsnObj related methods - */ - - /** - * - * @param $FilePath 圖檔路徑 - * @param $Type 檔案類型 3=>大頭貼,2表情圖案 - * @return array - */ - private function MsnObj($FilePath, $Type = 3) { - if (!($FileSize=filesize($FilePath))) return ''; - $Location = md5($FilePath); - $Friendly = md5($FilePath.$Type); - if (isset($this->MsnObjMap[$Location])) return $this->MsnObjMap[$Location]; - $sha1d = base64_encode(sha1(file_get_contents($FilePath), true)); - $sha1c = base64_encode(sha1("Creator".$this->user."Size$FileSize"."Type$Type"."Location$Location"."Friendly".$Friendly."SHA1D$sha1d", true)); - $this->MsnObjArray[$Location] = $FilePath; - $MsnObj = ''; - $this->MsnObjMap[$Location] = $MsnObj; - $this->debug_message("*** p2p: addMsnObj $FilePath::$MsnObj\n"); - return $MsnObj; - } - - private function GetPictureFilePath($Context) { - $MsnObj = base64_decode($Context); - if (preg_match('/location="(.*?)"/i', $MsnObj, $Match)) - $location = $Match[1]; - $this->debug_message("*** p2p: PictureFile[$location] ::All".print_r($this->MsnObjArray,true)."\n"); - if ($location && isset($this->MsnObjArray[$location])) - return $this->MsnObjArray[$location]; - return false; - } - - private function GetMsnObjDefine($Message) { - $DefineString = ''; - if (is_array($this->Emotions)) - foreach ($this->Emotions as $Pattern => $FilePath) { - if (strpos($Message, $Pattern) !== false) - $DefineString .= "$Pattern\t".$this->MsnObj($FilePath, 2)."\t"; - } - return $DefineString; - } - - /** - * Socket methods - */ - - /** - * Read data of specified size from NS socket - * - * @param integer $size Size to read - * @return string Data read - */ - private function ns_readdata($size) { - $data = ''; - $count = 0; - while (!feof($this->NSfp)) { - $buf = @fread($this->NSfp, $size - $count); - $data .= $buf; - $count += strlen($buf); - if ($count >= $size) break; - } - $this->debug_message("NS: data ($size/$count) <<<\n$data"); - return $data; - } - - /** - * Read line from the NS socket - * - * @return string Data read - */ - private function ns_readln() { - $data = @fgets($this->NSfp, 4096); - if ($data !== false) { - $data = trim($data); - $this->debug_message("NS: <<< $data"); - } - return $data; - } - - /** - * Write line to NS socket - * - * Also increments id - * - * @param string $data Line to write to socket - * @return mixed Bytes written or false on failure - */ - private function ns_writeln($data) { - $result = @fwrite($this->NSfp, $data."\r\n"); - if ($result !== false) { - $this->debug_message("NS: >>> $data"); - $this->id++; - } - return $result; - } - - /** - * Write data to NS socket - * - * @param string $data Data to write to socket - * @return mixed Bytes written or false on failure - */ - private function ns_writedata($data) { - $result = @fwrite($this->NSfp, $data); - if ($result !== false) { - $this->debug_message("NS: >>> $data"); - } - return $result; - } - - /** - * Read data of specified size from given SB socket - * - * @param resource $socket SB socket - * @param integer $size Size to read - * @return string Data read - */ - private function sb_readdata($socket, $size) { - $data = ''; - $count = 0; - while (!feof($socket)) { - $buf = @fread($socket, $size - $count); - $data .= $buf; - $count += strlen($buf); - if ($count >= $size) break; - } - $this->debug_message("SB: data ($size/$count) <<<\n$data"); - return $data; - } - - /** - * Read line from given SB socket - * - * @param resource $socket SB Socket - * @return string Line read - */ - private function sb_readln($socket) { - $data = @fgets($socket, 4096); - if ($data !== false) { - $data = trim($data); - $this->debug_message("SB: <<< $data"); - } - return $data; - } - - /** - * Write line to given SB socket - * - * Also increments id - * - * @param resource $socket SB socket - * @param integer $id Reference to SB id - * @param string $data Line to write - * @return mixed Bytes written or false on error - */ - private function sb_writeln($socket, &$id, $data) { - $result = @fwrite($socket, $data."\r\n"); - if ($result !== false) { - $this->debug_message("SB: >>> $data"); - $id++; - } - return $result; - } - - /** - * Write data to given SB socket - * - * @param resource $socket SB socket - * @param $data Data to write to socket - * @return mixed Bytes written or false on error - */ - private function sb_writedata($socket, $data) { - $result = @fwrite($socket, $data); - if ($result !== false) { - $this->debug_message("SB: >>> $data"); - } - return $result; - } - - /** - * Get all the sockets currently in use - * - * @return array Array of socket resources - */ - public function getSockets() { - return array_merge(array($this->NSfp), $this->switchBoardSessionLookup); - } - - /** - * Checks socket for end of file - * - * @param resource $socket Socket to check - * @return boolean true if end of file (socket) - */ - private static function socketcheck($socket){ - $info = stream_get_meta_data($socket); - return $info['eof']; - } - - /** - * Key generation methods - */ - - private function derive_key($key, $magic) { - $hash1 = $this->mhash_sha1($magic, $key); - $hash2 = $this->mhash_sha1($hash1.$magic, $key); - $hash3 = $this->mhash_sha1($hash1, $key); - $hash4 = $this->mhash_sha1($hash3.$magic, $key); - return $hash2.substr($hash4, 0, 4); - } - - private function generateLoginBLOB($key, $challenge) { - $key1 = base64_decode($key); - $key2 = $this->derive_key($key1, 'WS-SecureConversationSESSION KEY HASH'); - $key3 = $this->derive_key($key1, 'WS-SecureConversationSESSION KEY ENCRYPTION'); - - // get hash of challenge using key2 - $hash = $this->mhash_sha1($challenge, $key2); - - // get 8 bytes random data - $iv = substr(base64_encode(rand(1000,9999).rand(1000,9999)), 2, 8); - - $cipher = mcrypt_cbc(MCRYPT_3DES, $key3, $challenge."\x08\x08\x08\x08\x08\x08\x08\x08", MCRYPT_ENCRYPT, $iv); - - $blob = pack('LLLLLLL', 28, 1, 0x6603, 0x8004, 8, 20, 72); - $blob .= $iv; - $blob .= $hash; - $blob .= $cipher; - - return base64_encode($blob); - } - - /** - * Generate challenge response - * - * @param string $code - * @return string challenge response code - */ - private function getChallenge($code) { - // MSNP15 - // http://msnpiki.msnfanatic.com/index.php/MSNP11:Challenges - // Step 1: The MD5 Hash - $md5Hash = md5($code.self::PROD_KEY); - $aMD5 = @explode("\0", chunk_split($md5Hash, 8, "\0")); - for ($i = 0; $i < 4; $i++) { - $aMD5[$i] = implode('', array_reverse(@explode("\0", chunk_split($aMD5[$i], 2, "\0")))); - $aMD5[$i] = (0 + base_convert($aMD5[$i], 16, 10)) & 0x7FFFFFFF; - } - - // Step 2: A new string - $chl_id = $code.self::PROD_ID; - $chl_id .= str_repeat('0', 8 - (strlen($chl_id) % 8)); - - $aID = @explode("\0", substr(chunk_split($chl_id, 4, "\0"), 0, -1)); - for ($i = 0; $i < count($aID); $i++) { - $aID[$i] = implode('', array_reverse(@explode("\0", chunk_split($aID[$i], 1, "\0")))); - $aID[$i] = 0 + base_convert(bin2hex($aID[$i]), 16, 10); - } - - // Step 3: The 64 bit key - $magic_num = 0x0E79A9C1; - $str7f = 0x7FFFFFFF; - $high = 0; - $low = 0; - for ($i = 0; $i < count($aID); $i += 2) { - $temp = $aID[$i]; - $temp = bcmod(bcmul($magic_num, $temp), $str7f); - $temp = bcadd($temp, $high); - $temp = bcadd(bcmul($aMD5[0], $temp), $aMD5[1]); - $temp = bcmod($temp, $str7f); - - $high = $aID[$i+1]; - $high = bcmod(bcadd($high, $temp), $str7f); - $high = bcadd(bcmul($aMD5[2], $high), $aMD5[3]); - $high = bcmod($high, $str7f); - - $low = bcadd(bcadd($low, $high), $temp); - } - - $high = bcmod(bcadd($high, $aMD5[1]), $str7f); - $low = bcmod(bcadd($low, $aMD5[3]), $str7f); - - $new_high = bcmul($high & 0xFF, 0x1000000); - $new_high = bcadd($new_high, bcmul($high & 0xFF00, 0x100)); - $new_high = bcadd($new_high, bcdiv($high & 0xFF0000, 0x100)); - $new_high = bcadd($new_high, bcdiv($high & 0xFF000000, 0x1000000)); - // we need integer here - $high = 0+$new_high; - - $new_low = bcmul($low & 0xFF, 0x1000000); - $new_low = bcadd($new_low, bcmul($low & 0xFF00, 0x100)); - $new_low = bcadd($new_low, bcdiv($low & 0xFF0000, 0x100)); - $new_low = bcadd($new_low, bcdiv($low & 0xFF000000, 0x1000000)); - // we need integer here - $low = 0+$new_low; - - // we just use 32 bits integer, don't need the key, just high/low - // $key = bcadd(bcmul($high, 0x100000000), $low); - - // Step 4: Using the key - $md5Hash = md5($code.self::PROD_KEY); - $aHash = @explode("\0", chunk_split($md5Hash, 8, "\0")); - - $hash = ''; - $hash .= sprintf("%08x", (0 + base_convert($aHash[0], 16, 10)) ^ $high); - $hash .= sprintf("%08x", (0 + base_convert($aHash[1], 16, 10)) ^ $low); - $hash .= sprintf("%08x", (0 + base_convert($aHash[2], 16, 10)) ^ $high); - $hash .= sprintf("%08x", (0 + base_convert($aHash[3], 16, 10)) ^ $low); - - return $hash; - } - - /** - * Utility methods - */ - - private function Array2SoapVar($Array, $ReturnSoapVarObj = true, $TypeName = null, $TypeNameSpace = null) { - $ArrayString = ''; - foreach($Array as $Key => $Val) { - if ($Key{0} == ':') continue; - $Attrib = ''; - if (is_array($Val[':'])) { - foreach ($Val[':'] as $AttribName => $AttribVal) - $Attrib .= " $AttribName = '$AttribVal'"; - } - if ($Key{0} == '!') { - //List Type Define - $Key = substr($Key,1); - foreach ($Val as $ListKey => $ListVal) { - if ($ListKey{0} == ':') continue; - if (is_array($ListVal)) $ListVal = $this->Array2SoapVar($ListVal, false); - elseif (is_bool($ListVal)) $ListVal = $ListVal ? 'true' : 'false'; - $ArrayString .= "<$Key$Attrib>$ListVal"; - } - continue; - } - if (is_array($Val)) $Val = $this->Array2SoapVar($Val, false); - elseif (is_bool($Val)) $Val = $Val ? 'true' : 'false'; - $ArrayString .= "<$Key$Attrib>$Val"; - } - if ($ReturnSoapVarObj) return new SoapVar($ArrayString, XSD_ANYXML, $TypeName, $TypeNameSpace); - return $ArrayString; - } - - private function linetoArray($lines) { - $lines = str_replace("\r", '', $lines); - $lines = explode("\n", $lines); - foreach ($lines as $line) { - if (!isset($line{3})) continue; - list($Key, $Val) = explode(':', $line); - $Data[trim($Key)] = trim($Val); - } - return $Data; - } - - /** - * Get Passport ticket - * - * @param string $url URL string (Optional) - * @return mixed Array of tickets or false on failure - */ - private function get_passport_ticket($url = '') { - $user = $this->user; - $password = htmlspecialchars($this->password); - - if ($url === '') - $passport_url = self::PASSPORT_URL; - else - $passport_url = $url; - - $XML = ' - -
- - {7108E71A-9926-4FCB-BCC9-9A9D3F32E423} - 4 - 1 - - AQAAAAIAAABsYwQAAAAxMDMz - - - - '.$user.' - '.$password.' - - -
- - - - http://schemas.xmlsoap.org/ws/2004/04/security/trust/Issue - - - http://Passport.NET/tb - - - - - http://schemas.xmlsoap.org/ws/2004/04/security/trust/Issue - - - messengerclear.live.com - - - - - - http://schemas.xmlsoap.org/ws/2004/04/security/trust/Issue - - - messenger.msn.com - - - - - - http://schemas.xmlsoap.org/ws/2004/04/security/trust/Issue - - - contacts.msn.com - - - - - - http://schemas.xmlsoap.org/ws/2004/04/security/trust/Issue - - - messengersecure.live.com - - - - - - http://schemas.xmlsoap.org/ws/2004/04/security/trust/Issue - - - spaces.live.com - - - - - - http://schemas.xmlsoap.org/ws/2004/04/security/trust/Issue - - - storage.msn.com - - - - - - -
'; - - $this->debug_message("*** URL: $passport_url"); - $this->debug_message("*** Sending SOAP:\n$XML"); - $curl = curl_init(); - curl_setopt($curl, CURLOPT_URL, $passport_url); - if ($this->debug) curl_setopt($curl, CURLOPT_HEADER, 1); - curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1); - curl_setopt($curl, CURLOPT_FOLLOWLOCATION, 1); - curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, 0); - curl_setopt($curl, CURLOPT_POST, 1); - curl_setopt($curl, CURLOPT_POSTFIELDS, $XML); - $data = curl_exec($curl); - $http_code = curl_getinfo($curl, CURLINFO_HTTP_CODE); - curl_close($curl); - $this->debug_message("*** Get Result:\n$data"); - - if ($http_code != 200) { - // sometimes, redirect to another URL - // MSNP15 - //psf:Redirect - //https://msnia.login.live.com/pp450/RST.srf - //Authentication Failure - if (strpos($data, 'psf:Redirect') === false) { - $this->debug_message("*** Could not get passport ticket! http code = $http_code"); - return false; - } - preg_match("#(.*)#", $data, $matches); - if (count($matches) == 0) { - $this->debug_message('*** Redirected, but could not get redirect URL!'); - return false; - } - $redirect_url = $matches[1]; - if ($redirect_url == $passport_url) { - $this->debug_message('*** Redirected, but to same URL!'); - return false; - } - $this->debug_message("*** Redirected to $redirect_url"); - return $this->get_passport_ticket($redirect_url); - } - - // sometimes, redirect to another URL, also return 200 - // MSNP15 - //psf:Redirect - //https://msnia.login.live.com/pp450/RST.srf - //Authentication Failure - if (strpos($data, 'psf:Redirect') !== false) { - preg_match("#(.*)#", $data, $matches); - if (count($matches) != 0) { - $redirect_url = $matches[1]; - if ($redirect_url == $passport_url) { - $this->debug_message('*** Redirected, but to same URL!'); - return false; - } - $this->debug_message("*** Redirected to $redirect_url"); - return $this->get_passport_ticket($redirect_url); - } - } - - // no Redurect faultcode or URL - // we should get the ticket here - - // we need ticket and secret code - // RST1: messengerclear.live.com - // t=tick&p= - // binary secret - // RST2: messenger.msn.com - // t=tick - // RST3: contacts.msn.com - // t=tick&p= - // RST4: messengersecure.live.com - // t=tick&p= - // RST5: spaces.live.com - // t=tick&p= - // RST6: storage.msn.com - // t=tick&p= - preg_match("#". - "(.*)(.*)". - "(.*)(.*)". - "(.*)(.*)". - "(.*)(.*)". - "(.*)(.*)". - "(.*)(.*)". - "(.*)(.*)". - "#", - $data, $matches); - - // no ticket found! - if (count($matches) == 0) { - // Since 2011/2/15, the return value will be Compact2, not PPToken2 - - // we need ticket and secret code - // RST1: messengerclear.live.com - // t=tick&p= - // binary secret - // RST2: messenger.msn.com - // t=tick - // RST3: contacts.msn.com - // t=tick&p= - // RST4: messengersecure.live.com - // t=tick&p= - // RST5: spaces.live.com - // t=tick&p= - // RST6: storage.msn.com - // t=tick&p= - preg_match("#". - "(.*)(.*)". - "(.*)(.*)". - "(.*)(.*)". - "(.*)(.*)". - "(.*)(.*)". - "(.*)(.*)". - "(.*)(.*)". - "#", - $data, $matches); - // no ticket found! - if (count($matches) == 0) { - $this->debug_message("*** Can't get passport ticket!"); - return false; - } - } - - //$this->debug_message(var_export($matches, true)); - // matches[0]: all data - // matches[1]: RST1 (messengerclear.live.com) ticket - // matches[2]: ... - // matches[3]: RST1 (messengerclear.live.com) binary secret - // matches[4]: ... - // matches[5]: RST2 (messenger.msn.com) ticket - // matches[6]: ... - // matches[7]: RST3 (contacts.msn.com) ticket - // matches[8]: ... - // matches[9]: RST4 (messengersecure.live.com) ticket - // matches[10]: ... - // matches[11]: RST5 (spaces.live.com) ticket - // matches[12]: ... - // matches[13]: RST6 (storage.live.com) ticket - // matches[14]: ... - - // so - // ticket => $matches[1] - // secret => $matches[3] - // web_ticket => $matches[5] - // contact_ticket => $matches[7] - // oim_ticket => $matches[9] - // space_ticket => $matches[11] - // storage_ticket => $matches[13] - - // yes, we get ticket - $aTickets = array( - 'ticket' => html_entity_decode($matches[1]), - 'secret' => html_entity_decode($matches[3]), - 'web_ticket' => html_entity_decode($matches[5]), - 'contact_ticket' => html_entity_decode($matches[7]), - 'oim_ticket' => html_entity_decode($matches[9]), - 'space_ticket' => html_entity_decode($matches[11]), - 'storage_ticket' => html_entity_decode($matches[13]) - ); - $this->ticket = $aTickets; - //$this->debug_message(var_export($aTickets, true)); - $ABAuthHeaderArray = array( - 'ABAuthHeader' => array( - ':' => array('xmlns' => 'http://www.msn.com/webservices/AddressBook'), - 'ManagedGroupRequest' => false, - 'TicketToken' => htmlspecialchars($this->ticket['contact_ticket']), - ) - ); - $this->ABAuthHeader = new SoapHeader('http://www.msn.com/webservices/AddressBook', 'ABAuthHeader', $this->Array2SoapVar($ABAuthHeaderArray)); - return $aTickets; - } - - /** - * Generate the data to send a message - * - * @param string $sMessage Message - * @param integer $network Network - * @return string Message data - */ - private function getMessage($sMessage, $network = 1) { - $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"; - $msg_header_len = strlen($msg_header); - if ($network == 1) - $maxlen = self::MAX_MSN_MESSAGE_LEN - $msg_header_len; - else - $maxlen = self::MAX_YAHOO_MESSAGE_LEN - $msg_header_len; - $sMessage = str_replace("\r", '', $sMessage); - $msg = substr($sMessage, 0, $maxlen); - return $msg_header.$msg; - } - - /** - * Sleep for the given number of seconds - * - * @param integer $wait Number of seconds to sleep for - */ - private function NSRetryWait($wait) { - $this->debug_message("*** Sleeping for $wait seconds before retrying"); - sleep($wait); - } - - /** - * Sends a ping command - * - * Should be called about every 50 seconds - * - * @return void - */ - public function sendPing() { - // NS: >>> PNG - $this->ns_writeln("PNG"); - } - - /** - * Methods to add / call callbacks - */ - - /** - * Calls User Handler - * - * Calls registered handler for a specific event. - * - * @param string $event Command (event) name (Rvous etc) - * @param array $data Data - * @see registerHandler - * @return void - */ - private function callHandler($event, $data = NULL) { - if (isset($this->myEventHandlers[$event])) { - if ($data !== NULL) { - call_user_func($this->myEventHandlers[$event], $data); - } else { - call_user_func($this->myEventHandlers[$event]); - } - } - } - - /** - * Registers a user handler - * - * Handler List - * IMIn, SessionReady, Pong, ConnectFailed, Reconnect, - * AddedToList, RemovedFromList, StatusChange - * - * @param string $event Event name - * @param string $handler User function to call - * @see callHandler - * @return boolean true if successful - */ - public function registerHandler($event, $handler) { - if (is_callable($handler)) { - $this->myEventHandlers[$event] = $handler; - return true; - } else { - return false; - } - } - - /** - * Debugging methods - */ - - /** - * Print message if debugging is enabled - * - * @param string $str Message to print - */ - private function debug_message($str) { - if (!$this->debug) return; - echo $str."\n"; - } - - /** - * Dump binary data - * - * @param string $str Data string - * @return Binary data - */ - private function dump_binary($str) { - $buf = ''; - $a_str = ''; - $h_str = ''; - $len = strlen($str); - for ($i = 0; $i < $len; $i++) { - if (($i % 16) == 0) { - if ($buf !== '') { - $buf .= "$h_str $a_str\n"; - } - $buf .= sprintf("%04X:", $i); - $a_str = ''; - $h_str = ''; - } - $ch = ord($str[$i]); - if ($ch < 32) - $a_str .= '.'; - else - $a_str .= chr($ch); - $h_str .= sprintf(" %02X", $ch); - } - if ($h_str !== '') - $buf .= "$h_str $a_str\n"; - return $buf; - } - - function mhash_sha1($data, $key) - { - if (extension_loaded("mhash")) - return mhash(MHASH_SHA1, $data, $key); - - if (function_exists("hash_hmac")) - return hash_hmac('sha1', $data, $key, true); - - // RFC 2104 HMAC implementation for php. Hacked by Lance Rushing - $b = 64; - if (strlen($key) > $b) - $key = pack("H*", sha1($key)); - $key = str_pad($key, $b, chr(0x00)); - $ipad = str_pad("", $b, chr(0x36)); - $opad = str_pad("", $b, chr(0x5c)); - $k_ipad = $key ^ $ipad ; - $k_opad = $key ^ $opad; - - $sha1_value = sha1($k_opad . pack("H*", sha1($k_ipad . $data))); - - $hash_data = ''; - $str = join('',explode('\x', $sha1_value)); - $len = strlen($str); - for ($i = 0; $i < $len; $i += 2) - $hash_data .= chr(hexdec(substr($str, $i, 2))); - return $hash_data; - } -} diff --git a/plugins/Msn/extlib/phpmsnclass/msnbot.php b/plugins/Msn/extlib/phpmsnclass/msnbot.php deleted file mode 100755 index 7a9f66ca2e..0000000000 --- a/plugins/Msn/extlib/phpmsnclass/msnbot.php +++ /dev/null @@ -1,63 +0,0 @@ -#!/usr/bin/php -End(); - return; - } -} - -// network: -// 1: WLM/MSN -// 2: LCS -// 4: Mobile Phones -// 32: Yahoo! -function getNetworkName($network) -{ - switch ($network) - { - case 1: - return 'WLM/MSN'; - case 2: - return 'LCS'; - case 4: - return 'Mobile Phones'; - case 32: - return 'Yahoo!'; - } - return "Unknown ($network)"; -} - - -require_once('config.php'); -include_once('msn.class.php'); - -$msn = new MSN(array( - 'user' => 'xxx@hotmail.com', - 'password' => 'mypassword', - 'alias' => 'myalias', - 'psm' => 'psm', -// 'PhotoSticker' => 'msntitle.jpg', - 'debug'=> true, -/* 'Emotions' => array( - 'aaa' => 'emotion.gif' - ),*/ -)); - -$fp=fopen(MSN_CLASS_LOG_DIR.DIRECTORY_SEPARATOR.'msnbot.pid', 'wt'); -if($fp) -{ - fputs($fp,posix_getpid()); - fclose($fp); -} -declare(ticks = 1); -$msn->Run(); -$msn->log_message("done!"); -@unlink(dirname($_SERVER['argv'][0]).DIRECTORY_SEPARATOR.'log'.DIRECTORY_SEPARATOR.'msnbot.pid'); diff --git a/plugins/Msn/extlib/phpmsnclass/soap/msnab_datatypes.xsd b/plugins/Msn/extlib/phpmsnclass/soap/msnab_datatypes.xsd deleted file mode 100644 index 46fc23f911..0000000000 --- a/plugins/Msn/extlib/phpmsnclass/soap/msnab_datatypes.xsd +++ /dev/null @@ -1,832 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - A space (ASCII #32) separated list of properties that - have changed as part of an update request. The property - names don't always match the name of the associated - element. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Indicates whether the contact has a Windows Live - Space or not. - - - - - - - - - - - - - Seen is YYYY/MM/DD format. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - A space (ASCII #32) separated list of properties that - have changed as part of an update request. The property - names don't always match the name of the associated - element. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/plugins/Msn/extlib/phpmsnclass/soap/msnab_servicetypes.xsd b/plugins/Msn/extlib/phpmsnclass/soap/msnab_servicetypes.xsd deleted file mode 100644 index 3fa9798b62..0000000000 --- a/plugins/Msn/extlib/phpmsnclass/soap/msnab_servicetypes.xsd +++ /dev/null @@ -1,567 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/plugins/Msn/extlib/phpmsnclass/soap/msnab_sharingservice.wsdl b/plugins/Msn/extlib/phpmsnclass/soap/msnab_sharingservice.wsdl deleted file mode 100644 index 7ec87f90c9..0000000000 --- a/plugins/Msn/extlib/phpmsnclass/soap/msnab_sharingservice.wsdl +++ /dev/null @@ -1,532 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/plugins/Msn/lib/msnmanager.php b/plugins/Msn/lib/msnmanager.php deleted file mode 100644 index 82d40d69c9..0000000000 --- a/plugins/Msn/lib/msnmanager.php +++ /dev/null @@ -1,276 +0,0 @@ -. - */ - -if (!defined('STATUSNET') && !defined('LACONICA')) { exit(1); } - -/** - * MSN background connection manager for MSN-using queue handlers, - * allowing them to send outgoing messages on the right connection. - * - * Input is handled during socket select loop, keepalive pings during idle. - * Any incoming messages will be handled. - * - * In a multi-site queuedaemon.php run, one connection will be instantiated - * for each site being handled by the current process that has MSN enabled. - */ -class MsnManager extends ImManager { - public $conn = null; - protected $lastPing = null; - protected $pingInterval; - - /** - * Initialise connection to server. - * - * @return boolean true on success - */ - public function start($master) { - if (parent::start($master)) { - $this->requeue_waiting_messages(); - $this->connect(); - return true; - } else { - return false; - } - } - - /** - * Return any open sockets that the run loop should listen - * for input on. - * - * @return array Array of socket resources - */ - public function getSockets() { - $this->connect(); - if ($this->conn) { - return $this->conn->getSockets(); - } else { - return array(); - } - } - - /** - * Idle processing for io manager's execution loop. - * Send keepalive pings to server. - * - * @return void - */ - public function idle($timeout = 0) { - if (empty($this->lastPing) || time() - $this->lastPing > $this->pingInterval) { - $this->send_ping(); - } - } - - /** - * Message pump is triggered on socket input, so we only need an idle() - * call often enough to trigger our outgoing pings. - */ - public function timeout() { - return $this->pingInterval; - } - - /** - * Process MSN events that have come in over the wire. - * - * @param resource $socket Socket ready - * @return void - */ - public function handleInput($socket) { - common_log(LOG_DEBUG, 'Servicing the MSN queue.'); - $this->stats('msn_process'); - $this->conn->receive(); - } - - /** - * Initiate connection - * - * @return void - */ - public function connect() { - if (!$this->conn) { - $this->conn = new MSN( - array( - 'user' => $this->plugin->user, - 'password' => $this->plugin->password, - 'alias' => $this->plugin->nickname, - // TRANS: MSN bot status message. - 'psm' => _m('Send me a message to post a notice'), - 'debug' => false - ) - ); - $this->conn->registerHandler('IMin', array($this, 'handle_msn_message')); - $this->conn->registerHandler('SessionReady', array($this, 'handle_session_ready')); - $this->conn->registerHandler('Pong', array($this, 'update_ping_time')); - $this->conn->registerHandler('ConnectFailed', array($this, 'handle_connect_failed')); - $this->conn->registerHandler('Reconnect', array($this, 'handle_reconnect')); - $this->conn->signon(); - $this->lastPing = time(); - } - return $this->conn; - } - - /** - * Called by the idle process to send a ping - * when necessary - * - * @return void - */ - protected function send_ping() { - $this->connect(); - if (!$this->conn) { - return false; - } - - $this->conn->sendPing(); - $this->lastPing = time(); - $this->pingInterval = 50; - return true; - } - - /** - * Update the time till the next ping - * - * @param $data Time till next ping - * @return void - */ - public function update_ping_time($data) { - $this->pingInterval = $data; - } - - /** - * Called via a callback when a message is received - * - * Passes it back to the queuing system - * - * @param array $data Data - * @return boolean - */ - public function handle_msn_message($data) { - $this->plugin->enqueueIncomingRaw($data); - return true; - } - - /** - * Called via a callback when a session becomes ready - * - * @param array $data Data - */ - public function handle_session_ready($data) { - $sessionFailed = false; - $wm = Msn_waiting_message::top($data['to']); - while ($wm != NULL) { - if ($sessionFailed) { - $this->plugin->sendMessage($wm->screenname, $wm->message); - $sessionFailed = true; - } elseif (!$this->conn->sendMessage($wm->screenname, $wm->message, $ignore)) { - $this->plugin->sendMessage($wm->screenname, $wm->message); - } - - $wm->delete(); - $wm = Msn_waiting_message::top($data['to']); - } - } - - /** - * Requeue messages from the waiting table so we try - * to send them again - * - * @return void - */ - protected function requeue_waiting_messages() { - $wm = Msn_waiting_message::top(); - while ($wm != NULL) { - $this->plugin->sendMessage($wm->screenname, $wm->message); - $wm->delete(); - $wm = Msn_waiting_message::top(); - } - } - - /** - * Called by callback to log failure during connect - * - * @param string $message error message reported - * @return void - */ - public function handle_connect_failed($message) { - common_log(LOG_NOTICE, 'MSN connect failed, retrying: ' . $message); - } - - /** - * Called by callback to log reconnection - * - * @param void $data Not used (there to keep callback happy) - * @return void - */ - public function handle_reconnect($data) { - common_log(LOG_NOTICE, 'MSN reconnecting'); - // Requeue messages waiting in the DB - $this->requeue_waiting_messages(); - } - - /** - * Enters a message into the database for sending via a callback - * when the session is established - * - * @param string $to Intended recipient - * @param string $message Message - */ - protected function enqueue_waiting_message($to, $message) { - $wm = new Msn_waiting_message(); - - $wm->screenname = $to; - $wm->message = $message; - $wm->created = common_sql_now(); - $result = $wm->insert(); - - if (!$result) { - common_log_db_error($wm, 'INSERT', __FILE__); - // TRANS: Server exception thrown when a message to be sent through MSN cannot be added to the database queue. - throw new ServerException(_m('Database error inserting queue item.')); - } - - return true; - } - - /** - * Send a message using the daemon - * - * @param $data Message data - * @return boolean true on success - */ - public function send_raw_message($data) { - $this->connect(); - if (!$this->conn) { - return false; - } - - $waitForSession = false; - if (!$this->conn->sendMessage($data['to'], $data['message'], $waitForSession)) { - if ($waitForSession) { - $this->enqueue_waiting_message($data['to'], $data['message']); - } else { - return false; - } - } - - // Sending a command updates the time till next ping - $this->lastPing = time(); - $this->pingInterval = 50; - return true; - } -} diff --git a/plugins/Msn/locale/Msn.pot b/plugins/Msn/locale/Msn.pot deleted file mode 100644 index 08f37d374f..0000000000 --- a/plugins/Msn/locale/Msn.pot +++ /dev/null @@ -1,53 +0,0 @@ -# SOME DESCRIPTIVE TITLE. -# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER -# This file is distributed under the same license as the PACKAGE package. -# FIRST AUTHOR , YEAR. -# -#, fuzzy -msgid "" -msgstr "" -"Project-Id-Version: PACKAGE VERSION\n" -"Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2012-06-30 11:07+0000\n" -"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" -"Last-Translator: FULL NAME \n" -"Language-Team: LANGUAGE \n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=CHARSET\n" -"Content-Transfer-Encoding: 8bit\n" - -#. TRANS: MSN bot status message. -#: msnmanager.php:112 -msgid "Send me a message to post a notice" -msgstr "" - -#. TRANS: Server exception thrown when a message to be sent through MSN cannot be added to the database queue. -#: msnmanager.php:244 -msgid "Database error inserting queue item." -msgstr "" - -#. TRANS: Display name of the MSN instant messaging service. -#: MsnPlugin.php:62 -msgid "MSN" -msgstr "" - -#. TRANS: Exception thrown when configuration for the MSN plugin is incomplete. -#: MsnPlugin.php:188 -msgid "Must specify a user." -msgstr "" - -#. TRANS: Exception thrown when configuration for the MSN plugin is incomplete. -#: MsnPlugin.php:192 -msgid "Must specify a password." -msgstr "" - -#. TRANS: Exception thrown when configuration for the MSN plugin is incomplete. -#: MsnPlugin.php:196 -msgid "Must specify a nickname." -msgstr "" - -#. TRANS: Plugin description. -#: MsnPlugin.php:216 -msgid "" -"The MSN plugin allows users to send and receive notices over the MSN network." -msgstr "" diff --git a/plugins/Msn/locale/ar/LC_MESSAGES/Msn.po b/plugins/Msn/locale/ar/LC_MESSAGES/Msn.po deleted file mode 100644 index 1b94253755..0000000000 --- a/plugins/Msn/locale/ar/LC_MESSAGES/Msn.po +++ /dev/null @@ -1,54 +0,0 @@ -# Translation of StatusNet - Msn to Arabic (العربية) -# Exported from translatewiki.net -# -# Author: Imksa -# -- -# This file is distributed under the same license as the StatusNet package. -# -msgid "" -msgstr "" -"Project-Id-Version: StatusNet - Msn\n" -"Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2012-06-30 11:07+0000\n" -"PO-Revision-Date: 2012-06-30 11:09:18+0000\n" -"Language-Team: Arabic \n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: 8bit\n" -"X-POT-Import-Date: 2011-12-03 13:48:56+0000\n" -"X-Generator: MediaWiki 1.20alpha (233fc08); Translate 2012-06-21\n" -"X-Translation-Project: translatewiki.net \n" -"X-Language-Code: ar\n" -"X-Message-Group: #out-statusnet-plugin-msn\n" -"Plural-Forms: nplurals=6; plural=(n == 0) ? 0 : ( (n == 1) ? 1 : ( (n == " -"2) ? 2 : ( (n%100 >= 3 && n%100 <= 10) ? 3 : ( (n%100 >= 11 && n%100 <= " -"99) ? 4 : 5 ) ) ) );\n" - -#. TRANS: MSN bot status message. -msgid "Send me a message to post a notice" -msgstr "أرسل لي رسالة لأرسل إشعارًا" - -#. TRANS: Server exception thrown when a message to be sent through MSN cannot be added to the database queue. -msgid "Database error inserting queue item." -msgstr "خطأ في قاعدة بيانات إدراج بند قائمة الانتظار." - -#. TRANS: Display name of the MSN instant messaging service. -msgid "MSN" -msgstr "" - -#. TRANS: Exception thrown when configuration for the MSN plugin is incomplete. -msgid "Must specify a user." -msgstr "يجب تحديد مستخدم." - -#. TRANS: Exception thrown when configuration for the MSN plugin is incomplete. -msgid "Must specify a password." -msgstr "يجب تحديد كلمة مرور." - -#. TRANS: Exception thrown when configuration for the MSN plugin is incomplete. -msgid "Must specify a nickname." -msgstr "يجب تحديد اسم مستعار." - -#. TRANS: Plugin description. -msgid "" -"The MSN plugin allows users to send and receive notices over the MSN network." -msgstr "" -"البرنامج المساعد MSN يسمح للمستخدمين بإرسال وتلقى إشعارات عبر شبكة MSN." diff --git a/plugins/Msn/locale/br/LC_MESSAGES/Msn.po b/plugins/Msn/locale/br/LC_MESSAGES/Msn.po deleted file mode 100644 index 533afc9969..0000000000 --- a/plugins/Msn/locale/br/LC_MESSAGES/Msn.po +++ /dev/null @@ -1,51 +0,0 @@ -# Translation of StatusNet - Msn to Breton (Brezhoneg) -# Exported from translatewiki.net -# -# Author: Y-M D -# -- -# This file is distributed under the same license as the StatusNet package. -# -msgid "" -msgstr "" -"Project-Id-Version: StatusNet - Msn\n" -"Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2011-04-27 12:36+0000\n" -"PO-Revision-Date: 2011-04-27 12:37:46+0000\n" -"Language-Team: Breton \n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: 8bit\n" -"X-POT-Import-Date: 2011-03-26 16:22:40+0000\n" -"X-Generator: MediaWiki 1.18alpha (r87008); Translate extension (2011-04-26)\n" -"X-Translation-Project: translatewiki.net at http://translatewiki.net\n" -"X-Language-Code: br\n" -"X-Message-Group: #out-statusnet-plugin-msn\n" -"Plural-Forms: nplurals=2; plural=(n > 1);\n" - -#. TRANS: MSN bot status message. -msgid "Send me a message to post a notice" -msgstr "" - -#. TRANS: Server exception thrown when a message to be sent through MSN cannot be added to the database queue. -msgid "Database error inserting queue item." -msgstr "" - -#. TRANS: Display name of the MSN instant messaging service. -msgid "MSN" -msgstr "MSN" - -#. TRANS: Exception thrown when configuration for the MSN plugin is incomplete. -msgid "Must specify a user." -msgstr "" - -#. TRANS: Exception thrown when configuration for the MSN plugin is incomplete. -msgid "Must specify a password." -msgstr "" - -#. TRANS: Exception thrown when configuration for the MSN plugin is incomplete. -msgid "Must specify a nickname." -msgstr "" - -#. TRANS: Plugin description. -msgid "" -"The MSN plugin allows users to send and receive notices over the MSN network." -msgstr "" diff --git a/plugins/Msn/locale/ca/LC_MESSAGES/Msn.po b/plugins/Msn/locale/ca/LC_MESSAGES/Msn.po deleted file mode 100644 index 65c84278db..0000000000 --- a/plugins/Msn/locale/ca/LC_MESSAGES/Msn.po +++ /dev/null @@ -1,51 +0,0 @@ -# Translation of StatusNet - Msn to Catalan (català) -# Exported from translatewiki.net -# -# Author: Toniher -# -- -# This file is distributed under the same license as the StatusNet package. -# -msgid "" -msgstr "" -"Project-Id-Version: StatusNet - Msn\n" -"Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2012-06-30 11:07+0000\n" -"PO-Revision-Date: 2012-06-30 11:09:18+0000\n" -"Language-Team: Catalan \n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: 8bit\n" -"X-POT-Import-Date: 2011-12-03 13:48:56+0000\n" -"X-Generator: MediaWiki 1.20alpha (233fc08); Translate 2012-06-21\n" -"X-Translation-Project: translatewiki.net \n" -"X-Language-Code: ca\n" -"X-Message-Group: #out-statusnet-plugin-msn\n" -"Plural-Forms: nplurals=2; plural=(n != 1);\n" - -#. TRANS: MSN bot status message. -msgid "Send me a message to post a notice" -msgstr "Envia'm un missatge per publicar un avís" - -#. TRANS: Server exception thrown when a message to be sent through MSN cannot be added to the database queue. -msgid "Database error inserting queue item." -msgstr "" - -#. TRANS: Display name of the MSN instant messaging service. -msgid "MSN" -msgstr "MSN" - -#. TRANS: Exception thrown when configuration for the MSN plugin is incomplete. -msgid "Must specify a user." -msgstr "Cal especificar un usuari." - -#. TRANS: Exception thrown when configuration for the MSN plugin is incomplete. -msgid "Must specify a password." -msgstr "Cal especificar una contrasenya." - -#. TRANS: Exception thrown when configuration for the MSN plugin is incomplete. -msgid "Must specify a nickname." -msgstr "Cal especificar un sobrenom." - -#. TRANS: Plugin description. -msgid "" -"The MSN plugin allows users to send and receive notices over the MSN network." -msgstr "" diff --git a/plugins/Msn/locale/de/LC_MESSAGES/Msn.po b/plugins/Msn/locale/de/LC_MESSAGES/Msn.po deleted file mode 100644 index 703dcbf924..0000000000 --- a/plugins/Msn/locale/de/LC_MESSAGES/Msn.po +++ /dev/null @@ -1,54 +0,0 @@ -# Translation of StatusNet - Msn to German (Deutsch) -# Exported from translatewiki.net -# -# Author: Giftpflanze -# Author: MF-Warburg -# -- -# This file is distributed under the same license as the StatusNet package. -# -msgid "" -msgstr "" -"Project-Id-Version: StatusNet - Msn\n" -"Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2012-06-30 11:07+0000\n" -"PO-Revision-Date: 2012-06-30 11:09:18+0000\n" -"Language-Team: German \n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: 8bit\n" -"X-POT-Import-Date: 2011-12-03 13:48:56+0000\n" -"X-Generator: MediaWiki 1.20alpha (233fc08); Translate 2012-06-21\n" -"X-Translation-Project: translatewiki.net \n" -"X-Language-Code: de\n" -"X-Message-Group: #out-statusnet-plugin-msn\n" -"Plural-Forms: nplurals=2; plural=(n != 1);\n" - -#. TRANS: MSN bot status message. -msgid "Send me a message to post a notice" -msgstr "Sende mir eine Nachricht um einen Hinweis bekanntzumachen" - -#. TRANS: Server exception thrown when a message to be sent through MSN cannot be added to the database queue. -msgid "Database error inserting queue item." -msgstr "Beim Einfügen des Queue-Items ist ein Datenbankfehler aufgetreten." - -#. TRANS: Display name of the MSN instant messaging service. -msgid "MSN" -msgstr "MSN" - -#. TRANS: Exception thrown when configuration for the MSN plugin is incomplete. -msgid "Must specify a user." -msgstr "Du musst einen Benutzer angeben." - -#. TRANS: Exception thrown when configuration for the MSN plugin is incomplete. -msgid "Must specify a password." -msgstr "Du musst ein Passwort angeben." - -#. TRANS: Exception thrown when configuration for the MSN plugin is incomplete. -msgid "Must specify a nickname." -msgstr "Du musst einen Nick angeben." - -#. TRANS: Plugin description. -msgid "" -"The MSN plugin allows users to send and receive notices over the MSN network." -msgstr "" -"Das MSN-Plugin ermöglicht Benutzern, Nachrichten über das MSN-Netzwerk zu " -"senden und zu empfangen." diff --git a/plugins/Msn/locale/el/LC_MESSAGES/Msn.po b/plugins/Msn/locale/el/LC_MESSAGES/Msn.po deleted file mode 100644 index 551ddc38f3..0000000000 --- a/plugins/Msn/locale/el/LC_MESSAGES/Msn.po +++ /dev/null @@ -1,51 +0,0 @@ -# Translation of StatusNet - Msn to Greek (Ελληνικά) -# Exported from translatewiki.net -# -# Author: Evropi -# -- -# This file is distributed under the same license as the StatusNet package. -# -msgid "" -msgstr "" -"Project-Id-Version: StatusNet - Msn\n" -"Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2011-04-27 12:36+0000\n" -"PO-Revision-Date: 2011-04-27 12:37:46+0000\n" -"Language-Team: Greek \n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: 8bit\n" -"X-POT-Import-Date: 2011-03-26 16:22:40+0000\n" -"X-Generator: MediaWiki 1.18alpha (r87008); Translate extension (2011-04-26)\n" -"X-Translation-Project: translatewiki.net at http://translatewiki.net\n" -"X-Language-Code: el\n" -"X-Message-Group: #out-statusnet-plugin-msn\n" -"Plural-Forms: nplurals=2; plural=(n != 1);\n" - -#. TRANS: MSN bot status message. -msgid "Send me a message to post a notice" -msgstr "" - -#. TRANS: Server exception thrown when a message to be sent through MSN cannot be added to the database queue. -msgid "Database error inserting queue item." -msgstr "" - -#. TRANS: Display name of the MSN instant messaging service. -msgid "MSN" -msgstr "MSN" - -#. TRANS: Exception thrown when configuration for the MSN plugin is incomplete. -msgid "Must specify a user." -msgstr "" - -#. TRANS: Exception thrown when configuration for the MSN plugin is incomplete. -msgid "Must specify a password." -msgstr "" - -#. TRANS: Exception thrown when configuration for the MSN plugin is incomplete. -msgid "Must specify a nickname." -msgstr "" - -#. TRANS: Plugin description. -msgid "" -"The MSN plugin allows users to send and receive notices over the MSN network." -msgstr "" diff --git a/plugins/Msn/locale/es/LC_MESSAGES/Msn.po b/plugins/Msn/locale/es/LC_MESSAGES/Msn.po deleted file mode 100644 index b71dcfb57a..0000000000 --- a/plugins/Msn/locale/es/LC_MESSAGES/Msn.po +++ /dev/null @@ -1,54 +0,0 @@ -# Translation of StatusNet - Msn to Spanish (español) -# Exported from translatewiki.net -# -# Author: Armando-Martin -# Author: Od1n -# -- -# This file is distributed under the same license as the StatusNet package. -# -msgid "" -msgstr "" -"Project-Id-Version: StatusNet - Msn\n" -"Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2012-06-30 11:07+0000\n" -"PO-Revision-Date: 2012-06-30 11:09:18+0000\n" -"Language-Team: Spanish \n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: 8bit\n" -"X-POT-Import-Date: 2011-12-03 13:48:56+0000\n" -"X-Generator: MediaWiki 1.20alpha (233fc08); Translate 2012-06-21\n" -"X-Translation-Project: translatewiki.net \n" -"X-Language-Code: es\n" -"X-Message-Group: #out-statusnet-plugin-msn\n" -"Plural-Forms: nplurals=2; plural=(n != 1);\n" - -#. TRANS: MSN bot status message. -msgid "Send me a message to post a notice" -msgstr "Envíeme un mensaje para publicar una nota" - -#. TRANS: Server exception thrown when a message to be sent through MSN cannot be added to the database queue. -msgid "Database error inserting queue item." -msgstr "Error en la base de datos al insertar un elemento en la cola." - -#. TRANS: Display name of the MSN instant messaging service. -msgid "MSN" -msgstr "MSN" - -#. TRANS: Exception thrown when configuration for the MSN plugin is incomplete. -msgid "Must specify a user." -msgstr "Debe especificar un usuario." - -#. TRANS: Exception thrown when configuration for the MSN plugin is incomplete. -msgid "Must specify a password." -msgstr "Debe especificar una contraseña." - -#. TRANS: Exception thrown when configuration for the MSN plugin is incomplete. -msgid "Must specify a nickname." -msgstr "Debe especificar un alias." - -#. TRANS: Plugin description. -msgid "" -"The MSN plugin allows users to send and receive notices over the MSN network." -msgstr "" -"El complemento (plugin) MSN permite a los usuarios enviar y recibir mensajes " -"mediante una red MSN." diff --git a/plugins/Msn/locale/eu/LC_MESSAGES/Msn.po b/plugins/Msn/locale/eu/LC_MESSAGES/Msn.po deleted file mode 100644 index 602f67f752..0000000000 --- a/plugins/Msn/locale/eu/LC_MESSAGES/Msn.po +++ /dev/null @@ -1,53 +0,0 @@ -# Translation of StatusNet - Msn to Basque (euskara) -# Exported from translatewiki.net -# -# Author: Artsuaga -# -- -# This file is distributed under the same license as the StatusNet package. -# -msgid "" -msgstr "" -"Project-Id-Version: StatusNet - Msn\n" -"Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2012-06-30 11:07+0000\n" -"PO-Revision-Date: 2012-06-30 11:09:18+0000\n" -"Language-Team: Basque \n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: 8bit\n" -"X-POT-Import-Date: 2011-12-03 13:48:56+0000\n" -"X-Generator: MediaWiki 1.20alpha (233fc08); Translate 2012-06-21\n" -"X-Translation-Project: translatewiki.net \n" -"X-Language-Code: eu\n" -"X-Message-Group: #out-statusnet-plugin-msn\n" -"Plural-Forms: nplurals=2; plural=(n != 1);\n" - -#. TRANS: MSN bot status message. -msgid "Send me a message to post a notice" -msgstr "Bidalidazu mezu bat ohar bat argitaratzeko" - -#. TRANS: Server exception thrown when a message to be sent through MSN cannot be added to the database queue. -msgid "Database error inserting queue item." -msgstr "Datubase akatsa zerrendako puntua txertatzerakoan." - -#. TRANS: Display name of the MSN instant messaging service. -msgid "MSN" -msgstr "MSN" - -#. TRANS: Exception thrown when configuration for the MSN plugin is incomplete. -msgid "Must specify a user." -msgstr "Erabiltzaile bat zehaztu." - -#. TRANS: Exception thrown when configuration for the MSN plugin is incomplete. -msgid "Must specify a password." -msgstr "Pasahitz bat zehaztu." - -#. TRANS: Exception thrown when configuration for the MSN plugin is incomplete. -msgid "Must specify a nickname." -msgstr "Goitizen bat zehaztu." - -#. TRANS: Plugin description. -msgid "" -"The MSN plugin allows users to send and receive notices over the MSN network." -msgstr "" -"MSN pluginak erabiltzaileei MSN sare bidez oharrak bidali eta jasotzen uzten " -"du." diff --git a/plugins/Msn/locale/fr/LC_MESSAGES/Msn.po b/plugins/Msn/locale/fr/LC_MESSAGES/Msn.po deleted file mode 100644 index 9c39c8a137..0000000000 --- a/plugins/Msn/locale/fr/LC_MESSAGES/Msn.po +++ /dev/null @@ -1,55 +0,0 @@ -# Translation of StatusNet - Msn to French (français) -# Exported from translatewiki.net -# -# Author: Gomoko -# Author: Hashar -# Author: Od1n -# -- -# This file is distributed under the same license as the StatusNet package. -# -msgid "" -msgstr "" -"Project-Id-Version: StatusNet - Msn\n" -"Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2012-06-30 11:07+0000\n" -"PO-Revision-Date: 2012-06-30 11:09:18+0000\n" -"Language-Team: French \n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: 8bit\n" -"X-POT-Import-Date: 2011-12-03 13:48:56+0000\n" -"X-Generator: MediaWiki 1.20alpha (233fc08); Translate 2012-06-21\n" -"X-Translation-Project: translatewiki.net \n" -"X-Language-Code: fr\n" -"X-Message-Group: #out-statusnet-plugin-msn\n" -"Plural-Forms: nplurals=2; plural=(n > 1);\n" - -#. TRANS: MSN bot status message. -msgid "Send me a message to post a notice" -msgstr "M’envoyer un message pour publier un avis." - -#. TRANS: Server exception thrown when a message to be sent through MSN cannot be added to the database queue. -msgid "Database error inserting queue item." -msgstr "Erreur de base de données lors de l'insertion d'un élément de file." - -#. TRANS: Display name of the MSN instant messaging service. -msgid "MSN" -msgstr "MSN" - -#. TRANS: Exception thrown when configuration for the MSN plugin is incomplete. -msgid "Must specify a user." -msgstr "Il faut spécifier un utilisateur." - -#. TRANS: Exception thrown when configuration for the MSN plugin is incomplete. -msgid "Must specify a password." -msgstr "Il faut spécifier un mot de passe." - -#. TRANS: Exception thrown when configuration for the MSN plugin is incomplete. -msgid "Must specify a nickname." -msgstr "Il faut indiquer un pseudonyme." - -#. TRANS: Plugin description. -msgid "" -"The MSN plugin allows users to send and receive notices over the MSN network." -msgstr "" -"Le plugin MSN permet aux utilisateurs d'envoyer et de recevoir des messages " -"depuis le réseau MSN." diff --git a/plugins/Msn/locale/gl/LC_MESSAGES/Msn.po b/plugins/Msn/locale/gl/LC_MESSAGES/Msn.po deleted file mode 100644 index 0fbe7c2a55..0000000000 --- a/plugins/Msn/locale/gl/LC_MESSAGES/Msn.po +++ /dev/null @@ -1,53 +0,0 @@ -# Translation of StatusNet - Msn to Galician (galego) -# Exported from translatewiki.net -# -# Author: Toliño -# -- -# This file is distributed under the same license as the StatusNet package. -# -msgid "" -msgstr "" -"Project-Id-Version: StatusNet - Msn\n" -"Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2012-06-30 11:07+0000\n" -"PO-Revision-Date: 2012-06-30 11:09:18+0000\n" -"Language-Team: Galician \n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: 8bit\n" -"X-POT-Import-Date: 2011-12-03 13:48:56+0000\n" -"X-Generator: MediaWiki 1.20alpha (233fc08); Translate 2012-06-21\n" -"X-Translation-Project: translatewiki.net \n" -"X-Language-Code: gl\n" -"X-Message-Group: #out-statusnet-plugin-msn\n" -"Plural-Forms: nplurals=2; plural=(n != 1);\n" - -#. TRANS: MSN bot status message. -msgid "Send me a message to post a notice" -msgstr "Envíame unha mensaxe para publicar unha nota" - -#. TRANS: Server exception thrown when a message to be sent through MSN cannot be added to the database queue. -msgid "Database error inserting queue item." -msgstr "Erro na base de datos ao inserir un elemento na cola." - -#. TRANS: Display name of the MSN instant messaging service. -msgid "MSN" -msgstr "MSN" - -#. TRANS: Exception thrown when configuration for the MSN plugin is incomplete. -msgid "Must specify a user." -msgstr "Cómpre especificar un usuario." - -#. TRANS: Exception thrown when configuration for the MSN plugin is incomplete. -msgid "Must specify a password." -msgstr "Cómpre especificar un contrasinal." - -#. TRANS: Exception thrown when configuration for the MSN plugin is incomplete. -msgid "Must specify a nickname." -msgstr "Cómpre especificar un alcume." - -#. TRANS: Plugin description. -msgid "" -"The MSN plugin allows users to send and receive notices over the MSN network." -msgstr "" -"O complemento MSN permite aos usuarios enviar e recibir mensaxes desde a " -"rede de MSN." diff --git a/plugins/Msn/locale/ia/LC_MESSAGES/Msn.po b/plugins/Msn/locale/ia/LC_MESSAGES/Msn.po deleted file mode 100644 index 8a32e3dc3f..0000000000 --- a/plugins/Msn/locale/ia/LC_MESSAGES/Msn.po +++ /dev/null @@ -1,54 +0,0 @@ -# Translation of StatusNet - Msn to Interlingua (interlingua) -# Exported from translatewiki.net -# -# Author: McDutchie -# -- -# This file is distributed under the same license as the StatusNet package. -# -msgid "" -msgstr "" -"Project-Id-Version: StatusNet - Msn\n" -"Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2012-06-30 11:07+0000\n" -"PO-Revision-Date: 2012-06-30 11:09:19+0000\n" -"Language-Team: Interlingua \n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: 8bit\n" -"X-POT-Import-Date: 2011-12-03 13:48:56+0000\n" -"X-Generator: MediaWiki 1.20alpha (233fc08); Translate 2012-06-21\n" -"X-Translation-Project: translatewiki.net \n" -"X-Language-Code: ia\n" -"X-Message-Group: #out-statusnet-plugin-msn\n" -"Plural-Forms: nplurals=2; plural=(n != 1);\n" - -#. TRANS: MSN bot status message. -msgid "Send me a message to post a notice" -msgstr "Inviar me un message pro publicar un nota" - -#. TRANS: Server exception thrown when a message to be sent through MSN cannot be added to the database queue. -msgid "Database error inserting queue item." -msgstr "" -"Error del base de datos durante le insertion de un elemento in le cauda." - -#. TRANS: Display name of the MSN instant messaging service. -msgid "MSN" -msgstr "MSN" - -#. TRANS: Exception thrown when configuration for the MSN plugin is incomplete. -msgid "Must specify a user." -msgstr "Es necessari specificar un usator." - -#. TRANS: Exception thrown when configuration for the MSN plugin is incomplete. -msgid "Must specify a password." -msgstr "Es necessari specificar un contrasigno." - -#. TRANS: Exception thrown when configuration for the MSN plugin is incomplete. -msgid "Must specify a nickname." -msgstr "Es necessari specificar un pseudonymo." - -#. TRANS: Plugin description. -msgid "" -"The MSN plugin allows users to send and receive notices over the MSN network." -msgstr "" -"Le plug-in de MSN permitte que usatores invia e recipe notas per le rete de " -"MSN." diff --git a/plugins/Msn/locale/it/LC_MESSAGES/Msn.po b/plugins/Msn/locale/it/LC_MESSAGES/Msn.po deleted file mode 100644 index 84b33666f6..0000000000 --- a/plugins/Msn/locale/it/LC_MESSAGES/Msn.po +++ /dev/null @@ -1,51 +0,0 @@ -# Translation of StatusNet - Msn to Italian (italiano) -# Exported from translatewiki.net -# -# Author: GreenFox -# Author: Od1n -# -- -# This file is distributed under the same license as the StatusNet package. -# -msgid "" -msgstr "" -"Project-Id-Version: StatusNet - Msn\n" -"Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2012-06-30 11:07+0000\n" -"PO-Revision-Date: 2012-06-30 11:09:19+0000\n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: 8bit\n" -"X-POT-Import-Date: 2011-12-03 13:48:56+0000\n" -"X-Translation-Project: translatewiki.net \n" -"X-Generator: MediaWiki 1.20alpha (233fc08); Translate 2012-06-21\n" -"Plural-Forms: nplurals=2; plural=(n != 1);\n" - -#. TRANS: MSN bot status message. -msgid "Send me a message to post a notice" -msgstr "Mandami un messaggio per pubblicare una comunicazione." - -#. TRANS: Server exception thrown when a message to be sent through MSN cannot be added to the database queue. -msgid "Database error inserting queue item." -msgstr "Errore nel database inserendo l'elemento in coda." - -#. TRANS: Display name of the MSN instant messaging service. -msgid "MSN" -msgstr "MSN" - -#. TRANS: Exception thrown when configuration for the MSN plugin is incomplete. -msgid "Must specify a user." -msgstr "Devi specificare un utente." - -#. TRANS: Exception thrown when configuration for the MSN plugin is incomplete. -msgid "Must specify a password." -msgstr "Devi specificare una password." - -#. TRANS: Exception thrown when configuration for the MSN plugin is incomplete. -msgid "Must specify a nickname." -msgstr "È necessario specificare un soprannome." - -#. TRANS: Plugin description. -msgid "" -"The MSN plugin allows users to send and receive notices over the MSN network." -msgstr "" -"Il plugin per MSN consente agli utenti di inviare e ricevere notizie tramite " -"la rete MSN." diff --git a/plugins/Msn/locale/mk/LC_MESSAGES/Msn.po b/plugins/Msn/locale/mk/LC_MESSAGES/Msn.po deleted file mode 100644 index d1faf2383c..0000000000 --- a/plugins/Msn/locale/mk/LC_MESSAGES/Msn.po +++ /dev/null @@ -1,53 +0,0 @@ -# Translation of StatusNet - Msn to Macedonian (македонски) -# Exported from translatewiki.net -# -# Author: Bjankuloski06 -# -- -# This file is distributed under the same license as the StatusNet package. -# -msgid "" -msgstr "" -"Project-Id-Version: StatusNet - Msn\n" -"Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2012-06-30 11:07+0000\n" -"PO-Revision-Date: 2012-06-30 11:09:19+0000\n" -"Language-Team: Macedonian \n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: 8bit\n" -"X-POT-Import-Date: 2011-12-03 13:48:56+0000\n" -"X-Generator: MediaWiki 1.20alpha (233fc08); Translate 2012-06-21\n" -"X-Translation-Project: translatewiki.net \n" -"X-Language-Code: mk\n" -"X-Message-Group: #out-statusnet-plugin-msn\n" -"Plural-Forms: nplurals=2; plural=(n == 1 || n%10 == 1) ? 0 : 1;\n" - -#. TRANS: MSN bot status message. -msgid "Send me a message to post a notice" -msgstr "Испрати ми порака за да објавам забелешка" - -#. TRANS: Server exception thrown when a message to be sent through MSN cannot be added to the database queue. -msgid "Database error inserting queue item." -msgstr "Грешка во базата при вметнувањето на ставка во редот на чекање." - -#. TRANS: Display name of the MSN instant messaging service. -msgid "MSN" -msgstr "MSN" - -#. TRANS: Exception thrown when configuration for the MSN plugin is incomplete. -msgid "Must specify a user." -msgstr "Мора да наведете корисник." - -#. TRANS: Exception thrown when configuration for the MSN plugin is incomplete. -msgid "Must specify a password." -msgstr "Мора да наведете лозинка." - -#. TRANS: Exception thrown when configuration for the MSN plugin is incomplete. -msgid "Must specify a nickname." -msgstr "Мора да наведете прекар." - -#. TRANS: Plugin description. -msgid "" -"The MSN plugin allows users to send and receive notices over the MSN network." -msgstr "" -"Приклучокот за MSN им овозможува на корисниците да испраќаат и примаат " -"забелешки преку мрежата на MSN." diff --git a/plugins/Msn/locale/nl/LC_MESSAGES/Msn.po b/plugins/Msn/locale/nl/LC_MESSAGES/Msn.po deleted file mode 100644 index 76e66ef6e3..0000000000 --- a/plugins/Msn/locale/nl/LC_MESSAGES/Msn.po +++ /dev/null @@ -1,54 +0,0 @@ -# Translation of StatusNet - Msn to Dutch (Nederlands) -# Exported from translatewiki.net -# -# Author: Siebrand -# -- -# This file is distributed under the same license as the StatusNet package. -# -msgid "" -msgstr "" -"Project-Id-Version: StatusNet - Msn\n" -"Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2012-06-30 11:07+0000\n" -"PO-Revision-Date: 2012-06-30 11:09:19+0000\n" -"Language-Team: Dutch \n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: 8bit\n" -"X-POT-Import-Date: 2011-12-03 13:48:56+0000\n" -"X-Generator: MediaWiki 1.20alpha (233fc08); Translate 2012-06-21\n" -"X-Translation-Project: translatewiki.net \n" -"X-Language-Code: nl\n" -"X-Message-Group: #out-statusnet-plugin-msn\n" -"Plural-Forms: nplurals=2; plural=(n != 1);\n" - -#. TRANS: MSN bot status message. -msgid "Send me a message to post a notice" -msgstr "Mij een bericht sturen om een mededeling te verzenden" - -#. TRANS: Server exception thrown when a message to be sent through MSN cannot be added to the database queue. -msgid "Database error inserting queue item." -msgstr "" -"Er is een databasefout opgetreden tijdens het invoegen van het queueitem." - -#. TRANS: Display name of the MSN instant messaging service. -msgid "MSN" -msgstr "MSN" - -#. TRANS: Exception thrown when configuration for the MSN plugin is incomplete. -msgid "Must specify a user." -msgstr "Geef een gebruiker op." - -#. TRANS: Exception thrown when configuration for the MSN plugin is incomplete. -msgid "Must specify a password." -msgstr "Geef een wachtwoord op." - -#. TRANS: Exception thrown when configuration for the MSN plugin is incomplete. -msgid "Must specify a nickname." -msgstr "Geef een nickname op." - -#. TRANS: Plugin description. -msgid "" -"The MSN plugin allows users to send and receive notices over the MSN network." -msgstr "" -"Maakt het mogelijk om mededelingen te zenden naar en ontvangen van het MSN-" -"netwerk." diff --git a/plugins/Msn/locale/pt/LC_MESSAGES/Msn.po b/plugins/Msn/locale/pt/LC_MESSAGES/Msn.po deleted file mode 100644 index 493131436c..0000000000 --- a/plugins/Msn/locale/pt/LC_MESSAGES/Msn.po +++ /dev/null @@ -1,51 +0,0 @@ -# Translation of StatusNet - Msn to Portuguese (Português) -# Exported from translatewiki.net -# -# Author: SandroHc -# -- -# This file is distributed under the same license as the StatusNet package. -# -msgid "" -msgstr "" -"Project-Id-Version: StatusNet - Msn\n" -"Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2011-04-27 12:36+0000\n" -"PO-Revision-Date: 2011-04-27 12:37:47+0000\n" -"Language-Team: Portuguese \n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: 8bit\n" -"X-POT-Import-Date: 2011-03-26 16:22:40+0000\n" -"X-Generator: MediaWiki 1.18alpha (r87008); Translate extension (2011-04-26)\n" -"X-Translation-Project: translatewiki.net at http://translatewiki.net\n" -"X-Language-Code: pt\n" -"X-Message-Group: #out-statusnet-plugin-msn\n" -"Plural-Forms: nplurals=2; plural=(n != 1);\n" - -#. TRANS: MSN bot status message. -msgid "Send me a message to post a notice" -msgstr "" - -#. TRANS: Server exception thrown when a message to be sent through MSN cannot be added to the database queue. -msgid "Database error inserting queue item." -msgstr "" - -#. TRANS: Display name of the MSN instant messaging service. -msgid "MSN" -msgstr "MSN" - -#. TRANS: Exception thrown when configuration for the MSN plugin is incomplete. -msgid "Must specify a user." -msgstr "" - -#. TRANS: Exception thrown when configuration for the MSN plugin is incomplete. -msgid "Must specify a password." -msgstr "" - -#. TRANS: Exception thrown when configuration for the MSN plugin is incomplete. -msgid "Must specify a nickname." -msgstr "" - -#. TRANS: Plugin description. -msgid "" -"The MSN plugin allows users to send and receive notices over the MSN network." -msgstr "" diff --git a/plugins/Msn/locale/sv/LC_MESSAGES/Msn.po b/plugins/Msn/locale/sv/LC_MESSAGES/Msn.po deleted file mode 100644 index 3151a5ad88..0000000000 --- a/plugins/Msn/locale/sv/LC_MESSAGES/Msn.po +++ /dev/null @@ -1,54 +0,0 @@ -# Translation of StatusNet - Msn to Swedish (svenska) -# Exported from translatewiki.net -# -# Author: Lokal Profil -# Author: WikiPhoenix -# -- -# This file is distributed under the same license as the StatusNet package. -# -msgid "" -msgstr "" -"Project-Id-Version: StatusNet - Msn\n" -"Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2012-06-30 11:07+0000\n" -"PO-Revision-Date: 2012-06-30 11:09:19+0000\n" -"Language-Team: Swedish \n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: 8bit\n" -"X-POT-Import-Date: 2011-12-03 13:48:56+0000\n" -"X-Generator: MediaWiki 1.20alpha (233fc08); Translate 2012-06-21\n" -"X-Translation-Project: translatewiki.net \n" -"X-Language-Code: sv\n" -"X-Message-Group: #out-statusnet-plugin-msn\n" -"Plural-Forms: nplurals=2; plural=(n != 1);\n" - -#. TRANS: MSN bot status message. -msgid "Send me a message to post a notice" -msgstr "" - -#. TRANS: Server exception thrown when a message to be sent through MSN cannot be added to the database queue. -msgid "Database error inserting queue item." -msgstr "" - -#. TRANS: Display name of the MSN instant messaging service. -msgid "MSN" -msgstr "MSN" - -#. TRANS: Exception thrown when configuration for the MSN plugin is incomplete. -msgid "Must specify a user." -msgstr "Du måste ange en användare." - -#. TRANS: Exception thrown when configuration for the MSN plugin is incomplete. -msgid "Must specify a password." -msgstr "Du måste ange ett lösenord." - -#. TRANS: Exception thrown when configuration for the MSN plugin is incomplete. -msgid "Must specify a nickname." -msgstr "Du måste ange ett smeknamn." - -#. TRANS: Plugin description. -msgid "" -"The MSN plugin allows users to send and receive notices over the MSN network." -msgstr "" -"MSN-tillägget tillåter användare skicka och ta emot meddelanden över MSN-" -"nätverket." diff --git a/plugins/Msn/locale/tl/LC_MESSAGES/Msn.po b/plugins/Msn/locale/tl/LC_MESSAGES/Msn.po deleted file mode 100644 index 09070c74e1..0000000000 --- a/plugins/Msn/locale/tl/LC_MESSAGES/Msn.po +++ /dev/null @@ -1,53 +0,0 @@ -# Translation of StatusNet - Msn to Tagalog (Tagalog) -# Exported from translatewiki.net -# -# Author: AnakngAraw -# -- -# This file is distributed under the same license as the StatusNet package. -# -msgid "" -msgstr "" -"Project-Id-Version: StatusNet - Msn\n" -"Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2012-06-30 11:07+0000\n" -"PO-Revision-Date: 2012-06-30 11:09:19+0000\n" -"Language-Team: Tagalog \n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: 8bit\n" -"X-POT-Import-Date: 2011-12-03 13:48:56+0000\n" -"X-Generator: MediaWiki 1.20alpha (233fc08); Translate 2012-06-21\n" -"X-Translation-Project: translatewiki.net \n" -"X-Language-Code: tl\n" -"X-Message-Group: #out-statusnet-plugin-msn\n" -"Plural-Forms: nplurals=2; plural=(n != 1);\n" - -#. TRANS: MSN bot status message. -msgid "Send me a message to post a notice" -msgstr "Padalhan ako ng isang mensahe upang makapagpaskil ng isang pabatid" - -#. TRANS: Server exception thrown when a message to be sent through MSN cannot be added to the database queue. -msgid "Database error inserting queue item." -msgstr "Kamalian ng kalipunan ng dato sa pagsisingit ng bagay ng pila." - -#. TRANS: Display name of the MSN instant messaging service. -msgid "MSN" -msgstr "MSN" - -#. TRANS: Exception thrown when configuration for the MSN plugin is incomplete. -msgid "Must specify a user." -msgstr "Dapat tumukoy ng isang tagagamit." - -#. TRANS: Exception thrown when configuration for the MSN plugin is incomplete. -msgid "Must specify a password." -msgstr "Dapat tumukoy ng isang hudyat." - -#. TRANS: Exception thrown when configuration for the MSN plugin is incomplete. -msgid "Must specify a nickname." -msgstr "Dapat tumukoy ng isang palayaw." - -#. TRANS: Plugin description. -msgid "" -"The MSN plugin allows users to send and receive notices over the MSN network." -msgstr "" -"Ang pampasak ng MSN ay nagpapahintulot sa mga tagagamit na makapagpadala at " -"makatanggap ng mga pabatid sa ibabaw ng kalambatan ng MSN." diff --git a/plugins/Msn/locale/uk/LC_MESSAGES/Msn.po b/plugins/Msn/locale/uk/LC_MESSAGES/Msn.po deleted file mode 100644 index 0126127bdc..0000000000 --- a/plugins/Msn/locale/uk/LC_MESSAGES/Msn.po +++ /dev/null @@ -1,53 +0,0 @@ -# Translation of StatusNet - Msn to Ukrainian (українська) -# Exported from translatewiki.net -# -# Author: Boogie -# -- -# This file is distributed under the same license as the StatusNet package. -# -msgid "" -msgstr "" -"Project-Id-Version: StatusNet - Msn\n" -"Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2012-06-30 11:07+0000\n" -"PO-Revision-Date: 2012-06-30 11:09:19+0000\n" -"Language-Team: Ukrainian \n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: 8bit\n" -"X-POT-Import-Date: 2011-12-03 13:48:56+0000\n" -"X-Generator: MediaWiki 1.20alpha (233fc08); Translate 2012-06-21\n" -"X-Translation-Project: translatewiki.net \n" -"X-Language-Code: uk\n" -"X-Message-Group: #out-statusnet-plugin-msn\n" -"Plural-Forms: nplurals=3; plural=(n%10 == 1 && n%100 != 11) ? 0 : ( (n%10 >= " -"2 && n%10 <= 4 && (n%100 < 10 || n%100 >= 20)) ? 1 : 2 );\n" - -#. TRANS: MSN bot status message. -msgid "Send me a message to post a notice" -msgstr "Надіслати повідомлення, щоб опублікувати новий допис." - -#. TRANS: Server exception thrown when a message to be sent through MSN cannot be added to the database queue. -msgid "Database error inserting queue item." -msgstr "Помилка бази даних при вставці елемента черги." - -#. TRANS: Display name of the MSN instant messaging service. -msgid "MSN" -msgstr "MSN" - -#. TRANS: Exception thrown when configuration for the MSN plugin is incomplete. -msgid "Must specify a user." -msgstr "Необхідно зазначити користувача." - -#. TRANS: Exception thrown when configuration for the MSN plugin is incomplete. -msgid "Must specify a password." -msgstr "Необхідно вказати пароль." - -#. TRANS: Exception thrown when configuration for the MSN plugin is incomplete. -msgid "Must specify a nickname." -msgstr "Необхідно вказати псевдонім." - -#. TRANS: Plugin description. -msgid "" -"The MSN plugin allows users to send and receive notices over the MSN network." -msgstr "" -"Додаток MSN дозволяє користувачам надсилати і отримувати дописи у мережі MSN." -- 2.39.5