summaryrefslogtreecommitdiffstats
path: root/kopete/protocols/yahoo/libkyahoo/sendfiletask.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'kopete/protocols/yahoo/libkyahoo/sendfiletask.cpp')
-rw-r--r--kopete/protocols/yahoo/libkyahoo/sendfiletask.cpp217
1 files changed, 180 insertions, 37 deletions
diff --git a/kopete/protocols/yahoo/libkyahoo/sendfiletask.cpp b/kopete/protocols/yahoo/libkyahoo/sendfiletask.cpp
index d0f843f2..5cdcf5c3 100644
--- a/kopete/protocols/yahoo/libkyahoo/sendfiletask.cpp
+++ b/kopete/protocols/yahoo/libkyahoo/sendfiletask.cpp
@@ -2,7 +2,7 @@
Kopete Yahoo Protocol
Send a file
- Copyright (c) 2006 AndrĂ© Duffeck <[email protected]>
+ Copyright (c) 2006 AndrĂ© Duffeck <[email protected]>
*************************************************************************
* *
@@ -21,6 +21,7 @@
#include "client.h"
#include <qstring.h>
#include <qtimer.h>
+#include <kapplication.h> // for random()
#include <kdebug.h>
#include <klocale.h>
#include <kstreamsocket.h>
@@ -30,9 +31,11 @@ using namespace KNetwork;
SendFileTask::SendFileTask(Task* parent) : Task(parent)
{
- kdDebug(YAHOO_RAW_DEBUG) << k_funcinfo << endl;
+ kdDebug(YAHOO_GEN_DEBUG) << k_funcinfo << endl;
m_transmitted = 0;
m_socket = 0;
+
+ QTime epoch(0, 0, 0);
}
SendFileTask::~SendFileTask()
@@ -41,47 +44,159 @@ SendFileTask::~SendFileTask()
m_socket = 0;
}
+bool SendFileTask::forMe( const Transfer *transfer ) const
+{
+ const YMSGTransfer *t = static_cast<const YMSGTransfer*>(transfer);
+
+ if(!t)
+ return false;
+
+ if((t->service() == Yahoo::ServiceFileTransfer7 ||
+ t->service() == Yahoo::ServiceFileTransfer7Accept) &&
+ t->firstParam(265).data() == m_yahooTransferId)
+ {
+ return true;
+ }
+
+ return false;
+}
+
+bool SendFileTask::take(Transfer* transfer)
+{
+ if( !forMe( transfer ) )
+ return false;
+
+ YMSGTransfer *t = static_cast<YMSGTransfer*>(transfer);
+
+ kdDebug(YAHOO_RAW_DEBUG) << t->service() << endl;
+
+ if(t->service() == Yahoo::ServiceFileTransfer7)
+ parseFileTransfer(t);
+ else if(t->service() == Yahoo::ServiceFileTransfer7Accept)
+ parseTransferAccept(t);
+
+ return true;
+}
+
+void SendFileTask::parseFileTransfer( const Transfer *transfer )
+{
+ kdDebug(YAHOO_GEN_DEBUG) << k_funcinfo << endl;
+
+ const YMSGTransfer *t = static_cast<const YMSGTransfer*>(transfer);
+
+ if(!t)
+ return;
+
+ if(t->firstParam(222).toInt() == 4)
+ {
+ emit declined();
+ }
+ else if(t->firstParam(222).toInt() == 3)
+ {
+ sendFileTransferInfo();
+ }
+ else
+ {
+ setError();
+ emit error(m_transferId, 0, i18n("Unknown error"));
+ }
+}
+
void SendFileTask::onGo()
{
- kdDebug(YAHOO_RAW_DEBUG) << k_funcinfo << endl;
+ kdDebug(YAHOO_GEN_DEBUG) << k_funcinfo << endl;
+
+ m_file.setName( m_url.path() );
+
+ m_yahooTransferId = newYahooTransferId();
+
+ YMSGTransfer *t = new YMSGTransfer(Yahoo::ServiceFileTransfer7);
+ t->setId( client()->sessionID() );
+
+ t->setParam( 1, client()->userId().local8Bit() );
+ t->setParam( 5, m_target.local8Bit() );
+ t->setParam( 265, m_yahooTransferId.local8Bit() );
+ t->setParam( 222, 1 );
+ t->setParam( 266, 1 );
+ t->setParam( 302, 268 );
+ t->setParam( 300, 268 );
+ t->setParam( 27, m_url.fileName().local8Bit() );
+ t->setParam( 28, m_file.size());
+ t->setParam( 301, 268 );
+ t->setParam( 303, 268 );
- QTimer::singleShot( 0, this, SLOT(initiateUpload()) );
+ send( t );
}
-void SendFileTask::initiateUpload()
+void SendFileTask::sendFileTransferInfo()
+{
+ kdDebug(YAHOO_GEN_DEBUG) << k_funcinfo << endl;
+
+ KResolverResults results = KResolver::resolve("filetransfer.msg.yahoo.com", QString::number(80));
+ if(results.count() > 0)
+ {
+ m_relayHost = results.first().address().toString();
+ m_relayHost = m_relayHost.left( m_relayHost.length() - 3 ); // Remove the :80 from the end
+ kdDebug(YAHOO_GEN_DEBUG) << k_funcinfo << m_relayHost << endl;
+ }
+ else
+ {
+ emit error(m_transferId, 0, i18n("Unable to connect to file transfer server"));
+ setError();
+ return;
+ }
+
+ YMSGTransfer *t = new YMSGTransfer(Yahoo::ServiceFileTransfer7Info);
+ t->setId( client()->sessionID() );
+
+ t->setParam( 1, client()->userId().local8Bit() );
+ t->setParam( 5, m_target.local8Bit() );
+ t->setParam( 265, m_yahooTransferId.local8Bit() );
+ t->setParam( 27, m_url.fileName().local8Bit() );
+ t->setParam( 249, 3 );
+ t->setParam( 250, m_relayHost.local8Bit() );
+
+ send( t );
+}
+
+void SendFileTask::parseTransferAccept(const Transfer *transfer)
{
- kdDebug(YAHOO_RAW_DEBUG) << k_funcinfo << endl;
- m_socket = new KStreamSocket( "filetransfer.msg.yahoo.com", QString::number(80) );
+ kdDebug(YAHOO_GEN_DEBUG) << k_funcinfo << endl;
+
+ const YMSGTransfer *t = static_cast<const YMSGTransfer*>(transfer);
+
+ // Disconnected
+ if(t->status() == Yahoo::StatusDisconnected)
+ {
+ setError();
+ return;
+ }
+
+ m_token = KURL::encode_string(t->firstParam(251));
+ kdDebug(YAHOO_RAW_DEBUG) << "Token: " << m_token << endl;
+
+ m_socket = new KStreamSocket( m_relayHost, QString::number(80) );
m_socket->setBlocking( true );
connect( m_socket, SIGNAL( connected( const KResolverEntry& ) ), this, SLOT( connectSucceeded() ) );
connect( m_socket, SIGNAL( gotError(int) ), this, SLOT( connectFailed(int) ) );
m_socket->connect();
+
}
void SendFileTask::connectFailed( int i )
{
- QString err = m_socket->errorString();
- kdDebug(YAHOO_RAW_DEBUG) << k_funcinfo << i << ": " << err << endl;
+ QString err = KSocketBase::errorString(m_socket->error());
+ kdDebug(YAHOO_RAW_DEBUG) << i << ": " << err << endl;
emit error( m_transferId, i, err );
- setSuccess( false );
+ setError();
}
void SendFileTask::connectSucceeded()
{
- kdDebug(YAHOO_RAW_DEBUG) << k_funcinfo << endl;
- YMSGTransfer t( Yahoo::ServiceFileTransfer );
+ kdDebug(YAHOO_GEN_DEBUG) << k_funcinfo << endl;
- m_file.setName( m_url.path() );
-
- t.setId( client()->sessionID() );
- t.setParam( 0, client()->userId().local8Bit());
- t.setParam( 5, m_target.local8Bit());
- t.setParam( 28, m_file.size() );
- t.setParam( 27, m_url.fileName().local8Bit() );
- t.setParam( 14, "" );
QByteArray buffer;
- QByteArray paket;
QDataStream stream( buffer, IO_WriteOnly );
if ( m_file.open(IO_ReadOnly ) )
@@ -90,22 +205,25 @@ void SendFileTask::connectSucceeded()
}
else
{
- client()->notifyError( i18n( "An error occured sending the file." ), m_file.errorString(), Client::Error );
- setSuccess( false );
+ kdDebug(YAHOO_RAW_DEBUG) << k_funcinfo << "Error opening file: " << m_file.errorString() << endl;
+ client()->notifyError( i18n( "An error occurred while sending the file." ), m_file.errorString(), Client::Error );
+ setError();
return;
}
- paket = t.serialize();
- kdDebug(YAHOO_RAW_DEBUG) << k_funcinfo << "Sizes: File (" << m_url << "): " << m_file.size() << " - paket: " << paket.size() << endl;
- QString header = QString::fromLatin1("POST http://filetransfer.msg.yahoo.com:80/notifyft HTTP/1.1\r\n"
- "Cookie: Y=%1; T=%2; C=%3 ;B=fckeert1kk1nl&b=2\r\n"
- "User-Agent: Mozilla/4.0 (compatible; MSIE 5.5)\r\n"
- "Host: filetransfer.msg.yahoo.com:80\r\n"
- "Content-length: %4\r\n"
- "Cache-Control: no-cache\r\n\r\n").arg(client()->yCookie()).arg(client()->tCookie()).arg(client()->cCookie()).arg(m_file.size()+4+paket.size());
+ kdDebug(YAHOO_RAW_DEBUG) << k_funcinfo << "Sizes: File (" << m_url << "): " << m_file.size() << endl;
+ QString header =
+ "POST /relay?token=" + m_token +
+ "&sender=" + client()->userId() +
+ "&recver=" + m_target + " HTTP/1.1\r\n"
+ "User-Agent: Mozilla/5.0\r\n"
+ "Cache-Control: no-cache\r\n"
+ "Cookie: T=" + client()->tCookie() + "; Y=" + client()->yCookie() + "\r\n"
+ "Host: " + m_relayHost + "\r\n"
+ "Content-Length: " + QString::number(m_file.size()) + "\r\n"
+ "Connection: Close\r\n\r\n";
+ kdDebug() << header << endl;
stream.writeRawBytes( header.local8Bit(), header.length() );
- stream.writeRawBytes( paket.data(), paket.size() );
- stream << (Q_INT8)0x32 << (Q_INT8)0x39 << (Q_INT8)0xc0 << (Q_INT8)0x80;
if( !m_socket->writeBlock( buffer, buffer.size() ) )
{
@@ -121,7 +239,7 @@ void SendFileTask::connectSucceeded()
void SendFileTask::transmitData()
{
- kdDebug(YAHOO_RAW_DEBUG) << k_funcinfo << endl;
+ kdDebug(YAHOO_GEN_DEBUG) << k_funcinfo << endl;
int read = 0;
int written = 0;
char buf[1024];
@@ -138,14 +256,14 @@ void SendFileTask::transmitData()
{
kdDebug(YAHOO_RAW_DEBUG) << k_funcinfo << "Upload Failed!" << endl;
emit error( m_transferId, m_socket->error(), m_socket->errorString() );
- setSuccess( false );
+ setError();
return;
}
if( m_transmitted == m_file.size() )
{
kdDebug(YAHOO_RAW_DEBUG) << k_funcinfo << "Upload Successful: " << m_transmitted << endl;
emit complete( m_transferId );
- setSuccess( true );
+ setSuccess();
m_socket->close();
}
else
@@ -182,7 +300,32 @@ void SendFileTask::canceled( unsigned int id )
if( m_socket )
m_socket->close();
- setSuccess( false );
+ setError();
+}
+
+QString SendFileTask::newYahooTransferId()
+{
+ // Adapted from libpurple/protocols/yahoo/yahoo_filexfer.c yahoo_xfer_new_xfer_id()
+
+ QString newId;
+
+ for(int i = 0; i < 22; i++)
+ {
+ char j = KApplication::random() % 61;
+
+ if(j < 26)
+ newId += j + 'a';
+ else if(j < 52)
+ newId += j - 26 + 'A';
+ else
+ newId += j - 52 + '0';
+ }
+
+ newId += "$$";
+
+ kdDebug() << "New Yahoo Transfer Id: " << newId << endl;
+
+ return newId;
}
#include "sendfiletask.moc"