diff options
author | Michele Calgaro <[email protected]> | 2014-03-29 00:54:51 +0900 |
---|---|---|
committer | Michele Calgaro <[email protected]> | 2014-03-29 00:54:51 +0900 |
commit | 0486034738b850c210b1389a8c3ae51a6b9fad23 (patch) | |
tree | b1e3a4dbf9673b5e0031e8225e88f5dd490585a5 /kopete/protocols/msn/msnnotifysocket.cpp | |
parent | 4bd7620e88d450995b78c201f9e7d9181f62ea6a (diff) | |
download | tdenetwork-0486034738b850c210b1389a8c3ae51a6b9fad23.tar.gz tdenetwork-0486034738b850c210b1389a8c3ae51a6b9fad23.zip |
Removed MSN support across Kopete by removing the MSN protocol and the netmeeting plugin.
This resolves bug 1547.
Diffstat (limited to 'kopete/protocols/msn/msnnotifysocket.cpp')
-rw-r--r-- | kopete/protocols/msn/msnnotifysocket.cpp | 1309 |
1 files changed, 0 insertions, 1309 deletions
diff --git a/kopete/protocols/msn/msnnotifysocket.cpp b/kopete/protocols/msn/msnnotifysocket.cpp deleted file mode 100644 index ec9b27c8..00000000 --- a/kopete/protocols/msn/msnnotifysocket.cpp +++ /dev/null @@ -1,1309 +0,0 @@ -/* - msnnotifysocket.cpp - Notify Socket for the MSN Protocol - - Copyright (c) 2002 by Duncan Mac-Vicar Prett <[email protected]> - Copyright (c) 2002-2003 by Martijn Klingens <[email protected]> - Copyright (c) 2002-2005 by Olivier Goffart <ogoffart at kde.org> - Copyright (c) 2005 by Michaël Larouche <[email protected]> - Copyright (c) 2005 by Gregg Edghill <[email protected]> - - Kopete (c) 2002-2005 by the Kopete developers <[email protected]> - - Portions taken from - KMerlin (c) 2001 by Olaf Lueg <[email protected]> - - ************************************************************************* - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - ************************************************************************* -*/ - -#include "msnnotifysocket.h" -#include "msncontact.h" -#include "msnaccount.h" -#include "msnsecureloginhandler.h" -#include "msnchallengehandler.h" - -#include <tqdatetime.h> -#include <tqregexp.h> -#include <tqdom.h> - -#include <kdebug.h> -#include <tdeversion.h> -#include <tdelocale.h> -#include <kmdcodec.h> -#include <tdemessagebox.h> -#include <kstandarddirs.h> -#include <tdetempfile.h> -#include <krun.h> -#include <tdeio/job.h> -#include <tqfile.h> -#include <tdeconfig.h> -#include <knotification.h> - -#include "kopeteuiglobal.h" -#include "kopeteglobal.h" - -#include <ctime> - - -MSNNotifySocket::MSNNotifySocket( MSNAccount *account, const TQString& /*msnId*/, const TQString &password ) -: MSNSocket( account ) -{ - m_newstatus = MSNProtocol::protocol()->NLN; - m_secureLoginHandler=0L; - m_challengeHandler = 0L; - - m_isHotmailAccount=false; - m_ping=false; - m_disconnectReason=Kopete::Account::Unknown; - - m_account = account; - m_password=password; - TQObject::connect( this, TQT_SIGNAL( blockRead( const TQByteArray & ) ), - this, TQT_SLOT( slotReadMessage( const TQByteArray & ) ) ); - m_keepaliveTimer = 0L; - m_isLogged = false; -} - -MSNNotifySocket::~MSNNotifySocket() -{ - delete m_secureLoginHandler; - delete m_challengeHandler; - - kdDebug(14140) << k_funcinfo << endl; -} - -void MSNNotifySocket::doneConnect() -{ -// kdDebug( 14140 ) << k_funcinfo << "Negotiating server protocol version" << endl; - sendCommand( "VER", "MSNP11 MSNP10 CVR0" ); -} - - -void MSNNotifySocket::disconnect() -{ - m_isLogged = false; - if( m_disconnectReason==Kopete::Account::Unknown ) - m_disconnectReason=Kopete::Account::Manual; - if( onlineStatus() == Connected ) - sendCommand( "OUT", TQString(), false ); - - if( m_keepaliveTimer ) - m_keepaliveTimer->stop(); - - // the socket is not connected yet, so I should force the signals - if ( onlineStatus() == Disconnected || onlineStatus() == Connecting ) - emit socketClosed(); - else - MSNSocket::disconnect(); -} - -void MSNNotifySocket::handleError( uint code, uint id ) -{ - kdDebug(14140) << k_funcinfo << endl; - - TQString handle; - if(m_tmpHandles.contains(id)) - handle=m_tmpHandles[id]; - - TQString msg; - MSNSocket::ErrorType type; - // See http://www.hypothetic.org/docs/msn/basics.php for a - // description of all possible error codes. - // TODO: Add support for all of these! - switch( code ) - { - case 201: - case 205: - case 208: - { - msg = i18n( "<qt>The MSN user '%1' does not exist.<br>Please check the MSN ID.</qt>" ).arg( handle ); - type = MSNSocket::ErrorServerError; - break; - } - case 207: - case 218: - case 540: - { - msg = i18n( "<qt>An internal error occurred in the MSN plugin.<br>" - "MSN Error: %1<br>" - "please send us a detailed bug report " - "at [email protected] containing the raw debug output on the " - "console (in gzipped format, as it is probably a lot of output.)" ).arg(code); - type = MSNSocket::ErrorServerError; - break; - } - case 209: - { - if(handle==m_account->accountId()) - { - msg = i18n( "Unable to change your display name.\n" - "Please ensure your display is not too long and does not contains censored words." ); - type = MSNSocket::ErrorServerError; - } - /*else - { - TQString msg = i18n( "You are trying to change the display name of a user who has not " - "confirmed his or her email address;\n" - "the contact was not renamed on the server." ); - KMessageBox::queuedMessageBox( Kopete::UI::Global::mainWidget(), KMessageBox::Error, msg, i18n( "MSN Plugin" ) ); - }*/ - break; - } - case 210: - { - msg = i18n("Your contact list is full; you cannot add any new contacts."); - type = MSNSocket::ErrorServerError; - break; - } - case 215: - { - msg = i18n( "<qt>The user '%1' already exists in this group on the MSN server;<br>" - "if Kopete does not show the user, please send us a detailed bug report " - "at [email protected] containing the raw debug output on the " - "console (in gzipped format, as it is probably a lot of output.)</qt>" ).arg(handle); - type = MSNSocket::ErrorInformation; - break; - } - case 216: - { - //This might happen is you rename an user if he is not in the contactlist - //currently, we just iniore; - //TODO: try to don't rename user not in the list - //actualy, the bug is in MSNChatSession::slotUserJoined() - break; - } - case 219: - { - msg = i18n( "The user '%1' seems to already be blocked or allowed on the server." ).arg(handle); - type = MSNSocket::ErrorServerError; - break; - } - case 223: - { - msg = i18n( "You have reached the maximum number of groups:\n" - "MSN does not support more than 30 groups." ); - type = MSNSocket::ErrorServerError; - break; - } - case 224: - case 225: - case 230: - { - msg = i18n("Kopete is trying to perform an operation on a group or a contact that does not exists on the server.\n" - "This might happen if the Kopete contact list and the MSN-server contact list are not correctly synchronized; if this is the case, you probably should send a bug report."); - type = MSNSocket::ErrorServerError; - break; - } - - case 229: - { - msg = i18n("The group name is too long; it has not been changed on the MSN server."); - type = MSNSocket::ErrorServerError; - break; - } - case 710: - { - msg = i18n( "You cannot open a Hotmail inbox because you do not have an MSN account with a valid " - "Hotmail or MSN mailbox." ); - type = MSNSocket::ErrorServerError; - break; - } - case 715: - { - /* - //if(handlev==m_account->accountId()) - TQString msg = i18n( "Your email address has not been verified with the MSN server.\n" - "You should have received a mail with a link to confirm your email address.\n" - "Some functions will be restricted if you do not confirm your email address." ); - KMessageBox::queuedMessageBox( Kopete::UI::Global::mainWidget(), KMessageBox::Sorry, msg, i18n( "MSN Plugin" ) );//TODO don't show again - */ - break; - } - case 800: - { - //This happen when too much commends are sent to the server. - //the command will not be executed, too bad. - // ignore it for now, as we don't really know what command it was. - /* TQString msg = i18#n( "You are trying to change your status, or your display name too rapidly.\n" - "This might happen if you added yourself to your own contact list." ); - KMessageBox::queuedMessageBox( Kopete::UI::Global::mainWidget(), KMessageBox::Sorry, msg, i18n( "MSN Plugin" ) ); - //FIXME: try to fix this problem*/ - break; - } - case 911: - m_disconnectReason=Kopete::Account::BadPassword; - disconnect(); - break; - case 913: - { - msg = i18n( "You can not send messages when you are offline or when you are invisible." ); - type = MSNSocket::ErrorServerError; - break; - } - case 923: - { - msg = i18n( "You are trying to perform an action you are not allowed to perform in 'kid mode'." ); - type = MSNSocket::ErrorServerError; - break; - } - - default: - MSNSocket::handleError( code, id ); - break; - } - - if( !msg.isEmpty() ) - emit errorMessage( type, msg ); -} - -void MSNNotifySocket::parseCommand( const TQString &cmd, uint id, const TQString &data ) -{ - //kdDebug(14140) << "MSNNotifySocket::parseCommand: Command: " << cmd << endl; - - if ( cmd == "VER" ) - { - sendCommand( "CVR", "0x0409 winnt 5.1 i386 MSNMSGR 7.0.0816 MSMSGS " + m_account->accountId() ); -/* - struct utsname utsBuf; - uname ( &utsBuf ); - - sendCommand( "CVR", i18n( "MS Local code, see http://www.microsoft.com/globaldev/reference/oslocversion.mspx", "0x0409" ) + - " " + escape( utsBuf.sysname ) + " " + escape( utsBuf.release ) + " " + escape( utsBuf.machine ) + " Kopete " + - escape( kapp->aboutData()->version() ) + " Kopete " + m_msnId ); -*/ - } - else if ( cmd == "CVR" ) //else if ( cmd == "INF" ) - { - sendCommand( "USR", "TWN I " + m_account->accountId() ); - } - else if( cmd == "USR" ) //// here follow the auth processus - { - if( data.section( ' ', 1, 1 ) == "S" ) - { - m_secureLoginHandler = new MSNSecureLoginHandler(m_account->accountId(), m_password, data.section( ' ' , 2 , 2 )); - - TQObject::connect(m_secureLoginHandler, TQT_SIGNAL(loginFailed()), this, TQT_SLOT(sslLoginFailed())); - TQObject::connect(m_secureLoginHandler, TQT_SIGNAL(loginBadPassword()), this, TQT_SLOT(sslLoginIncorrect())); - TQObject::connect(m_secureLoginHandler, TQT_SIGNAL(loginSuccesful(TQString )), this, TQT_SLOT(sslLoginSucceeded(TQString ))); - - m_secureLoginHandler->login(); - } - else - { - // Successful authentication. - m_disconnectReason=Kopete::Account::Unknown; - - // Synchronize with the server. - TQString lastSyncTime, lastChange; - - if(m_account->contacts().count() > 1) - { - // Retrieve the last synchronization timestamp, and last change timestamp. - lastSyncTime = m_account->configGroup()->readEntry("lastsynctime", "0"); - lastChange = m_account->configGroup()->readEntry("lastchange", "0"); - } - else - { - //the contactliust has maybe being removed, force to sync - //(the only contact is myself) - lastSyncTime="0"; - lastChange="0"; - } - - sendCommand( "SYN", lastChange + " " + lastSyncTime); - // Get client features. - if(!useHttpMethod()) { - sendCommand( "GCF", "Shields.xml"); - // We are connected start to ping - slotSendKeepAlive(); - } - } - } - else if( cmd == "LST" ) - { - // MSNP11 changed command. Now it's: - // LST [email protected] F=Display%20Name C=xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx 13 xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx - // But can be - // LST [email protected] 10 - TQString publicName, contactGuid, groups; - uint lists; - - TQRegExp regex("N=([^ ]+)(?: F=([^ ]+))?(?: C=([0-9a-fA-F]{8}\\-[0-9a-fA-F]{4}\\-[0-9a-fA-F]{4}\\-[0-9a-fA-F]{4}\\-[0-9a-fA-F]{12}))? (\\d+)\\s?((?:[0-9a-fA-F]{8}\\-[0-9a-fA-F]{4}\\-[0-9a-fA-F]{4}\\-[0-9a-fA-F]{4}\\-[0-9a-fA-F]{12},?)*)$"); - regex.search(data); - - // Capture passport email. - m_tmpLastHandle = regex.cap(1); - // Capture public name. - publicName = unescape( regex.cap(2) ); - // Capture contact guid. - contactGuid = regex.cap(3); - // Capture list enum type. - lists = regex.cap(4).toUInt(); - // Capture contact group(s) guid(s) - groups = regex.cap(5); - -// kdDebug(14140) << k_funcinfo << " msnId: " << m_tmpLastHandle << " publicName: " << publicName << " contactGuid: " << contactGuid << " list: " << lists << " groupGuid: " << groups << endl; - - // handle, publicName, Contact GUID, lists, Group GUID - emit contactList( m_tmpLastHandle , publicName, contactGuid, lists, groups ); - } - else if( cmd == "GCF" ) - { - m_configFile = data.section(' ', 0, 0); - readBlock( data.section( ' ', 1, 1 ).toUInt() ); - } - else if( cmd == "MSG" ) - { - readBlock( data.section( ' ', 2, 2 ).toUInt() ); - } - else if( cmd == "ILN" || cmd == "NLN" ) - { - // status handle publicName strangeNumber MSNOBJECT - MSNContact *c = static_cast<MSNContact*>( m_account->contacts()[ data.section( ' ', 1, 1 ) ] ); - if( c && c->contactId() != m_account->accountId() ) - { - TQString publicName=unescape( data.section( ' ', 2, 2 ) ); - if ( (publicName!=c->contactId() || c->hasProperty(Kopete::Global::Properties::self()->nickName().key()) ) && - publicName!=c->property( Kopete::Global::Properties::self()->nickName()).value().toString() ) - - changePublicName(publicName,c->contactId()); - TQString obj=unescape(data.section( ' ', 4, 4 )); - c->setObject( obj ); - c->setOnlineStatus( convertOnlineStatus( data.section( ' ', 0, 0 ) ) ); - c->setClientFlags(data.section( ' ', 3, 3 ).toUInt()); - } - } - else if( cmd == "UBX" ) - { - m_tmpLastHandle = data.section(' ', 0, 0); - uint length = data.section( ' ', 1, 1 ).toUInt(); - if(length > 0) { - readBlock( length ); - } - } - else if( cmd == "UUX" ) - { - // UUX is sended to acknowledge that the server has received and processed the personal Message. - // if the result is 0, set the myself() contact personalMessage. - if( data.section(' ', 0, 0) == TQString::fromUtf8("0") ) - m_account->myself()->setProperty(MSNProtocol::protocol()->propPersonalMessage, m_propertyPersonalMessage); - } - else if( cmd == "FLN" ) - { - MSNContact *c = static_cast<MSNContact*>( m_account->contacts()[ data.section( ' ', 0, 0 ) ] ); - if( c && c->contactId() != m_account->accountId() ) - { - c->setOnlineStatus( MSNProtocol::protocol()->FLN ); - c->removeProperty( MSNProtocol::protocol()->propClient ); - } - } - else if( cmd == "XFR" ) - { - TQString stype=data.section( ' ', 0, 0 ); - if( stype=="SB" ) //switchboard connection (chat) - { - // Address, AuthInfo - emit startChat( data.section( ' ', 1, 1 ), data.section( ' ', 3, 3 ) ); - } - else if( stype=="NS" ) //notifysocket ; Got our notification server - { //we are connecting and we receive the initial NS, or the msn server encounter a problem, and we are switching to another switchboard - TQString host = data.section( ' ', 1, 1 ); - TQString server = host.section( ':', 0, 0 ); - uint port = host.section( ':', 1, 1 ).toUInt(); - setOnlineStatus( Connected ); - emit receivedNotificationServer( server, port ); - disconnect(); - } - - } - else if( cmd == "RNG" ) - { - // SessionID, Address, AuthInfo, handle, publicName - emit invitedToChat( TQString::number( id ), data.section( ' ', 0, 0 ), data.section( ' ', 2, 2 ), - data.section( ' ', 3, 3 ), unescape( data.section( ' ', 4, 4 ) ) ); - } - else if( cmd == "ADC" ) - { - TQString msnId, list, publicName, contactGuid, groupGuid; - - // Retrieve the list parameter (FL/AL/BL/RL) - list = data.section( ' ', 0, 0 ); - - // Examples of received data - // ADC TrID xL [email protected] - // ADC TrID FL C=contactGuid groupdGuid - // ADC TrID RL [email protected] F=friednly%20name - // ADC TrID FL [email protected] F=My%20Name C=contactGuid - // Thanks Gregg for that complex RegExp. - TQRegExp regex("(?:N=([^ ]+))?(?: F=([^ ]+))?(?: C=([0-9a-fA-F]{8}\\-[0-9a-fA-F]{4}\\-[0-9a-fA-F]{4}\\-[0-9a-fA-F]{4}\\-[0-9a-fA-F]{12}))?\\s?((?:[0-9a-fA-F]{8}\\-[0-9a-fA-F]{4}\\-[0-9a-fA-F]{4}\\-[0-9a-fA-F]{4}\\-[0-9a-fA-F]{12},?)*)$"); - regex.search( data.section( ' ', 1 ) ); - - // Capture passport email. - msnId = regex.cap(1); - // Capture public name. - publicName = unescape( regex.cap(2) ); - // Capture contact guid. - contactGuid = regex.cap(3); - // Capture contact group(s) guid(s) - groupGuid = regex.cap(4); - -// kdDebug(14140) << k_funcinfo << list << " msnId: " << msnId << " publicName: " << publicName << " contactGuid: " << contactGuid << " groupGuid: " << groupGuid << endl; - - // handle, list, publicName, contactGuid, groupGuid - emit contactAdded( msnId, list, publicName, contactGuid, groupGuid ); - } - else if( cmd == "REM" ) // someone is removed from a list - { - TQString handle, list, contactGuid, groupGuid; - list = data.section( ' ', 0, 0 ); - if( list == "FL" ) - { - // Removing a contact - if( data.contains( ' ' ) < 2 ) - { - contactGuid = data.section( ' ', 1, 1 ); - } - // Removing a contact from a group - else if( data.contains( ' ' ) < 3 ) - { - contactGuid = data.section( ' ', 1, 1 ); - groupGuid = data.section( ' ', 2, 2 ); - } - } - else - { - handle = data.section( ' ', 1, 1); - } - - // handle, list, contactGuid, groupGuid - emit contactRemoved( handle, list, contactGuid, groupGuid ); - - } - else if( cmd == "OUT" ) - { - if( data.section( ' ', 0, 0 ) == "OTH" ) - { - m_disconnectReason=Kopete::Account::OtherClient; - } - disconnect(); - } - else if( cmd == "CHG" ) - { - TQString status = data.section( ' ', 0, 0 ); - setOnlineStatus( Connected ); - emit statusChanged( convertOnlineStatus( status ) ); - } - else if( cmd == "SBP" ) - { - TQString contactGuid, type, publicName; - contactGuid = data.section( ' ', 0, 0 ); - type = data.section( ' ', 1, 1 ); - if(type == "MFN" ) - { - publicName = unescape( data.section( ' ', 2, 2 ) ); - MSNContact *c = m_account->findContactByGuid( contactGuid ); - if(c != 0L) - { - c->setProperty( Kopete::Global::Properties::self()->nickName(), publicName ); - } - } - } - else if( cmd == "LSG" ) - { - // New Format: LSG Friends xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx - // groupDisplayName, groupGuid - emit groupListed( unescape( data.section( ' ', 0, 0 ) ), data.section( ' ', 1, 1) ); - } - else if( cmd == "ADG" ) - { - // groupName, groupGuid - emit groupAdded( unescape( data.section( ' ', 0, 0 ) ), - data.section( ' ', 1, 1 ) ); - } - else if( cmd == "REG" ) - { - // groupGuid, groupName - emit groupRenamed( data.section( ' ', 0, 0 ), unescape( data.section( ' ', 1, 1 ) ) ); - } - else if( cmd == "RMG" ) - { - // groupGuid - emit groupRemoved( data.section( ' ', 1, 1 ) ); - } - else if( cmd == "CHL" ) - { - m_challengeHandler = new MSNChallengeHandler("CFHUR$52U_{VIX5T", "PROD0101{0RM?UBW"); - // Compute the challenge response hash, and send the response. - TQString chlResponse = m_challengeHandler->computeHash(data.section(' ', 0, 0)); - sendCommand("QRY", m_challengeHandler->productId(), true, chlResponse.utf8()); - // Dispose of the challenge handler. - m_challengeHandler->deleteLater(); - m_challengeHandler = 0L; - } - else if( cmd == "SYN" ) - { - // Retrieve the last synchronization timestamp known to the server. - TQString lastSyncTime = data.section( ' ', 1, 1 ); - TQString lastChange = data.section( ' ', 0, 0 ); - if( lastSyncTime != m_account->configGroup()->readEntry("lastsynctime") || - lastChange != m_account->configGroup()->readEntry("lastchange") ) - { - // If the server timestamp and the local timestamp are different, - // prepare to receive the contact list. - emit newContactList(); // remove all contacts datas, msn sends a new contact list - m_account->configGroup()->writeEntry( "lastsynctime" , lastSyncTime); - m_account->configGroup()->writeEntry( "lastchange", lastChange); - }else - kdDebug(14140) << k_funcinfo << "Contact list up-to-date." << endl; - - // set the status - setStatus( m_newstatus ); - } - else if( cmd == "BPR" ) - { - MSNContact *c = static_cast<MSNContact*>( m_account->contacts()[ m_tmpLastHandle ] ); - if( c ) - c->setInfo(data.section( ' ', 0, 0 ),unescape(data.section( ' ', 1, 1 ))); - } - else if( cmd == "PRP" ) - { - MSNContact *c = static_cast<MSNContact*>( m_account->myself() ); - if( c ) - { - TQString type = data.section( ' ', 0, 0 ); - TQString prpData = unescape( data.section( ' ', 1, 1 ) ); //SECURITY???????? - c->setInfo( type, prpData ); - m_account->configGroup()->writeEntry( type, prpData ); - } - } - else if( cmd == "BLP" ) - { - if( id > 0 ) //FROM BLP - { - m_account->configGroup()->writeEntry( "serial" , data.section( ' ', 0, 0 ) ); - m_account->configGroup()->writeEntry( "BLP" , data.section( ' ', 1, 1 ) ); - } - else //FROM SYN - m_account->configGroup()->writeEntry( "BLP" , data.section( ' ', 0, 0 ) ); - } - else if( cmd == "QRY" ) - { - // Do nothing - } - else if( cmd == "QNG" ) - { - //this is a reply from a ping - m_ping=false; - - // id is the timeout in fact, and we remove 5% of it - if( m_keepaliveTimer ) - m_keepaliveTimer->start( id * 950, true ); - kdDebug( 14140 ) << k_funcinfo << "timerTimeout=" << id << "sec"<< endl; - } - else if( cmd == "URL" ) - { - // URL 6 /cgi-bin/HoTMaiL https://loginnet.passport.com/ppsecure/md5auth.srf?lc=1033 2 - //example of reply: URL 10 /cgi-bin/HoTMaiL https://msnialogin.passport.com/ppsecure/md5auth.srf?lc=1036 3 - TQString from_action_url = data.section( ' ', 1, 1 ); - TQString rru = data.section( ' ', 0, 0 ); - TQString id = data.section( ' ', 2, 2 ); - - //write the tmp file - TQString UserID=m_account->accountId(); - - time_t actualTime; - time(&actualTime); - TQString sl = TQString::number( ( unsigned long ) actualTime - m_loginTime.toULong() ); - - TQString md5this( m_MSPAuth + sl + m_password ); - KMD5 md5( md5this.utf8() ); - - TQString hotmailRequest = "<html>\n" - "<head>\n" - "<noscript>\n" - "<meta http-equiv=Refresh content=\"0; url=http://www.hotmail.com\">\n" - "</noscript>\n" - "</head>\n" - "<body onload=\"document.pform.submit(); \">\n" - "<form name=\"pform\" action=\"" + from_action_url + "\" method=\"POST\">\n" - "<input type=\"hidden\" name=\"mode\" value=\"ttl\">\n" - "<input type=\"hidden\" name=\"login\" value=\"" + UserID.left( UserID.find('@') ) + "\">\n" - "<input type=\"hidden\" name=\"username\" value=\"" + UserID + "\">\n" - "<input type=\"hidden\" name=\"sid\" value=\"" + m_sid + "\">\n" - "<input type=\"hidden\" name=\"kv\" value=\"" + m_kv + "\">\n" - "<input type=\"hidden\" name=\"id\" value=\""+ id +"\">\n" - "<input type=\"hidden\" name=\"sl\" value=\"" + sl +"\">\n" - "<input type=\"hidden\" name=\"rru\" value=\"" + rru + "\">\n" - "<input type=\"hidden\" name=\"auth\" value=\"" + m_MSPAuth + "\">\n" - "<input type=\"hidden\" name=\"creds\" value=\"" + TQString::fromLatin1( md5.hexDigest() ) + "\">\n" - "<input type=\"hidden\" name=\"svc\" value=\"mail\">\n" - "<input type=\"hidden\" name=\"js\" value=\"yes\">\n" - "</form></body>\n</html>\n"; - - KTempFile tmpMailFile( locateLocal( "tmp", "kopetehotmail-" ), ".html" ); - *tmpMailFile.textStream() << hotmailRequest; - tmpMailFile.file()->flush(); - - KRun::runURL( KURL::fromPathOrURL( tmpMailFile.name() ), "text/html" , true ); - - } - else if ( cmd == "NOT" ) - { - kdDebug( 14140 ) << k_funcinfo << "Received NOT command, issueing read block for '" << id << " more bytes" << endl; - readBlock( id ); - } - else - { - // Let the base class handle the rest - //MSNSocket::parseCommand( cmd, id, data ); - kdDebug( 14140 ) << k_funcinfo << "Unimplemented command '" << cmd << " " << id << " " << data << "' from server!" << endl; - } -} - - -void MSNNotifySocket::sslLoginFailed() -{ - m_disconnectReason=Kopete::Account::InvalidHost; - disconnect(); -} - -void MSNNotifySocket::sslLoginIncorrect() -{ - m_disconnectReason=Kopete::Account::BadPassword; - disconnect(); -} - -void MSNNotifySocket::sslLoginSucceeded(TQString ticket) -{ - sendCommand("USR" , "TWN S " + ticket); - - m_secureLoginHandler->deleteLater(); - m_secureLoginHandler = 0L; -} - -void MSNNotifySocket::slotMSNAlertUnwanted() -{ - // user not interested .. clean up the list of actions - m_msnAlertURLs.clear(); -} - -void MSNNotifySocket::slotMSNAlertLink(unsigned int action) -{ - // index into our action list and pull out the URL that was clicked .. - KURL tempURLForLaunch(m_msnAlertURLs[action-1]); - - KRun* urlToRun = new KRun(tempURLForLaunch); -} - -void MSNNotifySocket::slotOpenInbox() -{ - sendCommand("URL", "INBOX" ); -} - -void MSNNotifySocket::sendMail(const TQString &email) -{ - sendCommand("URL", TQString("COMPOSE " + email).utf8() ); -} - -bool MSNNotifySocket::setUseHttpMethod(bool useHttp) -{ - bool ret = MSNSocket::setUseHttpMethod( useHttp ); - - if( useHttpMethod() ) { - if( m_keepaliveTimer ) { - delete m_keepaliveTimer; - m_keepaliveTimer = 0L; - } - } - else { - if( !m_keepaliveTimer ) { - m_keepaliveTimer = new TQTimer( this, "m_keepaliveTimer" ); - TQObject::connect( m_keepaliveTimer, TQT_SIGNAL( timeout() ), TQT_SLOT( slotSendKeepAlive() ) ); - } - } - - return ret; -} - -void MSNNotifySocket::slotReadMessage( const TQByteArray &bytes ) -{ - TQString msg = TQString::fromUtf8(bytes, bytes.size()); - - if(msg.contains("text/x-msmsgsinitialmdatanotification")) - { - //Mail-Data: <MD><E><I>301</I><IU>1</IU><O>4</O><OU>2</OU></E><Q><TQTM>409600</TQTM><TQNM>204800</TQNM></Q></MD> - // MD - Mail Data - // E - email - // I - initial mail - // IU - initial unread - // O - other mail - // OU - other unread. - TQRegExp regex("<MD><E><I>(\\d+)?</I>(?:<IU>(\\d+)?</IU>)<O>(\\d+)?</O><OU>(\\d+)?</OU></E><Q>.*</Q></MD>"); - regex.search(msg); - - bool unread; - // Retrieve the number of unread email messages. - mailCount = regex.cap(2).toUInt(&unread); - if(unread && mailCount > 0) - { - // If there are new email message available, raise the unread email event. - TQObject::connect(KNotification::event( "msn_mail", i18n( "You have one unread message in your MSN inbox.", - "You have %n unread messages in your MSN inbox.", mailCount ), 0 , 0 , i18n( "Open Inbox..." ) ), - TQT_SIGNAL(activated(unsigned int ) ) , this, TQT_SLOT( slotOpenInbox() ) ); - } - } - else if(msg.contains("text/x-msmsgsactivemailnotification")) - { - //this sends the server if mails are deleted - TQString m = msg.right(msg.length() - msg.find("Message-Delta:") ); - m = m.left(msg.find("\r\n")); - mailCount = mailCount - m.right(m.length() -m.find(" ")-1).toUInt(); - } - else if(msg.contains("text/x-msmsgsemailnotification")) - { - //this sends the server if a new mail has arrived - TQRegExp rx("From-Addr: ([A-Za-z0-9@._\\-]*)"); - rx.search(msg); - TQString m=rx.cap(1); - - mailCount++; - - //TODO: it is also possible to get the subject (but warning about the encoding) - TQObject::connect(KNotification::event( "msn_mail",i18n( "You have one new email from %1 in your MSN inbox." ).arg(m), - 0 , 0 , i18n( "Open Inbox..." ) ), - TQT_SIGNAL(activated(unsigned int ) ) , this, TQT_SLOT( slotOpenInbox() ) ); - } - else if(msg.contains("text/x-msmsgsprofile")) - { - //Hotmail profile - if(msg.contains("MSPAuth:")) - { - TQRegExp rx("MSPAuth: ([A-Za-z0-9$!*]*)"); - rx.search(msg); - m_MSPAuth=rx.cap(1); - } - if(msg.contains("sid:")) - { - TQRegExp rx("sid: ([0-9]*)"); - rx.search(msg); - m_sid=rx.cap(1); - } - if(msg.contains("kv:")) - { - TQRegExp rx("kv: ([0-9]*)"); - rx.search(msg); - m_kv=rx.cap(1); - } - if(msg.contains("LoginTime:")) - { - TQRegExp rx("LoginTime: ([0-9]*)"); - rx.search(msg); - m_loginTime=rx.cap(1); - } - else //IN MSNP9 there are no logintime it seems, so set it manualy - { - time_t actualTime; - time(&actualTime); - m_loginTime=TQString::number((unsigned long)actualTime); - } - if(msg.contains("EmailEnabled:")) - { - TQRegExp rx("EmailEnabled: ([0-9]*)"); - rx.search(msg); - m_isHotmailAccount = (rx.cap(1).toUInt() == 1); - emit hotmailSeted(m_isHotmailAccount); - } - if(msg.contains("ClientIP:")) - { - TQRegExp rx("ClientIP: ([0-9.]*)"); - rx.search(msg); - m_localIP = rx.cap(1); - } - - // We are logged when we receive the initial profile from Hotmail. - m_isLogged = true; - } - else if (msg.contains("NOTIFICATION")) - { - // MSN alert (i.e. NOTIFICATION) [for docs see http://www.hypothetic.org/docs/msn/client/notification.php] - // format of msg is as follows: - // - // <NOTIFICATION ver="2" id="1342902633" siteid="199999999" siteurl="http://alerts.msn.com"> - // <TO pid="0x0006BFFD:0x8582C0FB" name="[email protected]"/> - // <MSG pri="1" id="1342902633"> - // <SUBSCR url="http://g.msn.com/3ALMSNTRACKING/199999999ToastChange?http://alerts.msn.com/Alerts/MyAlerts.aspx?strela=1"/> - // <ACTION url="http://g.msn.com/3ALMSNTRACKING/199999999ToastAction?http://alerts.msn.com/Alerts/MyAlerts.aspx?strela=1"/> - // <BODY lang="3076" icon=""> - // <TEXT>utf8-encoded text</TEXT> - // </BODY> - // </MSG> - // </NOTIFICATION> - - // MSN sends out badly formed XML .. fix it for them (thanks MS!) - TQString notificationDOMAsString(msg); - - TQRegExp rx( "&(?!amp;)" ); // match ampersands but not & - notificationDOMAsString.replace(rx, "&"); - TQDomDocument alertDOM; - alertDOM.setContent(notificationDOMAsString); - - TQDomNodeList msgElements = alertDOM.elementsByTagName("MSG"); - for (uint i = 0 ; i < msgElements.count() ; i++) - { - TQString subscString; - TQString actionString; - TQString textString; - - TQDomNode msgDOM = msgElements.item(i); - - TQDomNodeList msgChildren = msgDOM.childNodes(); - for (uint i = 0 ; i < msgChildren.length() ; i++) { - TQDomNode child = msgChildren.item(i); - TQDomElement element = child.toElement(); - if (element.tagName() == "SUBSCR") - { - TQDomAttr subscElementURLAttribute; - if (element.hasAttribute("url")) - { - subscElementURLAttribute = element.attributeNode("url"); - subscString = subscElementURLAttribute.value(); - } - } - else if (element.tagName() == "ACTION") - { - // process ACTION node to pull out URL the alert is tied to - TQDomAttr actionElementURLAttribute; - if (element.hasAttribute("url")) - { - actionElementURLAttribute = element.attributeNode("url"); - actionString = actionElementURLAttribute.value(); - } - } - else if (element.tagName() == "BODY") - { - // process BODY node to get the text of the alert - TQDomNodeList textElements = element.elementsByTagName("TEXT"); - if (textElements.count() >= 1) - { - TQDomElement textElement = textElements.item(0).toElement(); - textString = textElement.text(); - } - } - - - } - -// kdDebug( 14140 ) << "subscString " << subscString << " actionString " << actionString << " textString " << textString << endl; - // build an internal list of actions ... we'll need to index into this list when we receive an event - TQStringList actions; - actions.append(i18n("More Information")); - m_msnAlertURLs.append(actionString); - - actions.append(i18n("Manage Subscription")); - m_msnAlertURLs.append(subscString); - - // Don't do any MSN alerts notification for new blog updates - if( subscString != TQString::fromLatin1("s.htm") && actionString != TQString::fromLatin1("a.htm") ) - { - KNotification* notification = KNotification::event("msn_alert", textString, 0L, 0L, actions); - TQObject::connect(notification, TQT_SIGNAL(activated(unsigned int)), this, TQT_SLOT(slotMSNAlertLink(unsigned int))); - TQObject::connect(notification, TQT_SIGNAL(closed()), this, TQT_SLOT(slotMSNAlertUnwanted())); - } - } // end for each MSG tag - } - - if(!m_configFile.isNull()) - { - // TODO Get client features. - } - - if(!m_tmpLastHandle.isNull()) - { - TQString personalMessage, currentMedia; - TQDomDocument psm; - if( psm.setContent(msg) ) - { - // Get the first child of the xml "document"; - TQDomElement psmElement = psm.documentElement().firstChild().toElement(); - - while( !psmElement.isNull() ) - { - if(psmElement.tagName() == TQString::fromUtf8("PSM")) - { - personalMessage = psmElement.text(); - kdDebug(14140) << k_funcinfo << "Personnal Message received: " << personalMessage << endl; - } - else if(psmElement.tagName() == TQString::fromUtf8("CurrentMedia")) - { - if( !psmElement.text().isEmpty() ) - { - kdDebug(14140) << k_funcinfo << "XML CurrentMedia: " << psmElement.text() << endl; - currentMedia = processCurrentMedia( psmElement.text() ); - } - } - psmElement = psmElement.nextSibling().toElement(); - } - - MSNContact *contact = static_cast<MSNContact*>(m_account->contacts()[ m_tmpLastHandle ]); - if(contact) - { - contact->setProperty(MSNProtocol::protocol()->propPersonalMessage, currentMedia.isEmpty() ? personalMessage : currentMedia); - } - } - m_tmpLastHandle = TQString(); - } -} - -TQString MSNNotifySocket::processCurrentMedia( const TQString &mediaXmlElement ) -{ - /* - The value of the CurrentMedia tag you can think of like an array - seperated by "\0" characters (literal backslash followed by zero, not NULL). - - The elements of this "array" are as follows: - - * Application - This is the app you are using. Usually empty - * Type - This is the type of PSM, either “Music”, “Games” or “Office” - * Enabled - This is a boolean value (0/1) to enable/disable - * Format - A formatter string ala .Net; For example, “{0} - {1}” - * First line - The first line (Matches {0} in the Format) - * Second line - The second line (Matches {1} in the Format) - * Third line - The third line (Matches {2} in the Format) - - There is probably no limit to the number of lines unless you go over the maximum length of the tag. - - Example of currentMedia xml tag: - <CurrentMedia>\0Music\01\0{0} - {1}\0 Song Title\0Song Artist\0Song Album\0\0</CurrentMedia> - <CurrentMedia>\0Games\01\0Playing {0}\0Game Name\0</CurrentMedia> - <CurrentMedia>\0Office\01\0Office Message\0Office App Name\0</CurrentMedia> - - From http://msnpiki.msnfanatic.com/index.php/MSNP11:Changes - */ - TQString application, type, format, currentMedia; - bool enabled=false, test; - // \0 is textual, it's the "array" separator. - TQStringList argumentLists = TQStringList::split(TQString::fromUtf8("\\0"), mediaXmlElement, true); - - // Retrive the "stable" array elements. - application = argumentLists[0]; - type = argumentLists[1]; - enabled = argumentLists[2].toInt(&test); - format = argumentLists[3]; - - // Get the formatter strings - TQStringList formatterStrings; - TQStringList::ConstIterator it; - for( it = argumentLists.at(4); it != argumentLists.end(); ++it ) - { - formatterStrings.append( *it ); - } - - // Replace the formatter in the format string. - currentMedia = format; - for(uint i=0; i<formatterStrings.size(); i++) - { - currentMedia = currentMedia.replace(TQString("{%1}").arg(i), formatterStrings[i]); - } - - if( type == TQString::fromUtf8("Music") ) - { - // the "♫" is encoded in utf8 (and should be in utf8) - currentMedia = i18n("Now Listening: ♫ %1 ♫").arg(currentMedia); - } - - kdDebug(1414) << "Current Media received: " << currentMedia << endl; - - return currentMedia; -} - -void MSNNotifySocket::addGroup(const TQString& groupName) -{ - // escape spaces - sendCommand( "ADG", escape( groupName ) ); -} - -void MSNNotifySocket::renameGroup( const TQString& groupName, const TQString& groupGuid ) -{ - // escape spaces - sendCommand( "REG", groupGuid + " " + escape( groupName ) ); -} - -void MSNNotifySocket::removeGroup( const TQString& groupGuid ) -{ - sendCommand( "RMG", groupGuid ); -} - -void MSNNotifySocket::addContact( const TQString &handle, int list, const TQString& publicName, const TQString& contactGuid, const TQString& groupGuid ) -{ - TQString args; - switch( list ) - { - case MSNProtocol::FL: - { - // Adding the contact to a group - if( !contactGuid.isEmpty() ) - { - args = TQString("FL C=%1 %2").arg( contactGuid ).arg( groupGuid ); - kdDebug(14140) << k_funcinfo << "In adding contact to a group" << endl; - } - // Adding a new contact - else - { - args = TQString("FL N=%1 F=%2").arg( handle ).arg( escape( publicName ) ); - kdDebug(14140) << k_funcinfo << "In adding contact to a new contact" << endl; - } - break; - } - case MSNProtocol::AL: - args = TQString("AL N=%1").arg( handle ); - break; - case MSNProtocol::BL: - args = TQString("BL N=%1").arg( handle ); - break; - case MSNProtocol::RL: - args = TQString("RL N=%1").arg( handle ); - break; - default: - kdDebug(14140) << k_funcinfo <<"WARNING! Unknown list " << list << "!" << endl; - return; - } - unsigned int id=sendCommand( "ADC", args ); - m_tmpHandles[id]=handle; -} - -void MSNNotifySocket::removeContact( const TQString &handle, int list, const TQString& contactGuid, const TQString& groupGuid ) -{ - TQString args; - switch( list ) - { - case MSNProtocol::FL: - args = "FL " + contactGuid; - // Removing a contact from a group - if( !groupGuid.isEmpty() ) - args += " " + groupGuid; - break; - case MSNProtocol::AL: - args = "AL " + handle; - break; - case MSNProtocol::BL: - args = "BL " + handle; - break; - case MSNProtocol::PL: - args = "PL " + handle; - break; - default: - kdDebug(14140) <<k_funcinfo << "WARNING! Unknown list " << list << "!" << endl; - return; - } - unsigned int id=sendCommand( "REM", args ); - m_tmpHandles[id]=handle; -} - -void MSNNotifySocket::setStatus( const Kopete::OnlineStatus &status ) -{ -// kdDebug( 14140 ) << k_funcinfo << statusToString( status ) << endl; - - if( onlineStatus() == Disconnected ) - m_newstatus = status; - else - sendCommand( "CHG", statusToString( status ) + " " + m_account->myselfClientId() + " " + escape(m_account->pictureObject()) ); -} - -void MSNNotifySocket::changePublicName( const TQString &publicName, const TQString &handle ) -{ - TQString tempPublicName = publicName; - - //The maximum length is 387. but with utf8 or encodage, each character may be triple - // 387/3 = 129 so we make sure the length is not longer than 129 char, even if - // it's possible to have longer nicks. - if( escape(publicName).length() > 129 ) - { - tempPublicName = publicName.left(129); - } - - if( handle.isNull() ) - { - unsigned int id = sendCommand( "PRP", "MFN " + escape( tempPublicName ) ); - m_tmpHandles[id] = m_account->accountId(); - } - else - { - MSNContact *currentContact = static_cast<MSNContact *>(m_account->contacts()[handle]); - if(currentContact && !currentContact->guid().isEmpty() ) - { - // FIXME if there is not guid server disconnects. - unsigned int id = sendCommand( "SBP", currentContact->guid() + " MFN " + escape( tempPublicName ) ); - m_tmpHandles[id] = handle; - } - } -} - -void MSNNotifySocket::changePersonalMessage( MSNProtocol::PersonalMessageType type, const TQString &personalMessage ) -{ - TQString tempPersonalMessage; - TQString xmlCurrentMedia; - - // Only espace and cut the personalMessage is the type is normal. - if(type == MSNProtocol::PersonalMessageNormal) - { - tempPersonalMessage = personalMessage; - //Magic number : 129 characters - if( escape(personalMessage).length() > 129 ) - { - // We cut. for now. - tempPersonalMessage = personalMessage.left(129); - } - } - - TQDomDocument xmlMessage; - xmlMessage.appendChild( xmlMessage.createElement( "Data" ) ); - - TQDomElement psm = xmlMessage.createElement("PSM"); - psm.appendChild( xmlMessage.createTextNode( tempPersonalMessage ) ); - xmlMessage.documentElement().appendChild( psm ); - - TQDomElement currentMedia = xmlMessage.createElement("CurrentMedia"); - - /* Example of currentMedia xml tag: - <CurrentMedia>\0Music\01\0{0} - {1}\0 Song Title\0Song Artist\0Song Album\0\0</CurrentMedia> - <CurrentMedia>\0Games\01\0Playing {0}\0Game Name\0</CurrentMedia> - <CurrentMedia>\0Office\01\0Office Message\0Office App Name\0</CurrentMedia> - */ - switch(type) - { - case MSNProtocol::PersonalMessageMusic: - { - xmlCurrentMedia = "\\0Music\\01\\0"; - TQStringList mediaList = TQStringList::split(";", personalMessage); - TQString formatterArguments; - if( !mediaList[0].isEmpty() ) // Current Track - { - xmlCurrentMedia += "{0}"; - formatterArguments += TQString("%1\\0").arg(mediaList[0]); - } - if( !mediaList[1].isEmpty() ) // Current Artist - { - xmlCurrentMedia += " - {1}"; - formatterArguments += TQString("%1\\0").arg(mediaList[1]); - } - if( !mediaList[2].isEmpty() ) // Current Album - { - xmlCurrentMedia += " ({2})"; - formatterArguments += TQString("%1\\0").arg(mediaList[2]); - } - xmlCurrentMedia += "\\0" + formatterArguments + "\\0"; - break; - } - default: - break; - } - - currentMedia.appendChild( xmlMessage.createTextNode( xmlCurrentMedia ) ); - - // Set the status message for myself, check if currentMedia is empty, for either using the normal or Music personal - m_propertyPersonalMessage = xmlCurrentMedia.isEmpty() ? tempPersonalMessage : processCurrentMedia( currentMedia.text() ); - - xmlMessage.documentElement().appendChild( currentMedia ); - - unsigned int id = sendCommand("UUX","",true, xmlMessage.toString().utf8(), false); - m_tmpHandles[id] = m_account->accountId(); - -} - -void MSNNotifySocket::changePhoneNumber( const TQString &key, const TQString &data ) -{ - sendCommand( "PRP", key + " " + escape ( data ) ); -} - - -void MSNNotifySocket::createChatSession() -{ - sendCommand( "XFR", "SB" ); -} - -TQString MSNNotifySocket::statusToString( const Kopete::OnlineStatus &status ) const -{ - if( status == MSNProtocol::protocol()->NLN ) - return "NLN"; - else if( status == MSNProtocol::protocol()->BSY ) - return "BSY"; - else if( status == MSNProtocol::protocol()->BRB ) - return "BRB"; - else if( status == MSNProtocol::protocol()->AWY ) - return "AWY"; - else if( status == MSNProtocol::protocol()->PHN ) - return "PHN"; - else if( status == MSNProtocol::protocol()->LUN ) - return "LUN"; - else if( status == MSNProtocol::protocol()->FLN ) - return "FLN"; - else if( status == MSNProtocol::protocol()->HDN ) - return "HDN"; - else if( status == MSNProtocol::protocol()->IDL ) - return "IDL"; - else - { - kdWarning( 14140 ) << k_funcinfo << "Unknown status " << status.internalStatus() << "!" << endl; - return "UNK"; - } -} - -void MSNNotifySocket::slotSendKeepAlive() -{ - //we did not received the previous TQNG - if(m_ping) - { - m_disconnectReason=Kopete::Account::ConnectionReset; - disconnect(); - /*KMessageBox::queuedMessageBox( Kopete::UI::Global::mainWidget(), KMessageBox::Information, - i18n( "The connection with the MSN network has been lost." ) , i18n ("MSN Plugin") );*/ - return; - } - else - { - // Send a dummy command to fake activity. This makes sure MSN doesn't - // disconnect you when the notify socket is idle. - sendCommand( "PNG" , TQString() , false ); - m_ping=true; - } - - //at least 90 second has been ellapsed since the last messages - // we shouldn't receive error from theses command anymore - m_tmpHandles.clear(); -} - -Kopete::OnlineStatus MSNNotifySocket::convertOnlineStatus( const TQString &status ) -{ - if( status == "NLN" ) - return MSNProtocol::protocol()->NLN; - else if( status == "FLN" ) - return MSNProtocol::protocol()->FLN; - else if( status == "HDN" ) - return MSNProtocol::protocol()->HDN; - else if( status == "PHN" ) - return MSNProtocol::protocol()->PHN; - else if( status == "LUN" ) - return MSNProtocol::protocol()->LUN; - else if( status == "BRB" ) - return MSNProtocol::protocol()->BRB; - else if( status == "AWY" ) - return MSNProtocol::protocol()->AWY; - else if( status == "BSY" ) - return MSNProtocol::protocol()->BSY; - else if( status == "IDL" ) - return MSNProtocol::protocol()->IDL; - else - return MSNProtocol::protocol()->UNK; -} - - -#include "msnnotifysocket.moc" - -// vim: set noet ts=4 sts=4 sw=4: - |