Commit 99ff3840 authored by Volker Krause's avatar Volker Krause
Browse files

Sending mails via SMTP works now, using at most one slave per transport as it's done in KMail.

svn path=/trunk/KDE/kdepim/mailtransport/; revision=619462
parent f56ed69d
......@@ -43,8 +43,10 @@ TransportJob
SendmailJob
-----------
- implement doKill()
- indicate progress
SMTPJob
-------
- complete start()
- get rid of kmail specific stuff in start()
- implement doKill()
- indicate progress
......@@ -24,15 +24,51 @@
#include <klocale.h>
#include <kurl.h>
#include <kio/job.h>
#include <kio/scheduler.h>
#include <kio/slave.h>
#include <kio/passworddialog.h>
#include <qbuffer.h>
#include <qhash.h>
using namespace KPIM;
static int slavePoolRef = 0;
static QHash<int,KIO::Slave*> slavePool;
static void removeSlaveFromPool( KIO::Slave *slave, bool disconnect = false )
{
bool found = false;
for ( QHash<int,KIO::Slave*>::Iterator it = slavePool.begin(); it != slavePool.end(); ) {
if ( it.value() == slave ) {
found = true;
it = slavePool.erase( it );
} else {
++it;
}
}
if ( disconnect && found )
KIO::Scheduler::disconnectSlave( slave );
}
SmtpJob::SmtpJob(Transport * transport, QObject * parent) :
TransportJob( transport, parent )
TransportJob( transport, parent ),
mSlave( 0 )
{
slavePoolRef++;
KIO::Scheduler::connect( SIGNAL(slaveError(KIO::Slave*,int,QString)),
this, SLOT(slaveError(KIO::Slave*,int,QString)) );
}
SmtpJob::~SmtpJob()
{
slavePoolRef--;
if ( slavePoolRef == 0 ) {
kDebug() << k_funcinfo << "clearing SMTP slave pool " << slavePool.count() << endl;
foreach ( KIO::Slave *slave, slavePool.values() )
KIO::Scheduler::disconnectSlave( slave );
slavePool.clear();
}
}
void SmtpJob::start()
......@@ -90,21 +126,6 @@ void SmtpJob::start()
destination.setPass( transport()->password() );
}
// TODO: from kmsender.cpp
// if (!mSlave || !mInProcess)
// {
// KIO::MetaData slaveConfig;
// slaveConfig.insert("tls", (ti->encryption == "TLS") ? "on" : "off");
// if (ti->auth) slaveConfig.insert("sasl", ti->authType);
// mSlave = KIO::Scheduler::getConnectedSlave(destination, slaveConfig);
// }
//
// if (!mSlave)
// {
// abort();
// return false;
// }
// dotstuffing is now done by the slave (see setting of metadata)
if ( !data().isEmpty() )
// allow +5% for subsequent LF->CRLF and dotstuffing (an average
......@@ -113,17 +134,42 @@ void SmtpJob::start()
destination.setPath("/send");
destination.setQuery( query );
kDebug() << k_funcinfo << destination << endl;
KIO::Job *job = KIO::put( destination, -1, false, false, false );
Q_ASSERT( job );
mSlave = slavePool.value( transport()->id() );
if ( !mSlave ) {
kDebug() << k_funcinfo << "creating new SMTP slave" << endl;
KIO::MetaData slaveConfig;
slaveConfig.insert( "tls", (transport()->encryption() == Transport::EnumEncryption::TLS) ? "on" : "off" );
if ( transport()->requiresAuthentication() )
slaveConfig.insert( "sasl", transport()->authenticationTypeString() );
mSlave = KIO::Scheduler::getConnectedSlave( destination, slaveConfig );
slavePool.insert( transport()->id(), mSlave );
} else {
kDebug() << k_funcinfo << "re-using existing slave" << endl;
}
KIO::TransferJob *job = KIO::put( destination, -1, false, false, false );
if ( !mSlave || !job ) {
setError( UserDefinedError );
setErrorText( i18n("Unable to create SMTP job.") );
emitResult();
return;
}
job->addMetaData( "lf2crlf+dotstuff", "slave" );
connect( job, SIGNAL(dataReq(KIO::Job*,QByteArray&)), SLOT(dataRequest(KIO::Job*,QByteArray&)) );
addSubjob( job );
// TODO from kmsender.cpp
/* KIO::Scheduler::assignJobToSlave(mSlave, mJob);
connect(mJob, SIGNAL(result(KJob *)), this, SLOT(result(KJob *))); */
KIO::Scheduler::assignJobToSlave( mSlave, job );
}
void SmtpJob::slotResult(KJob * job)
{
kDebug() << k_funcinfo << job->error() << error() << endl;
TransportJob::slotResult( job );
removeSlaveFromPool( mSlave, error() != KIO::ERR_SLAVE_DIED );
if ( !error() )
emitResult();
}
void SmtpJob::dataRequest(KIO::Job * job, QByteArray & data)
......@@ -137,4 +183,15 @@ void SmtpJob::dataRequest(KIO::Job * job, QByteArray & data)
// mSender->emitProgressInfo( mMessageOffset );
}
void SmtpJob::slaveError(KIO::Slave * slave, int errorCode, const QString & errorMsg)
{
kDebug() << k_funcinfo << errorCode << errorMsg << endl;
removeSlaveFromPool( slave, errorCode != KIO::ERR_SLAVE_DIED );
if ( mSlave == slave ) {
setError( errorCode );
setErrorText( KIO::buildErrorString( errorCode, errorMsg ) );
emitResult();
}
}
#include "smtpjob.moc"
......@@ -24,6 +24,7 @@
namespace KIO {
class Job;
class Slave;
}
namespace KPIM {
......@@ -31,7 +32,7 @@ namespace KPIM {
/**
Mail transport job for SMTP.
*/
class SmtpJob : public TransportJob
class MAILTRANSPORT_EXPORT SmtpJob : public TransportJob
{
Q_OBJECT
public:
......@@ -42,10 +43,22 @@ class SmtpJob : public TransportJob
*/
SmtpJob( Transport* transport, QObject* parent = 0 );
/**
Deletes this job.
*/
virtual ~SmtpJob();
virtual void start();
protected slots:
virtual void slotResult( KJob *job );
void slaveError(KIO::Slave *slave, int errorCode, const QString &errorMsg);
private slots:
void dataRequest( KIO::Job* job, QByteArray &data );
private:
KIO::Slave* mSlave;
};
}
......
......@@ -62,6 +62,20 @@ bool Transport::isComplete() const
return !requiresAuthentication() || mPasswordLoaded;
}
QString Transport::authenticationTypeString() const
{
switch ( authenticationType() ) {
case EnumAuthenticationType::LOGIN: return QLatin1String( "LOGIN" );
case EnumAuthenticationType::PLAIN: return QLatin1String( "PLAIN" );
case EnumAuthenticationType::CRAM_MD5: return QLatin1String( "CRAM-MD5" );
case EnumAuthenticationType::DIGEST_MD5: return QLatin1String( "DIGEST-MD5" );
case EnumAuthenticationType::NTLM: return QLatin1String( "NTLM" );
case EnumAuthenticationType::GSSAPI: return QLatin1String( "GSSAPI" );
}
Q_ASSERT( false );
return QString();
}
void Transport::usrReadConfig()
{
TransportBase::usrReadConfig();
......
......@@ -62,6 +62,11 @@ class MAILTRANSPORT_EXPORT Transport : public TransportBase
*/
bool isComplete() const;
/**
Returns a string representation of the authentication type.
*/
QString authenticationTypeString() const;
protected:
/**
Creates a Transport object. Should only be used by TransportManager.
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment