Commit 9607e890 authored by Volker Krause's avatar Volker Krause
Browse files

Add mail transport jobs for sendmail and SMTP.

The sendmail job actually works, the SMTP job is still incomplete.

svn path=/trunk/KDE/kdepim/mailtransport/; revision=619047
parent 6eba31df
......@@ -6,9 +6,12 @@ set(mailtransport_lib_srcs
transport.cpp
transportcombobox.cpp
transportconfigdialog.cpp
transportjob.cpp
transportmanager.cpp
transportmanagementwidget.cpp
transporttypedialog.cpp
sendmailjob.cpp
smtpjob.cpp
)
kde4_automoc(${mailtransport_lib_srcs})
......
......@@ -3,8 +3,9 @@ Mail Transport TODO
General
-------
- use own namespace?
- message sending job classes
- use own namespace
- compile with QT_NO_ASCII_CAST and without QT3_SUPPORT
- fix license/copyright, some of the code is taken from KMail/KNode
Migration
---------
......@@ -17,6 +18,7 @@ TransportManager
- deletetion of Transport objects during reload is a problem
(create a copy for edit?)
- load passwords if another instance opens the wallet
- add job scheduler (see knode) for async wallet loading during sending
TransportComboBox
-----------------
......@@ -31,3 +33,18 @@ TransportConfigDialog
Transport
---------
- fallback to config file password storage
- use int for port number instead of QString
TransportJob
------------
- use QByteArray for addresses instead of QString
- Transport validity checking
SendmailJob
-----------
- implement doKill()
SMTPJob
-------
- complete start()
- implement doKill()
/*
Copyright (c) 2007 Volker Krause <vkrause@kde.org>
This library is free software; you can redistribute it and/or modify it
under the terms of the GNU Library General Public License as published by
the Free Software Foundation; either version 2 of the License, or (at your
option) any later version.
This library is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
License for more details.
You should have received a copy of the GNU Library General Public License
along with this library; see the file COPYING.LIB. If not, write to the
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301, USA.
*/
#include "sendmailjob.h"
#include "transport.h"
#include <klocale.h>
#include <kprocess.h>
#include <qbuffer.h>
using namespace KPIM;
SendmailJob::SendmailJob(Transport * transport, QObject * parent) :
TransportJob( transport, parent )
{
mProcess = new KProcess( this );
connect( mProcess, SIGNAL(processExited(KProcess*)), SLOT(sendmailExited()) );
connect( mProcess, SIGNAL(wroteStdin(KProcess*)), SLOT(wroteStdin()) );
connect( mProcess, SIGNAL(receivedStderr(KProcess*,char*,int)),
SLOT(receivedStdErr(KProcess*,char*,int)) );
}
void SendmailJob::start()
{
*mProcess << transport()->host() << "-i" << "-f" << sender() << to() << cc() << bcc();
if ( !mProcess->start( KProcess::NotifyOnExit, KProcess::All ) ) {
setError( UserDefinedError );
setErrorText( i18n("Failed to execute mailer program %1", transport()->host()) );
emitResult();
}
wroteStdin();
}
void SendmailJob::sendmailExited()
{
if ( !mProcess->normalExit() || !mProcess->exitStatus() == 0 ) {
setError( UserDefinedError );
setErrorText( i18n("Sendmail exited abnormally: %1", mLastError) );
}
emitResult();
}
void SendmailJob::wroteStdin()
{
if ( buffer()->atEnd() ) {
mProcess->closeStdin();
} else {
QByteArray data = buffer()->read( 1024 );
mProcess->writeStdin( data.constData(), data.length() );
}
}
void SendmailJob::receivedStdErr(KProcess * proc, char * data, int len)
{
Q_ASSERT( proc == mProcess );
kDebug() << k_funcinfo << endl;
mLastError += QString::fromLocal8Bit( data, len );
}
#include "sendmailjob.moc"
/*
Copyright (c) 2007 Volker Krause <vkrause@kde.org>
This library is free software; you can redistribute it and/or modify it
under the terms of the GNU Library General Public License as published by
the Free Software Foundation; either version 2 of the License, or (at your
option) any later version.
This library is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
License for more details.
You should have received a copy of the GNU Library General Public License
along with this library; see the file COPYING.LIB. If not, write to the
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301, USA.
*/
#ifndef KPIM_SENDMAILJOB_H
#define KPIM_SENDMAILJOB_H
#include <mailtransport/transportjob.h>
class KProcess;
namespace KPIM {
/**
Mail transport job for sendmail.
*/
class MAILTRANSPORT_EXPORT SendmailJob : public TransportJob
{
Q_OBJECT
public:
/**
Creates a SendmailJob.
@param transport The transport settings.
@param parent The parent object.
*/
SendmailJob( Transport* transport, QObject* parent = 0 );
virtual void start();
private slots:
void sendmailExited();
void wroteStdin();
void receivedStdErr( KProcess *proc, char* data, int len );
private:
KProcess* mProcess;
QString mLastError;
};
}
#endif
/*
Copyright (c) 2007 Volker Krause <vkrause@kde.org>
This library is free software; you can redistribute it and/or modify it
under the terms of the GNU Library General Public License as published by
the Free Software Foundation; either version 2 of the License, or (at your
option) any later version.
This library is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
License for more details.
You should have received a copy of the GNU Library General Public License
along with this library; see the file COPYING.LIB. If not, write to the
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301, USA.
*/
#include "smtpjob.h"
#include "transport.h"
#include "mailtransport_defs.h"
#include <klocale.h>
#include <kurl.h>
#include <kio/job.h>
#include <kio/passdlg.h>
#include <qbuffer.h>
using namespace KPIM;
SmtpJob::SmtpJob(Transport * transport, QObject * parent) :
TransportJob( transport, parent )
{
}
void SmtpJob::start()
{
QString query = "headers=0&from=";
query += KUrl::toPercentEncoding( sender() );
foreach ( QString str, to() )
query += "&to=" + KUrl::toPercentEncoding( str );
foreach ( QString str, cc() )
query += "&cc=" + KUrl::toPercentEncoding( str );
foreach ( QString str, bcc() )
query += "&bcc=" + KUrl::toPercentEncoding( str );
if ( transport()->specifyHostname() )
query += "&hostname=" + KUrl::toPercentEncoding( transport()->localHostname() );
#warning Argh!
// if ( !kmkernel->msgSender()->sendQuotedPrintable() )
// query += "&body=8bit";
KUrl destination;
destination.setProtocol( (transport()->encryption() == Transport::EnumEncryption::SSL) ? SMTPS_PROTOCOL : SMTP_PROTOCOL );
destination.setHost( transport()->host() );
destination.setPort( transport()->port().toUShort() );
if ( transport()->requiresAuthentication() ) {
if( (transport()->userName().isEmpty() || transport()->password().isEmpty())
&& transport()->authenticationType() != Transport::EnumAuthenticationType::GSSAPI )
{
QString user = transport()->userName();
QString passwd = transport()->password();
bool keep = transport()->storePassword();
int result;
#warning yet another KMail specific thing
// KCursorSaver idle( KBusyPtr::idle() );
result = KIO::PasswordDialog::getNameAndPassword(
user, passwd, &keep,
i18n("You need to supply a username and a password to use this SMTP server."),
false, QString(), transport()->name(), QString() );
if ( result != QDialog::Accepted ) {
setError( KilledJobError );
emitResult();
return;
}
transport()->setUserName( user );
transport()->setPassword( passwd );
transport()->setStorePassword( keep );
transport()->writeConfig();
}
destination.setUser( transport()->userName() );
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
// over 2G-lines gives an average line length of 42-43):
query += "&size=" + QString::number( qRound( data().length() * 1.05 ) );
destination.setPath("/send");
destination.setQuery( query );
kDebug() << k_funcinfo << destination << endl;
KIO::Job *job = KIO::put( destination, -1, false, false, false );
Q_ASSERT( job );
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 *))); */
}
void SmtpJob::dataRequest(KIO::Job * job, QByteArray & data)
{
Q_ASSERT( job );
if ( buffer()->atEnd() )
data.clear();
else
data = buffer()->read( 32*1024 );
// TODO: from kmsender.cpp
// mSender->emitProgressInfo( mMessageOffset );
}
#include "smtpjob.moc"
/*
Copyright (c) 2007 Volker Krause <vkrause@kde.org>
This library is free software; you can redistribute it and/or modify it
under the terms of the GNU Library General Public License as published by
the Free Software Foundation; either version 2 of the License, or (at your
option) any later version.
This library is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
License for more details.
You should have received a copy of the GNU Library General Public License
along with this library; see the file COPYING.LIB. If not, write to the
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301, USA.
*/
#ifndef KPIM_SMTPJOB_H
#define KPIM_SMTPJOB_H
#include <mailtransport/transportjob.h>
namespace KIO {
class Job;
}
namespace KPIM {
/**
Mail transport job for SMTP.
*/
class SmtpJob : public TransportJob
{
Q_OBJECT
public:
/**
Creates a SendmailJob.
@param transport The transport settings.
@param parent The parent object.
*/
SmtpJob( Transport* transport, QObject* parent = 0 );
virtual void start();
private slots:
void dataRequest( KIO::Job* job, QByteArray &data );
};
}
#endif
......@@ -22,20 +22,34 @@
#include <mailtransport/transportconfigdialog.h>
#include <mailtransport/transportmanager.h>
#include <mailtransport/transportmanagementwidget.h>
#include <mailtransport/transportjob.h>
#include <KApplication>
#include <KCmdLineArgs>
#include <KLineEdit>
#include <QPushButton>
#include <QTextEdit>
using namespace KPIM;
TransportMgr::TransportMgr()
{
new TransportManagementWidget( this );
mComboBox = new TransportComboBox( this );
QPushButton *b = new QPushButton( "&Edit", this );
connect( b, SIGNAL(clicked(bool)), SLOT(editBtnClicked()) );
new TransportManagementWidget( this );
mSenderEdit = new KLineEdit( this );
mSenderEdit->setClickMessage( "Sender" );
mToEdit = new KLineEdit( this );
mToEdit->setClickMessage( "To" );
mCcEdit = new KLineEdit( this );
mCcEdit->setClickMessage( "Cc" );
mBccEdit = new KLineEdit( this );
mBccEdit->setClickMessage( "Bcc" );
mMailEdit = new QTextEdit( this );
b = new QPushButton( "&Send", this );
connect( b, SIGNAL(clicked(bool)), SLOT(sendBtnClicked()) );
}
void TransportMgr::editBtnClicked()
......@@ -45,6 +59,19 @@ void TransportMgr::editBtnClicked()
delete t;
}
void TransportMgr::sendBtnClicked()
{
TransportJob *job = TransportManager::self()->createTransportJob( mComboBox->currentTransportId() );
Q_ASSERT( job );
job->setSender( mSenderEdit->text() );
job->setTo( mToEdit->text().isEmpty() ? QStringList() : mToEdit->text().split(',') );
job->setCc( mCcEdit->text().isEmpty() ? QStringList() : mCcEdit->text().split(',') );
job->setBcc( mBccEdit->text().isEmpty() ? QStringList() : mBccEdit->text().split(',') );
job->setData( mMailEdit->document()->toPlainText().toLatin1() );
connect( job, SIGNAL(result(KJob*)), SLOT(jobResult(KJob*)) );
job->start();
}
int main( int argc, char** argv )
{
KCmdLineArgs::init(argc, argv, "transportmgr", "transportmgr", "Mail Transport Manager Demo", "0" );
......@@ -54,5 +81,10 @@ int main( int argc, char** argv )
app.exec();
}
void TransportMgr::jobResult( KJob* job )
{
kDebug() << k_funcinfo << job->error() << job->errorText() << endl;
}
#include "transportmgr.moc"
......@@ -23,6 +23,10 @@
#include <KVBox>
#include <mailtransport/transportcombobox.h>
class KJob;
class KLineEdit;
class QTextEdit;
class TransportMgr : public KVBox
{
Q_OBJECT
......@@ -30,11 +34,15 @@ class TransportMgr : public KVBox
public:
TransportMgr();
public slots:
private slots:
void editBtnClicked();
void sendBtnClicked();
void jobResult( KJob* job );
private:
KPIM::TransportComboBox* mComboBox;
KLineEdit *mSenderEdit, *mToEdit, *mCcEdit, *mBccEdit;
QTextEdit *mMailEdit;
};
#endif
/*
Copyright (c) 2007 Volker Krause <vkrause@kde.org>
This library is free software; you can redistribute it and/or modify it
under the terms of the GNU Library General Public License as published by
the Free Software Foundation; either version 2 of the License, or (at your
option) any later version.
This library is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
License for more details.
You should have received a copy of the GNU Library General Public License
along with this library; see the file COPYING.LIB. If not, write to the
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301, USA.
*/
#include "transport.h"
#include "transportjob.h"
#include <qbuffer.h>
using namespace KPIM;
class KPIM::TransportJob::Private
{
public:
Transport* transport;
QString sender;
QStringList to;
QStringList cc;
QStringList bcc;
QByteArray data;
QBuffer *buffer;
};
TransportJob::TransportJob( Transport* transport, QObject * parent ) :
KCompositeJob( parent ),
d( new Private )
{
d->transport = transport;
d->buffer = 0;
}
void TransportJob::setSender(const QString & sender)
{
d->sender = sender;
}
void TransportJob::setTo(const QStringList &to)
{
d->to = to;
}
void TransportJob::setCc(const QStringList &cc)
{
d->cc = cc;
}
void TransportJob::setBcc(const QStringList &bcc)
{
d->bcc = bcc;
}
void TransportJob::setData(const QByteArray & data)
{
d->data = data;
}
Transport* TransportJob::transport() const
{
return d->transport;
}
QString TransportJob::sender() const
{
return d->sender;
}
QStringList TransportJob::to() const
{
return d->to;
}
QStringList TransportJob::cc() const
{
return d->cc;
}
QStringList TransportJob::bcc() const
{
return d->bcc;
}
QByteArray TransportJob::data() const
{
return d->data;
}
QBuffer* TransportJob::buffer()
{
if ( !d->buffer ) {
d->buffer = new QBuffer( this );
d->buffer->setData( d->data );
Q_ASSERT( d->buffer->open( QIODevice::ReadOnly ) );
}
return d->buffer;
}
/*
Copyright (c) 2007 Volker Krause <vkrause@kde.org>
This library is free software; you can redistribute it and/or modify it
under the terms of the GNU Library General Public License as published by
the Free Software Foundation; either version 2 of the License, or (at your
option) any later version.
This library is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
License for more details.
You should have received a copy of the GNU Library General Public License
along with this library; see the file COPYING.LIB. If not, write to the
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301, USA.
*/
#ifndef KPIM_TRANSPORTJOB_H
#define KPIM_TRANSPORTJOB_H
#include <mailtransport/mailtransport_export.h>
#include <kcompositejob.h>
#include <QStringList>
class QBuffer;
namespace KPIM {
class Transport;
/**
Abstract base class for all mail transport jobs.
This is a job that is supposed to send exactly one mail.
*/
class MAILTRANSPORT_EXPORT TransportJob : public KCompositeJob
{
public:
/**
Creates a new mail transport job.
@param transport The transport configuration.
@param parent The parent object.
*/
TransportJob( Transport* transport, QObject* parent = 0 );
/**
Sets the sender of the mail.
*/