24 #include "transport.h"
26 #include "precommandjob.h"
27 #include "smtp/smtpsession.h"
33 #include <KLocalizedString>
37 #include <KIO/Scheduler>
38 #include <KPasswordDialog>
40 using namespace MailTransport;
45 SlavePool() : ref( 0 ) {}
49 void removeSlave( KIO::Slave *slave,
bool disconnect =
false )
51 kDebug() <<
"Removing slave" << slave <<
"from pool";
52 const int slaveKey = slaves.
key( slave );
54 slaves.remove( slaveKey );
56 KIO::Scheduler::disconnectSlave( slave );
62 K_GLOBAL_STATIC( SlavePool, s_slavePool )
71 SmtpJobPrivate(
SmtpJob *parent ) : q( parent ) {}
75 #ifndef MAILTRANSPORT_INPROCESS_SMTP
79 q->setError( KJob::UserDefinedError );
89 Idle, Precommand, Smtp
95 :
TransportJob( transport, parent ), d( new SmtpJobPrivate( this ) )
97 d->currentState = SmtpJobPrivate::Idle;
100 if ( !s_slavePool.isDestroyed() ) {
103 KIO::Scheduler::connect( SIGNAL(slaveError(KIO::Slave*,
int,
QString)),
104 this, SLOT(slaveError(KIO::Slave*,
int,
QString)) );
109 if ( !s_slavePool.isDestroyed() ) {
111 if ( s_slavePool->ref == 0 ) {
112 kDebug() <<
"clearing SMTP slave pool" << s_slavePool->slaves.count();
113 foreach ( KIO::Slave *slave, s_slavePool->slaves ) {
115 KIO::Scheduler::disconnectSlave( slave );
118 s_slavePool->slaves.clear();
126 if ( s_slavePool.isDestroyed() ) {
130 if ( ( !s_slavePool->slaves.isEmpty() &&
131 s_slavePool->slaves.contains(
transport()->
id() ) ) ||
133 d->currentState = SmtpJobPrivate::Smtp;
136 d->currentState = SmtpJobPrivate::Precommand;
143 void SmtpJob::startSmtpJob()
145 if ( s_slavePool.isDestroyed() ) {
150 destination.setProtocol( (
transport()->encryption() == Transport::EnumEncryption::SSL ) ?
151 SMTPS_PROTOCOL : SMTP_PROTOCOL );
152 destination.setHost(
transport()->host().trimmed() );
153 destination.setPort(
transport()->port() );
172 if (
transport()->requiresAuthentication() ) {
176 transport()->authenticationType() != Transport::EnumAuthenticationType::GSSAPI ) {
181 KPasswordDialog::ShowUsernameLine |
182 KPasswordDialog::ShowKeepPassword );
183 dlg->setPrompt( i18n(
"You need to supply a username and a password "
184 "to use this SMTP server." ) );
185 dlg->setKeepPassword(
transport()->storePassword() );
187 dlg->setUsername( user );
188 dlg->setPassword( passwd );
192 transport()->setUserName( dlg->username() );
194 transport()->setStorePassword( dlg->keepPassword() );
201 setError( KilledJobError );
206 destination.setUser(
transport()->userName() );
207 destination.setPass(
transport()->password() );
211 if ( !
data().isEmpty() ) {
220 #ifndef MAILTRANSPORT_INPROCESS_SMTP
221 d->slave = s_slavePool->slaves.value(
transport()->
id() );
223 KIO::MetaData slaveConfig;
225 (
transport()->encryption() == Transport::EnumEncryption::TLS ) ?
227 if (
transport()->requiresAuthentication() ) {
230 d->slave = KIO::Scheduler::getConnectedSlave( destination, slaveConfig );
231 kDebug() <<
"Created new SMTP slave" << d->slave;
232 s_slavePool->slaves.insert(
transport()->
id(), d->slave );
234 kDebug() <<
"Re-using existing slave" << d->slave;
237 KIO::TransferJob *job = KIO::put( destination, -1, KIO::HideProgressInfo );
238 if ( !d->slave || !job ) {
239 setError( UserDefinedError );
240 setErrorText( i18n(
"Unable to create SMTP job." ) );
246 connect( job, SIGNAL(dataReq(KIO::Job*,
QByteArray&)),
250 KIO::Scheduler::assignJobToSlave( d->slave, job );
256 if (
transport()->requiresAuthentication() ) {
262 setTotalAmount( KJob::Bytes,
data().length() );
265 bool SmtpJob::doKill()
267 if ( s_slavePool.isDestroyed() ) {
271 if ( !hasSubjobs() ) {
274 if ( d->currentState == SmtpJobPrivate::Precommand ) {
275 return subjobs().first()->kill();
276 }
else if ( d->currentState == SmtpJobPrivate::Smtp ) {
277 KIO::SimpleJob *job =
static_cast<KIO::SimpleJob*
>( subjobs().first() );
279 KIO::Scheduler::cancelJob( job );
280 s_slavePool->removeSlave( d->slave );
286 void SmtpJob::slotResult( KJob *job )
288 if ( s_slavePool.isDestroyed() ) {
313 int errorCode = error();
315 errorCode = job->error();
318 if ( errorCode && d->currentState == SmtpJobPrivate::Smtp ) {
319 s_slavePool->removeSlave( d->slave, errorCode != KIO::ERR_SLAVE_DIED );
320 TransportJob::slotResult( job );
324 TransportJob::slotResult( job );
325 if ( !error() && d->currentState == SmtpJobPrivate::Precommand ) {
326 d->currentState = SmtpJobPrivate::Smtp;
335 void SmtpJob::dataRequest( KIO::Job *job,
QByteArray &data )
337 if ( s_slavePool.isDestroyed() ) {
343 if (
buffer()->atEnd() ) {
346 Q_ASSERT(
buffer()->isOpen() );
349 setProcessedAmount( KJob::Bytes,
buffer()->pos() );
352 void SmtpJob::slaveError( KIO::Slave *slave,
int errorCode,
const QString &errorMsg )
354 if ( s_slavePool.isDestroyed() ) {
358 s_slavePool->removeSlave( slave, errorCode != KIO::ERR_SLAVE_DIED );
359 if ( d->slave == slave && !d->finished ) {
360 setError( errorCode );
361 setErrorText( KIO::buildErrorString( errorCode, errorMsg ) );
366 #include "moc_smtpjob.cpp"
QStringList bcc() const
Returns the "Bcc" receiver(s) of the mail.
const Key key(const T &value) const
void setPassword(const QString &passwd)
Sets the password of this transport.
QString password()
Returns the password of this transport.
Connection to an SMTP server.
Mail transport job for SMTP.
virtual void start()
Executes the precommand.
void setSaslMethod(const QString &method)
Sets the SASL method used for authentication.
Job to execute a command.
QString number(int n, int base)
void setUseTLS(bool useTLS)
Enable TLS encryption.
QStringList cc() const
Returns the "Cc" receiver(s) of the mail.
SmtpJob(Transport *transport, QObject *parent=0)
Creates a SmtpJob.
QString sender() const
Returns the sender of the mail.
qint64 read(char *data, qint64 maxSize)
Abstract base class for all mail transport jobs.
QByteArray data() const
Returns the data of the mail.
virtual void doStart()
Do the actual work, implement in your subclass.
QString errorMessage() const
Returns the error nmeesage, if any.
Internal file containing constant definitions etc.
Represents the settings of a specific mail transport.
QStringList to() const
Returns the "To" receiver(s) of the mail.
void sendMessage(const KUrl &destination, QIODevice *data)
Send a message.
virtual ~SmtpJob()
Deletes this job.
Transport * transport() const
Returns the Transport object containing the mail transport settings.
QBuffer * buffer()
Returns a QBuffer opened on the message data.