summaryrefslogtreecommitdiffabout
Side-by-side diff
Diffstat (more/less context) (show whitespace changes)
-rw-r--r--kmicromail/libmailwrapper/smtpwrapper.cpp18
1 files changed, 14 insertions, 4 deletions
diff --git a/kmicromail/libmailwrapper/smtpwrapper.cpp b/kmicromail/libmailwrapper/smtpwrapper.cpp
index 448a2e9..a6c12e4 100644
--- a/kmicromail/libmailwrapper/smtpwrapper.cpp
+++ b/kmicromail/libmailwrapper/smtpwrapper.cpp
@@ -1,490 +1,500 @@
#include "smtpwrapper.h"
#include "mailwrapper.h"
#include "abstractmail.h"
#include "logindialog.h"
#include "mailtypes.h"
#include "sendmailprogress.h"
//#include <opie2/odebug.h>
//#include <qt.h>
#include <qapplication.h>
#include <qmessagebox.h>
#include <stdlib.h>
#ifndef DESKTOP_VERSION
//#include <qpe/config.h>
#include <qpe/qcopenvelope_qws.h>
#endif
#include <libetpan/libetpan.h>
#include <klocale.h>
#include <kglobal.h>
#include <kconfig.h>
using namespace Opie::Core;
progressMailSend*SMTPwrapper::sendProgress = 0;
SMTPwrapper::SMTPwrapper(SMTPaccount * aSmtp )
: Generatemail()
{
m_SmtpAccount = aSmtp;
KConfig cfg( locateLocal("config", "kopiemailrc" ) );
cfg.setGroup( "Status" );
m_queuedMail = cfg.readNumEntry( "outgoing", 0 );
emit queuedMails( m_queuedMail );
connect( this, SIGNAL( queuedMails(int) ), this, SLOT( emitQCop(int) ) );
m_smtp = 0;
}
SMTPwrapper::~SMTPwrapper()
{
disc_server();
}
void SMTPwrapper::emitQCop( int queued ) {
#ifndef DESKTOP_VERSION
// LR : not used in kde-pim
//QCopEnvelope env( "QPE/Pim", "outgoingMails(int)" );
//env << queued;
#endif
}
QString SMTPwrapper::mailsmtpError( int errnum ) {
switch ( errnum ) {
case MAILSMTP_NO_ERROR:
return i18n( "No error" );
case MAILSMTP_ERROR_UNEXPECTED_CODE:
return i18n( "Unexpected error code" );
case MAILSMTP_ERROR_SERVICE_NOT_AVAILABLE:
return i18n( "Service not available" );
case MAILSMTP_ERROR_STREAM:
return i18n( "Stream error" );
case MAILSMTP_ERROR_HOSTNAME:
return i18n( "gethostname() failed" );
case MAILSMTP_ERROR_NOT_IMPLEMENTED:
return i18n( "Not implemented" );
case MAILSMTP_ERROR_ACTION_NOT_TAKEN:
return i18n( "Error, action not taken" );
case MAILSMTP_ERROR_EXCEED_STORAGE_ALLOCATION:
return i18n( "Data exceeds storage allocation" );
case MAILSMTP_ERROR_IN_PROCESSING:
return i18n( "Error in processing" );
case MAILSMTP_ERROR_STARTTLS_NOT_SUPPORTED:
return i18n( "Starttls not supported" );
// case MAILSMTP_ERROR_INSUFFISANT_SYSTEM_STORAGE:
// return i18n( "Insufficient system storage" );
case MAILSMTP_ERROR_MAILBOX_UNAVAILABLE:
return i18n( "Mailbox unavailable" );
case MAILSMTP_ERROR_MAILBOX_NAME_NOT_ALLOWED:
return i18n( "Mailbox name not allowed" );
case MAILSMTP_ERROR_BAD_SEQUENCE_OF_COMMAND:
return i18n( "Bad command sequence" );
case MAILSMTP_ERROR_USER_NOT_LOCAL:
return i18n( "User not local" );
case MAILSMTP_ERROR_TRANSACTION_FAILED:
return i18n( "Transaction failed" );
case MAILSMTP_ERROR_MEMORY:
return i18n( "Memory error" );
case MAILSMTP_ERROR_CONNECTION_REFUSED:
return i18n( "Connection refused" );
default:
return i18n( "Unknown error code" );
}
}
void SMTPwrapper::progress( size_t current, size_t maximum ) {
if (SMTPwrapper::sendProgress) {
SMTPwrapper::sendProgress->setSingleMail(current, maximum );
qApp->processEvents();
}
}
void SMTPwrapper::storeMail(const char*mail, size_t length, const QString&box) {
if (!mail)
return;
QString localfolders = AbstractMail::defaultLocalfolder();
AbstractMail*wrap = AbstractMail::getWrapper(localfolders);
wrap->createMbox(box);
wrap->storeMessage(mail,length,box);
delete wrap;
}
bool SMTPwrapper::smtpSend( mailmime *mail,bool later) {
clist *rcpts = 0;
char *from, *data;
size_t size;
from = data = 0;
mailmessage * msg = 0;
msg = mime_message_init(mail);
mime_message_set_tmpdir(msg,getenv( "HOME" ));
int r = mailmessage_fetch(msg,&data,&size);
mime_message_detach_mime(msg);
mailmessage_free(msg);
if (r != MAIL_NO_ERROR || !data) {
if (data)
free(data);
qDebug("Error fetching mime... ");
return false;
}
msg = 0;
if (later) {
storeMail(data,size,"Outgoing");
if (data)
free( data );
KConfig cfg( locateLocal("config", "kopiemailrc" ) );
cfg.setGroup( "Status" );
cfg.writeEntry( "outgoing", ++m_queuedMail );
emit queuedMails( m_queuedMail );
return true;
}
from = getFrom( mail );
rcpts = createRcptList( mail->mm_data.mm_message.mm_fields );
bool result = smtpSend(from,rcpts,data,size);
if (data) {
free(data);
}
if (from) {
free(from);
}
if (rcpts)
smtp_address_list_free( rcpts );
return result;
}
void SMTPwrapper::storeFailedMail(const char*data,unsigned int size, const char*failuremessage)
{
if (data) {
storeMail(data,size,"Sendfailed");
}
if (failuremessage) {
QMessageBox::critical(0,i18n("Error sending mail"),
failuremessage);
}
}
int SMTPwrapper::start_smtp_tls()
{
if (!m_smtp) {
return MAILSMTP_ERROR_IN_PROCESSING;
}
int err = mailesmtp_starttls(m_smtp);
if (err != MAILSMTP_NO_ERROR) return err;
mailstream_low * low;
mailstream_low * new_low;
low = mailstream_get_low(m_smtp->stream);
if (!low) {
return MAILSMTP_ERROR_IN_PROCESSING;
}
int fd = mailstream_low_get_fd(low);
if (fd > -1 && (new_low = mailstream_low_ssl_open(fd))!=0) {
mailstream_low_free(low);
mailstream_set_low(m_smtp->stream, new_low);
} else {
return MAILSMTP_ERROR_IN_PROCESSING;
}
return err;
}
void SMTPwrapper::connect_server()
{
QString server, user, pass;
bool ssl;
uint16_t port;
ssl = false;
bool try_tls = false;
bool force_tls=false;
QString failuretext = "";
if (m_smtp || !m_SmtpAccount) {
return;
}
server = m_SmtpAccount->getServer();
if ( m_SmtpAccount->ConnectionType() == 3 ) {
ssl = true;
try_tls = false;
} else if (m_SmtpAccount->ConnectionType() == 2) {
force_tls = true;
try_tls = true;
} else if (m_SmtpAccount->ConnectionType() == 1) {
try_tls = true;
}
int result = 1;
port = m_SmtpAccount->getPort().toUInt();
m_smtp = mailsmtp_new( 20, &progress );
if ( m_smtp == NULL ) {
/* no failure message cause this happens when problems with memory - than we
we can not display any messagebox */
return;
}
+ //m_smtp->auth = MAILSMTP_AUTH_LOGIN;
int err = MAILSMTP_NO_ERROR;
; // odebug << "Servername " << server << " at port " << port << "" << oendl;
if ( ssl ) {
qDebug("smtp: ssl_connect ");
err = mailsmtp_ssl_connect( m_smtp, server.latin1(), port );
} else {
; // odebug << "No SSL session" << oendl;
err = mailsmtp_socket_connect( m_smtp, server.latin1(), port );
}
if ( err != MAILSMTP_NO_ERROR ) {
qDebug("Error init SMTP connection" );
failuretext = i18n("Error init SMTP connection:\n%1").arg(mailsmtpError(err));
result = 0;
}
qDebug("SMTP connection inited ");
/* switch to tls after init 'cause there it will send the ehlo */
if (result) {
err = mailsmtp_init( m_smtp );
if (err != MAILSMTP_NO_ERROR) {
result = 0;
qDebug("Error init SMTP connection ");
failuretext = i18n("Error init SMTP connection:\n%1").arg(mailsmtpError(err));
}
}
if (result && try_tls) {
qDebug("Smpt: Try TLS... ");
err = start_smtp_tls();
if (err != MAILSMTP_NO_ERROR) {
try_tls = false;
qDebug("Smpt: No TLS possible ");
} else {
- err = mailesmtp_ehlo(m_smtp);
- if ( err != MAILSMTP_NO_ERROR )
- result = 0;
- else
qDebug("Smpt: Using TLS ");
}
}
+
//qDebug("mailesmtp_ehlo %d ",err );
if (!try_tls && force_tls) {
result = 0;
failuretext = i18n("Error init SMTP tls:%1").arg(mailsmtpError(err));
}
+ if ( mailesmtp_ehlo(m_smtp) != MAILSMTP_NO_ERROR ) {
+ qDebug("Smpt: ehlo failed ");
+ result = 0;
+ }
+ else {
+ //qDebug("Smpt: auth is %d -- %d %d",m_smtp->auth, MAILSMTP_AUTH_LOGIN, MAILSMTP_AUTH_PLAIN);
+ if ( m_smtp->auth & MAILSMTP_AUTH_LOGIN && m_smtp->auth & MAILSMTP_AUTH_PLAIN ) {
+ qDebug("Smpt: Using MAILSMTP_AUTH_LOGIN ");
+ m_smtp->auth -= MAILSMTP_AUTH_PLAIN;
+ //qDebug("Smpt: auth is %d -- %d %d",m_smtp->auth, MAILSMTP_AUTH_LOGIN, MAILSMTP_AUTH_PLAIN);
+ }
+ }
if (result==1 && m_SmtpAccount->getLogin() ) {
; // odebug << "smtp with auth" << oendl;
if ( m_SmtpAccount->getUser().isEmpty() || m_SmtpAccount->getPassword().isEmpty() ) {
// get'em
LoginDialog login( m_SmtpAccount->getUser(),
m_SmtpAccount->getPassword(), NULL, 0, true );
login.show();
if ( QDialog::Accepted == login.exec() ) {
// ok
user = login.getUser();
pass = login.getPassword();
} else {
result = 0;
failuretext=i18n("Login aborted - \nstoring mail to localfolder");
}
} else {
user = m_SmtpAccount->getUser();
pass = m_SmtpAccount->getPassword();
}
; // odebug << "session->auth: " << m_smtp->auth << "" << oendl;
if (result) {
err = mailsmtp_auth( m_smtp, (char*)user.latin1(), (char*)pass.latin1() );
if ( err == MAILSMTP_NO_ERROR ) {
qDebug("Smtp authentification ok ");
} else {
failuretext = i18n("Authentification failed");
result = 0;
}
}
}
if ( result == 0 ) {
mailsmtp_free(m_smtp);
m_smtp = 0;
}
}
void SMTPwrapper::disc_server()
{
if (m_smtp) {
mailsmtp_quit( m_smtp );
mailsmtp_free( m_smtp );
m_smtp = 0;
}
}
int SMTPwrapper::smtpSend(char*from,clist*rcpts,const char*data,size_t size )
{
int err,result;
QString failuretext = "";
connect_server();
result = 1;
if (m_smtp) {
err = mailsmtp_send( m_smtp, from, rcpts, data, size );
if ( err != MAILSMTP_NO_ERROR ) {
qDebug("Error sending mail");
failuretext=i18n("Error sending mail:\n%1").arg(mailsmtpError(err));
result = 0;
}
} else {
result = 0;
}
if (!result) {
storeFailedMail(data,size,failuretext);
} else {
; // odebug << "Mail sent." << oendl;
storeMail(data,size,"Sent");
}
return result;
}
bool SMTPwrapper::sendMail(const Opie::Core::OSmartPointer<Mail>&mail,bool later )
{
mailmime * mimeMail;
bool result = true;
mimeMail = createMimeMail(mail );
if ( mimeMail == 0 ) {
qDebug("SMTP wrapper:Error creating mail! ");
return false;
} else {
sendProgress = new progressMailSend();
sendProgress->show();
sendProgress->setMaxMails(1);
result = smtpSend( mimeMail,later);
; // odebug << "Clean up done" << oendl;
sendProgress->hide();
delete sendProgress;
sendProgress = 0;
mailmime_free( mimeMail );
if ( m_smtp ) {
mailsmtp_free(m_smtp);
m_smtp = 0;
}
}
return result;
}
int SMTPwrapper::sendQueuedMail(AbstractMail*wrap,const RecMailP&which) {
size_t curTok = 0;
mailimf_fields *fields = 0;
mailimf_field*ffrom = 0;
clist *rcpts = 0;
char*from = 0;
int res = 0;
encodedString * data = wrap->fetchRawBody(which);
if (!data)
return 0;
int err = mailimf_fields_parse( data->Content(), data->Length(), &curTok, &fields );
if (err != MAILIMF_NO_ERROR) {
delete data;
delete wrap;
return 0;
}
rcpts = createRcptList( fields );
ffrom = getField(fields, MAILIMF_FIELD_FROM );
from = getFrom(ffrom);
if (rcpts && from) {
res = smtpSend(from,rcpts,data->Content(),data->Length());
}
if (fields) {
mailimf_fields_free(fields);
fields = 0;
}
if (data) {
delete data;
}
if (from) {
free(from);
}
if (rcpts) {
smtp_address_list_free( rcpts );
}
return res;
}
/* this is a special fun */
bool SMTPwrapper::flushOutbox() {
bool returnValue = true;
; // odebug << "Sending the queue" << oendl;
if (!m_SmtpAccount) {
; // odebug << "No smtp account given" << oendl;
return false;
}
bool reset_user_value = false;
QString localfolders = AbstractMail::defaultLocalfolder();
AbstractMail*wrap = AbstractMail::getWrapper(localfolders);
if (!wrap) {
; // odebug << "memory error" << oendl;
return false;
}
QString oldPw, oldUser;
QValueList<RecMailP> mailsToSend;
QValueList<RecMailP> mailsToRemove;
QString mbox("Outgoing");
wrap->listMessages(mbox,mailsToSend);
if (mailsToSend.count()==0) {
delete wrap;
; // odebug << "No mails to send" << oendl;
return false;
}
oldPw = m_SmtpAccount->getPassword();
oldUser = m_SmtpAccount->getUser();
if (m_SmtpAccount->getLogin() && (m_SmtpAccount->getUser().isEmpty() || m_SmtpAccount->getPassword().isEmpty()) ) {
// get'em
QString user,pass;
LoginDialog login( m_SmtpAccount->getUser(), m_SmtpAccount->getPassword(), NULL, 0, true );
login.show();
if ( QDialog::Accepted == login.exec() ) {
// ok
user = login.getUser().latin1();
pass = login.getPassword().latin1();
reset_user_value = true;
m_SmtpAccount->setUser(user);
m_SmtpAccount->setPassword(pass);
} else {
return true;
}
}
sendProgress = new progressMailSend();
sendProgress->show();
sendProgress->setMaxMails(mailsToSend.count());
while (returnValue && mailsToSend.count()>0) {
if (sendQueuedMail(wrap, (*mailsToSend.begin()))==0) {
QMessageBox::critical(0,i18n("Error sending mail"),
i18n("Error sending queued mail.\nBreaking."));
returnValue = false;
}
mailsToRemove.append((*mailsToSend.begin()));
mailsToSend.remove(mailsToSend.begin());
sendProgress->setCurrentMails(mailsToRemove.count());
}
if (reset_user_value) {
m_SmtpAccount->setUser(oldUser);
m_SmtpAccount->setPassword(oldPw);
}
KConfig cfg( locateLocal("config", "kopiemailrc" ) );
cfg.setGroup( "Status" );
m_queuedMail = mailsToSend.count();
cfg.writeEntry( "outgoing", m_queuedMail );
emit queuedMails( m_queuedMail );
sendProgress->hide();
delete sendProgress;
sendProgress = 0;
wrap->deleteMails(mbox,mailsToRemove);
delete wrap;
if ( m_smtp ) {
mailsmtp_free(m_smtp);
m_smtp = 0;
}
return returnValue;
}