summaryrefslogtreecommitdiff
Side-by-side diff
Diffstat (more/less context) (ignore whitespace changes)
-rw-r--r--noncore/net/mail/abstractmail.cpp1
-rw-r--r--noncore/net/mail/composemail.cpp3
-rw-r--r--noncore/net/mail/imapwrapper.cpp3
-rw-r--r--noncore/net/mail/imapwrapper.h1
-rw-r--r--noncore/net/mail/libmailwrapper/abstractmail.cpp1
-rw-r--r--noncore/net/mail/libmailwrapper/imapwrapper.cpp3
-rw-r--r--noncore/net/mail/libmailwrapper/imapwrapper.h1
-rw-r--r--noncore/net/mail/libmailwrapper/mailwrapper.cpp585
-rw-r--r--noncore/net/mail/libmailwrapper/mailwrapper.h35
-rw-r--r--noncore/net/mail/libmailwrapper/pop3wrapper.h6
-rw-r--r--noncore/net/mail/libmailwrapper/smtpwrapper.cpp604
-rw-r--r--noncore/net/mail/libmailwrapper/smtpwrapper.h53
-rw-r--r--noncore/net/mail/mail.pro6
-rw-r--r--noncore/net/mail/mailwrapper.cpp585
-rw-r--r--noncore/net/mail/mailwrapper.h35
-rw-r--r--noncore/net/mail/pop3wrapper.h6
-rw-r--r--noncore/net/mail/smtpwrapper.cpp604
-rw-r--r--noncore/net/mail/smtpwrapper.h53
18 files changed, 1340 insertions, 1245 deletions
diff --git a/noncore/net/mail/abstractmail.cpp b/noncore/net/mail/abstractmail.cpp
index 626b9aa..3cb8f7d 100644
--- a/noncore/net/mail/abstractmail.cpp
+++ b/noncore/net/mail/abstractmail.cpp
@@ -1,83 +1,84 @@
#include "abstractmail.h"
#include "imapwrapper.h"
#include "pop3wrapper.h"
#include "mailtypes.h"
#include <qstring.h>
#include <qfile.h>
#include <qtextstream.h>
#include <stdlib.h>
#include <libetpan/mailmime_content.h>
+#include <libetpan/mailmime.h>
AbstractMail* AbstractMail::getWrapper(IMAPaccount *a)
{
return new IMAPwrapper(a);
}
AbstractMail* AbstractMail::getWrapper(POP3account *a)
{
return new POP3wrapper(a);
}
encodedString* AbstractMail::decode_String(const encodedString*text,const QString&enc)
{
qDebug("Decode string start");
char*result_text;
size_t index = 0;
/* reset for recursive use! */
size_t target_length = 0;
result_text = 0;
int mimetype = MAILMIME_MECHANISM_7BIT;
if (enc.lower()=="quoted-printable") {
mimetype = MAILMIME_MECHANISM_QUOTED_PRINTABLE;
} else if (enc.lower()=="base64") {
mimetype = MAILMIME_MECHANISM_BASE64;
} else if (enc.lower()=="8bit") {
mimetype = MAILMIME_MECHANISM_8BIT;
} else if (enc.lower()=="binary") {
mimetype = MAILMIME_MECHANISM_BINARY;
}
int err = mailmime_part_parse(text->Content(),text->Length(),&index,mimetype,
&result_text,&target_length);
encodedString* result = new encodedString();
if (err == MAILIMF_NO_ERROR) {
result->setContent(result_text,target_length);
}
qDebug("Decode string finished");
return result;
}
QString AbstractMail::convert_String(const char*text)
{
size_t index = 0;
char*res = 0;
/* attention - doesn't work with arm systems! */
int err = mailmime_encoded_phrase_parse("iso-8859-1",
text, strlen(text),&index, "iso-8859-1",&res);
if (err != MAILIMF_NO_ERROR) {
if (res) free(res);
return QString(text);
}
if (res) {
QString result(res);
free(res);
return result;
}
return QString(text);
}
/* cp & paste from launcher */
QString AbstractMail::gen_attachment_id()
{
QFile file( "/proc/sys/kernel/random/uuid" );
if (!file.open(IO_ReadOnly ) )
return QString::null;
QTextStream stream(&file);
return "{" + stream.read().stripWhiteSpace() + "}";
}
diff --git a/noncore/net/mail/composemail.cpp b/noncore/net/mail/composemail.cpp
index cfccdbb..048fa85 100644
--- a/noncore/net/mail/composemail.cpp
+++ b/noncore/net/mail/composemail.cpp
@@ -1,202 +1,203 @@
#include <qt.h>
#include <opie/ofiledialog.h>
#include <qpe/resource.h>
#include "composemail.h"
+#include "smtpwrapper.h"
ComposeMail::ComposeMail( Settings *s, QWidget *parent, const char *name, bool modal, WFlags flags )
: ComposeMailUI( parent, name, modal, flags )
{
settings = s;
attList->addColumn( tr( "Name" ) );
attList->addColumn( tr( "Size" ) );
QList<Account> accounts = settings->getAccounts();
Account *it;
for ( it = accounts.first(); it; it = accounts.next() ) {
if ( it->getType().compare( "SMTP" ) == 0 ) {
SMTPaccount *smtp = static_cast<SMTPaccount *>(it);
fromBox->insertItem( smtp->getMail() );
smtpAccounts.append( smtp );
}
}
if ( smtpAccounts.count() > 0 ) {
fillValues( fromBox->currentItem() );
} else {
QMessageBox::information( this, tr( "Problem" ),
tr( "<p>Please create an SMTP account first.</p>" ),
tr( "Ok" ) );
}
connect( fromBox, SIGNAL( activated( int ) ), SLOT( fillValues( int ) ) );
connect( toButton, SIGNAL( clicked() ), SLOT( pickAddressTo() ) );
connect( ccButton, SIGNAL( clicked() ), SLOT( pickAddressCC() ) );
connect( bccButton, SIGNAL( clicked() ), SLOT( pickAddressBCC() ) );
connect( replyButton, SIGNAL( clicked() ), SLOT( pickAddressReply() ) );
connect( addButton, SIGNAL( clicked() ), SLOT( addAttachment() ) );
connect( deleteButton, SIGNAL( clicked() ), SLOT( removeAttachment() ) );
}
void ComposeMail::pickAddress( QLineEdit *line )
{
QString names = AddressPicker::getNames();
if ( line->text().isEmpty() ) {
line->setText( names );
} else if ( !names.isEmpty() ) {
line->setText( line->text() + ", " + names );
}
}
void ComposeMail::setTo( const QString & to )
{
/* QString toline;
QStringList toEntry = to;
for ( QStringList::Iterator it = toEntry.begin(); it != toEntry.end(); ++it ) {
toline += (*it);
}
toLine->setText( toline );
*/
toLine->setText( to );
}
void ComposeMail::setSubject( const QString & subject )
{
subjectLine->setText( subject );
}
void ComposeMail::setInReplyTo( const QString & messageId )
{
}
void ComposeMail::setMessage( const QString & text )
{
message->setText( text );
}
void ComposeMail::pickAddressTo()
{
pickAddress( toLine );
}
void ComposeMail::pickAddressCC()
{
pickAddress( ccLine );
}
void ComposeMail::pickAddressBCC()
{
pickAddress( bccLine );
}
void ComposeMail::pickAddressReply()
{
pickAddress( replyLine );
}
void ComposeMail::fillValues( int current )
{
SMTPaccount *smtp = smtpAccounts.at( current );
ccLine->clear();
if ( smtp->getUseCC() ) {
ccLine->setText( smtp->getCC() );
}
bccLine->clear();
if ( smtp->getUseBCC() ) {
bccLine->setText( smtp->getBCC() );
}
replyLine->clear();
if ( smtp->getUseReply() ) {
replyLine->setText( smtp->getReply() );
}
sigMultiLine->setText( smtp->getSignature() );
}
void ComposeMail::slotAdjustColumns()
{
int currPage = tabWidget->currentPageIndex();
tabWidget->showPage( attachTab );
attList->setColumnWidth( 0, attList->visibleWidth() - 80 );
attList->setColumnWidth( 1, 80 );
tabWidget->setCurrentPage( currPage );
}
void ComposeMail::addAttachment()
{
DocLnk lnk = OFileDialog::getOpenFileName( 1, "/" );
if ( !lnk.name().isEmpty() ) {
Attachment *att = new Attachment( lnk );
(void) new AttachViewItem( attList, att );
}
}
void ComposeMail::removeAttachment()
{
if ( !attList->currentItem() ) {
QMessageBox::information( this, tr( "Error" ),
tr( "<p>Please select a File.</p>" ),
tr( "Ok" ) );
} else {
attList->takeItem( attList->currentItem() );
}
}
void ComposeMail::accept()
{
qDebug( "Sending Mail with " +
smtpAccounts.at( fromBox->currentItem() )->getAccountName() );
Mail *mail = new Mail();
SMTPaccount *smtp = smtpAccounts.at( fromBox->currentItem() );
mail->setMail( smtp->getMail() );
mail->setName( smtp->getName() );
if ( !toLine->text().isEmpty() ) {
mail->setTo( toLine->text() );
} else {
qDebug( "No Reciever spezified -> returning" );
return;
}
mail->setCC( ccLine->text() );
mail->setBCC( bccLine->text() );
mail->setReply( replyLine->text() );
mail->setSubject( subjectLine->text() );
QString txt = message->text();
if ( !sigMultiLine->text().isEmpty() ) {
txt.append( "\n--\n" );
txt.append( sigMultiLine->text() );
}
mail->setMessage( txt );
AttachViewItem *it = (AttachViewItem *) attList->firstChild();
while ( it != NULL ) {
mail->addAttachment( it->getAttachment() );
it = (AttachViewItem *) it->itemBelow();
}
- MailWrapper wrapper( settings );
+ SMTPwrapper wrapper( settings );
wrapper.sendMail( *mail );
QDialog::accept();
}
AttachViewItem::AttachViewItem( QListView *parent, Attachment *att )
: QListViewItem( parent )
{
attachment = att;
qDebug( att->getMimeType() );
setPixmap( 0, attachment->getDocLnk().pixmap().isNull() ?
Resource::loadPixmap( "UnknownDocument-14" ) :
attachment->getDocLnk().pixmap() );
setText( 0, att->getName().isEmpty() ? att->getFileName() : att->getName() );
setText( 1, QString::number( att->getSize() ) );
}
diff --git a/noncore/net/mail/imapwrapper.cpp b/noncore/net/mail/imapwrapper.cpp
index cce3d34..30eb678 100644
--- a/noncore/net/mail/imapwrapper.cpp
+++ b/noncore/net/mail/imapwrapper.cpp
@@ -1,263 +1,264 @@
#include <stdlib.h>
+#include <libetpan/mailimap.h>
+
#include "imapwrapper.h"
#include "mailtypes.h"
#include "logindialog.h"
-#include <libetpan/mailimap.h>
IMAPwrapper::IMAPwrapper( IMAPaccount *a )
: AbstractMail()
{
account = a;
m_imap = 0;
}
IMAPwrapper::~IMAPwrapper()
{
logout();
}
void IMAPwrapper::imap_progress( size_t current, size_t maximum )
{
qDebug( "IMAP: %i of %i", current, maximum );
}
void IMAPwrapper::login()
{
const char *server, *user, *pass;
uint16_t port;
int err = MAILIMAP_NO_ERROR;
/* we are connected this moment */
/* TODO: setup a timer holding the line or if connection closed - delete the value */
if (m_imap) {
mailstream_flush(m_imap->imap_stream);
return;
}
server = account->getServer().latin1();
port = account->getPort().toUInt();
if ( account->getUser().isEmpty() || account->getPassword().isEmpty() ) {
LoginDialog login( account->getUser(), account->getPassword(), NULL, 0, true );
login.show();
if ( QDialog::Accepted == login.exec() ) {
// ok
user = strdup( login.getUser().latin1() );
pass = strdup( login.getPassword().latin1() );
} else {
// cancel
qDebug( "IMAP: Login canceled" );
return;
}
} else {
user = account->getUser().latin1();
pass = account->getPassword().latin1();
}
m_imap = mailimap_new( 20, &imap_progress );
/* connect */
if (account->getSSL()) {
err = mailimap_ssl_connect( m_imap, (char*)server, port );
} else {
err = mailimap_socket_connect( m_imap, (char*)server, port );
}
if ( err != MAILIMAP_NO_ERROR &&
err != MAILIMAP_NO_ERROR_AUTHENTICATED &&
err != MAILIMAP_NO_ERROR_NON_AUTHENTICATED ) {
qDebug("error connecting server: %s",m_imap->imap_response);
mailimap_free( m_imap );
m_imap = 0;
return;
}
/* login */
err = mailimap_login_simple( m_imap, (char*)user, (char*)pass );
if ( err != MAILIMAP_NO_ERROR ) {
qDebug("error logging in imap: %s",m_imap->imap_response);
err = mailimap_close( m_imap );
mailimap_free( m_imap );
m_imap = 0;
}
}
void IMAPwrapper::logout()
{
int err = MAILIMAP_NO_ERROR;
if (!m_imap) return;
err = mailimap_logout( m_imap );
err = mailimap_close( m_imap );
mailimap_free( m_imap );
m_imap = 0;
}
void IMAPwrapper::listMessages(const QString&mailbox,QList<RecMail> &target )
{
const char *mb;
int err = MAILIMAP_NO_ERROR;
clist *result;
clistcell *current;
// mailimap_fetch_att *fetchAtt,*fetchAttFlags,*fetchAttDate,*fetchAttSize;
mailimap_fetch_type *fetchType;
mailimap_set *set;
mb = mailbox.latin1();
login();
if (!m_imap) {
return;
}
/* select mailbox READONLY for operations */
err = mailimap_examine( m_imap, (char*)mb);
if ( err != MAILIMAP_NO_ERROR ) {
qDebug("error selecting mailbox: %s",m_imap->imap_response);
return;
}
int last = m_imap->imap_selection_info->sel_exists;
if (last == 0) {
qDebug("mailbox has no mails");
return;
}
result = clist_new();
/* the range has to start at 1!!! not with 0!!!! */
set = mailimap_set_new_interval( 1, last );
fetchType = mailimap_fetch_type_new_fetch_att_list_empty();
mailimap_fetch_type_new_fetch_att_list_add(fetchType,mailimap_fetch_att_new_envelope());
mailimap_fetch_type_new_fetch_att_list_add(fetchType,mailimap_fetch_att_new_flags());
mailimap_fetch_type_new_fetch_att_list_add(fetchType,mailimap_fetch_att_new_internaldate());
mailimap_fetch_type_new_fetch_att_list_add(fetchType,mailimap_fetch_att_new_rfc822_size());
err = mailimap_fetch( m_imap, set, fetchType, &result );
mailimap_set_free( set );
mailimap_fetch_type_free( fetchType );
QString date,subject,from;
if ( err == MAILIMAP_NO_ERROR ) {
mailimap_msg_att * msg_att;
int i = 0;
for (current = clist_begin(result); current != 0; current=clist_next(current)) {
++i;
msg_att = (mailimap_msg_att*)current->data;
RecMail*m = parse_list_result(msg_att);
if (m) {
m->setNumber(i);
m->setMbox(mailbox);
m->setWrapper(this);
target.append(m);
}
}
} else {
qDebug("Error fetching headers: %s",m_imap->imap_response);
}
mailimap_fetch_list_free(result);
}
QList<Folder>* IMAPwrapper::listFolders()
{
const char *path, *mask;
int err = MAILIMAP_NO_ERROR;
clist *result;
clistcell *current;
QList<Folder> * folders = new QList<Folder>();
folders->setAutoDelete( false );
login();
if (!m_imap) {
return folders;
}
/*
* First we have to check for INBOX 'cause it sometimes it's not inside the path.
* We must not forget to filter them out in next loop!
* it seems like ugly code. and yes - it is ugly code. but the best way.
*/
QString temp;
mask = "INBOX" ;
result = clist_new();
mailimap_mailbox_list *list;
err = mailimap_list( m_imap, (char*)"", (char*)mask, &result );
QString del;
if ( err == MAILIMAP_NO_ERROR ) {
current = result->first;
for ( int i = result->count; i > 0; i-- ) {
list = (mailimap_mailbox_list *) current->data;
// it is better use the deep copy mechanism of qt itself
// instead of using strdup!
temp = list->mb_name;
del = list->mb_delimiter;
folders->append( new IMAPFolder(temp,del,true,account->getPrefix()));
current = current->next;
}
} else {
qDebug("error fetching folders: %s",m_imap->imap_response);
}
mailimap_list_result_free( result );
/*
* second stage - get the other then inbox folders
*/
mask = "*" ;
path = account->getPrefix().latin1();
if (!path) path = "";
result = clist_new();
qDebug(path);
bool selectable = true;
mailimap_mbx_list_flags*bflags;
err = mailimap_list( m_imap, (char*)path, (char*)mask, &result );
if ( err == MAILIMAP_NO_ERROR ) {
current = result->first;
for ( current=clist_begin(result);current!=NULL;current=clist_next(current)) {
list = (mailimap_mailbox_list *) current->data;
// it is better use the deep copy mechanism of qt itself
// instead of using strdup!
temp = list->mb_name;
if (temp.lower()=="inbox")
continue;
if (temp.lower()==account->getPrefix().lower())
continue;
if ( (bflags = list->mb_flag) ) {
selectable = !(bflags->mbf_type==MAILIMAP_MBX_LIST_FLAGS_SFLAG&&
bflags->mbf_sflag==MAILIMAP_MBX_LIST_SFLAG_NOSELECT);
}
del = list->mb_delimiter;
folders->append(new IMAPFolder(temp,del,selectable,account->getPrefix()));
}
} else {
qDebug("error fetching folders %s",m_imap->imap_response);
}
mailimap_list_result_free( result );
return folders;
}
RecMail*IMAPwrapper::parse_list_result(mailimap_msg_att* m_att)
{
RecMail * m = 0;
mailimap_msg_att_item *item=0;
clistcell *current,*c,*cf;
mailimap_msg_att_dynamic*flist;
mailimap_flag_fetch*cflag;
int size;
QBitArray mFlags(7);
QStringList addresslist;
if (!m_att) {
return m;
}
m = new RecMail();
for (c = clist_begin(m_att->att_list); c!=NULL;c=clist_next(c) ) {
current = c;
size = 0;
item = (mailimap_msg_att_item*)current->data;
if (item->att_type!=MAILIMAP_MSG_ATT_ITEM_STATIC) {
flist = (mailimap_msg_att_dynamic*)item->att_data.att_dyn;
if (!flist->att_list) {
continue;
}
cf = flist->att_list->first;
for (cf = clist_begin(flist->att_list); cf!=NULL; cf = clist_next(cf)) {
cflag = (mailimap_flag_fetch*)cf->data;
if (cflag->fl_type==MAILIMAP_FLAG_FETCH_OTHER && cflag->fl_flag!=0) {
diff --git a/noncore/net/mail/imapwrapper.h b/noncore/net/mail/imapwrapper.h
index aeebda8..f046297 100644
--- a/noncore/net/mail/imapwrapper.h
+++ b/noncore/net/mail/imapwrapper.h
@@ -1,62 +1,63 @@
#ifndef __IMAPWRAPPER
#define __IMAPWRAPPER
#include <qlist.h>
#include "mailwrapper.h"
#include "abstractmail.h"
+#include <libetpan/clist.h>
struct mailimap;
struct mailimap_body_type_1part;
struct mailimap_body_type_text;
struct mailimap_body_type_basic;
struct mailimap_body_type_msg;
struct mailimap_body_type_mpart;
struct mailimap_body_fields;
struct mailimap_msg_att;
class encodedString;
class IMAPwrapper : public AbstractMail
{
Q_OBJECT
public:
IMAPwrapper( IMAPaccount *a );
virtual ~IMAPwrapper();
virtual QList<Folder>* listFolders();
virtual void listMessages(const QString & mailbox,QList<RecMail>&target );
virtual void deleteMail(const RecMail&mail);
virtual void answeredMail(const RecMail&mail);
virtual RecBody fetchBody(const RecMail&mail);
virtual QString fetchTextPart(const RecMail&mail,const RecPart&part);
virtual encodedString* fetchDecodedPart(const RecMail&mail,const RecPart&part);
virtual encodedString* fetchRawPart(const RecMail&mail,const RecPart&part);
static void imap_progress( size_t current, size_t maximum );
protected:
RecMail*parse_list_result(mailimap_msg_att*);
void login();
void logout();
virtual QString fetchTextPart(const RecMail&mail,const QValueList<int>&path,bool internal_call=false,const QString&enc="");
virtual encodedString*fetchRawPart(const RecMail&mail,const QValueList<int>&path,bool internal_call);
void searchBodyText(const RecMail&mail,mailimap_body_type_1part*mailDescription,RecBody&target_body);
void searchBodyText(const RecMail&mail,mailimap_body_type_mpart*mailDescription,RecBody&target_body,int current_recursion=0,QValueList<int>recList=QValueList<int>());
void fillSinglePart(RecPart&target_part,mailimap_body_type_1part*Description);
void fillSingleTextPart(RecPart&target_part,mailimap_body_type_text*which);
void fillSingleBasicPart(RecPart&target_part,mailimap_body_type_basic*which);
void fillSingleMsgPart(RecPart&target_part,mailimap_body_type_msg*which);
/* just helpers */
static void fillBodyFields(RecPart&target_part,mailimap_body_fields*which);
static QStringList address_list_to_stringlist(clist*list);
IMAPaccount *account;
mailimap *m_imap;
};
#endif
diff --git a/noncore/net/mail/libmailwrapper/abstractmail.cpp b/noncore/net/mail/libmailwrapper/abstractmail.cpp
index 626b9aa..3cb8f7d 100644
--- a/noncore/net/mail/libmailwrapper/abstractmail.cpp
+++ b/noncore/net/mail/libmailwrapper/abstractmail.cpp
@@ -1,83 +1,84 @@
#include "abstractmail.h"
#include "imapwrapper.h"
#include "pop3wrapper.h"
#include "mailtypes.h"
#include <qstring.h>
#include <qfile.h>
#include <qtextstream.h>
#include <stdlib.h>
#include <libetpan/mailmime_content.h>
+#include <libetpan/mailmime.h>
AbstractMail* AbstractMail::getWrapper(IMAPaccount *a)
{
return new IMAPwrapper(a);
}
AbstractMail* AbstractMail::getWrapper(POP3account *a)
{
return new POP3wrapper(a);
}
encodedString* AbstractMail::decode_String(const encodedString*text,const QString&enc)
{
qDebug("Decode string start");
char*result_text;
size_t index = 0;
/* reset for recursive use! */
size_t target_length = 0;
result_text = 0;
int mimetype = MAILMIME_MECHANISM_7BIT;
if (enc.lower()=="quoted-printable") {
mimetype = MAILMIME_MECHANISM_QUOTED_PRINTABLE;
} else if (enc.lower()=="base64") {
mimetype = MAILMIME_MECHANISM_BASE64;
} else if (enc.lower()=="8bit") {
mimetype = MAILMIME_MECHANISM_8BIT;
} else if (enc.lower()=="binary") {
mimetype = MAILMIME_MECHANISM_BINARY;
}
int err = mailmime_part_parse(text->Content(),text->Length(),&index,mimetype,
&result_text,&target_length);
encodedString* result = new encodedString();
if (err == MAILIMF_NO_ERROR) {
result->setContent(result_text,target_length);
}
qDebug("Decode string finished");
return result;
}
QString AbstractMail::convert_String(const char*text)
{
size_t index = 0;
char*res = 0;
/* attention - doesn't work with arm systems! */
int err = mailmime_encoded_phrase_parse("iso-8859-1",
text, strlen(text),&index, "iso-8859-1",&res);
if (err != MAILIMF_NO_ERROR) {
if (res) free(res);
return QString(text);
}
if (res) {
QString result(res);
free(res);
return result;
}
return QString(text);
}
/* cp & paste from launcher */
QString AbstractMail::gen_attachment_id()
{
QFile file( "/proc/sys/kernel/random/uuid" );
if (!file.open(IO_ReadOnly ) )
return QString::null;
QTextStream stream(&file);
return "{" + stream.read().stripWhiteSpace() + "}";
}
diff --git a/noncore/net/mail/libmailwrapper/imapwrapper.cpp b/noncore/net/mail/libmailwrapper/imapwrapper.cpp
index cce3d34..30eb678 100644
--- a/noncore/net/mail/libmailwrapper/imapwrapper.cpp
+++ b/noncore/net/mail/libmailwrapper/imapwrapper.cpp
@@ -1,263 +1,264 @@
#include <stdlib.h>
+#include <libetpan/mailimap.h>
+
#include "imapwrapper.h"
#include "mailtypes.h"
#include "logindialog.h"
-#include <libetpan/mailimap.h>
IMAPwrapper::IMAPwrapper( IMAPaccount *a )
: AbstractMail()
{
account = a;
m_imap = 0;
}
IMAPwrapper::~IMAPwrapper()
{
logout();
}
void IMAPwrapper::imap_progress( size_t current, size_t maximum )
{
qDebug( "IMAP: %i of %i", current, maximum );
}
void IMAPwrapper::login()
{
const char *server, *user, *pass;
uint16_t port;
int err = MAILIMAP_NO_ERROR;
/* we are connected this moment */
/* TODO: setup a timer holding the line or if connection closed - delete the value */
if (m_imap) {
mailstream_flush(m_imap->imap_stream);
return;
}
server = account->getServer().latin1();
port = account->getPort().toUInt();
if ( account->getUser().isEmpty() || account->getPassword().isEmpty() ) {
LoginDialog login( account->getUser(), account->getPassword(), NULL, 0, true );
login.show();
if ( QDialog::Accepted == login.exec() ) {
// ok
user = strdup( login.getUser().latin1() );
pass = strdup( login.getPassword().latin1() );
} else {
// cancel
qDebug( "IMAP: Login canceled" );
return;
}
} else {
user = account->getUser().latin1();
pass = account->getPassword().latin1();
}
m_imap = mailimap_new( 20, &imap_progress );
/* connect */
if (account->getSSL()) {
err = mailimap_ssl_connect( m_imap, (char*)server, port );
} else {
err = mailimap_socket_connect( m_imap, (char*)server, port );
}
if ( err != MAILIMAP_NO_ERROR &&
err != MAILIMAP_NO_ERROR_AUTHENTICATED &&
err != MAILIMAP_NO_ERROR_NON_AUTHENTICATED ) {
qDebug("error connecting server: %s",m_imap->imap_response);
mailimap_free( m_imap );
m_imap = 0;
return;
}
/* login */
err = mailimap_login_simple( m_imap, (char*)user, (char*)pass );
if ( err != MAILIMAP_NO_ERROR ) {
qDebug("error logging in imap: %s",m_imap->imap_response);
err = mailimap_close( m_imap );
mailimap_free( m_imap );
m_imap = 0;
}
}
void IMAPwrapper::logout()
{
int err = MAILIMAP_NO_ERROR;
if (!m_imap) return;
err = mailimap_logout( m_imap );
err = mailimap_close( m_imap );
mailimap_free( m_imap );
m_imap = 0;
}
void IMAPwrapper::listMessages(const QString&mailbox,QList<RecMail> &target )
{
const char *mb;
int err = MAILIMAP_NO_ERROR;
clist *result;
clistcell *current;
// mailimap_fetch_att *fetchAtt,*fetchAttFlags,*fetchAttDate,*fetchAttSize;
mailimap_fetch_type *fetchType;
mailimap_set *set;
mb = mailbox.latin1();
login();
if (!m_imap) {
return;
}
/* select mailbox READONLY for operations */
err = mailimap_examine( m_imap, (char*)mb);
if ( err != MAILIMAP_NO_ERROR ) {
qDebug("error selecting mailbox: %s",m_imap->imap_response);
return;
}
int last = m_imap->imap_selection_info->sel_exists;
if (last == 0) {
qDebug("mailbox has no mails");
return;
}
result = clist_new();
/* the range has to start at 1!!! not with 0!!!! */
set = mailimap_set_new_interval( 1, last );
fetchType = mailimap_fetch_type_new_fetch_att_list_empty();
mailimap_fetch_type_new_fetch_att_list_add(fetchType,mailimap_fetch_att_new_envelope());
mailimap_fetch_type_new_fetch_att_list_add(fetchType,mailimap_fetch_att_new_flags());
mailimap_fetch_type_new_fetch_att_list_add(fetchType,mailimap_fetch_att_new_internaldate());
mailimap_fetch_type_new_fetch_att_list_add(fetchType,mailimap_fetch_att_new_rfc822_size());
err = mailimap_fetch( m_imap, set, fetchType, &result );
mailimap_set_free( set );
mailimap_fetch_type_free( fetchType );
QString date,subject,from;
if ( err == MAILIMAP_NO_ERROR ) {
mailimap_msg_att * msg_att;
int i = 0;
for (current = clist_begin(result); current != 0; current=clist_next(current)) {
++i;
msg_att = (mailimap_msg_att*)current->data;
RecMail*m = parse_list_result(msg_att);
if (m) {
m->setNumber(i);
m->setMbox(mailbox);
m->setWrapper(this);
target.append(m);
}
}
} else {
qDebug("Error fetching headers: %s",m_imap->imap_response);
}
mailimap_fetch_list_free(result);
}
QList<Folder>* IMAPwrapper::listFolders()
{
const char *path, *mask;
int err = MAILIMAP_NO_ERROR;
clist *result;
clistcell *current;
QList<Folder> * folders = new QList<Folder>();
folders->setAutoDelete( false );
login();
if (!m_imap) {
return folders;
}
/*
* First we have to check for INBOX 'cause it sometimes it's not inside the path.
* We must not forget to filter them out in next loop!
* it seems like ugly code. and yes - it is ugly code. but the best way.
*/
QString temp;
mask = "INBOX" ;
result = clist_new();
mailimap_mailbox_list *list;
err = mailimap_list( m_imap, (char*)"", (char*)mask, &result );
QString del;
if ( err == MAILIMAP_NO_ERROR ) {
current = result->first;
for ( int i = result->count; i > 0; i-- ) {
list = (mailimap_mailbox_list *) current->data;
// it is better use the deep copy mechanism of qt itself
// instead of using strdup!
temp = list->mb_name;
del = list->mb_delimiter;
folders->append( new IMAPFolder(temp,del,true,account->getPrefix()));
current = current->next;
}
} else {
qDebug("error fetching folders: %s",m_imap->imap_response);
}
mailimap_list_result_free( result );
/*
* second stage - get the other then inbox folders
*/
mask = "*" ;
path = account->getPrefix().latin1();
if (!path) path = "";
result = clist_new();
qDebug(path);
bool selectable = true;
mailimap_mbx_list_flags*bflags;
err = mailimap_list( m_imap, (char*)path, (char*)mask, &result );
if ( err == MAILIMAP_NO_ERROR ) {
current = result->first;
for ( current=clist_begin(result);current!=NULL;current=clist_next(current)) {
list = (mailimap_mailbox_list *) current->data;
// it is better use the deep copy mechanism of qt itself
// instead of using strdup!
temp = list->mb_name;
if (temp.lower()=="inbox")
continue;
if (temp.lower()==account->getPrefix().lower())
continue;
if ( (bflags = list->mb_flag) ) {
selectable = !(bflags->mbf_type==MAILIMAP_MBX_LIST_FLAGS_SFLAG&&
bflags->mbf_sflag==MAILIMAP_MBX_LIST_SFLAG_NOSELECT);
}
del = list->mb_delimiter;
folders->append(new IMAPFolder(temp,del,selectable,account->getPrefix()));
}
} else {
qDebug("error fetching folders %s",m_imap->imap_response);
}
mailimap_list_result_free( result );
return folders;
}
RecMail*IMAPwrapper::parse_list_result(mailimap_msg_att* m_att)
{
RecMail * m = 0;
mailimap_msg_att_item *item=0;
clistcell *current,*c,*cf;
mailimap_msg_att_dynamic*flist;
mailimap_flag_fetch*cflag;
int size;
QBitArray mFlags(7);
QStringList addresslist;
if (!m_att) {
return m;
}
m = new RecMail();
for (c = clist_begin(m_att->att_list); c!=NULL;c=clist_next(c) ) {
current = c;
size = 0;
item = (mailimap_msg_att_item*)current->data;
if (item->att_type!=MAILIMAP_MSG_ATT_ITEM_STATIC) {
flist = (mailimap_msg_att_dynamic*)item->att_data.att_dyn;
if (!flist->att_list) {
continue;
}
cf = flist->att_list->first;
for (cf = clist_begin(flist->att_list); cf!=NULL; cf = clist_next(cf)) {
cflag = (mailimap_flag_fetch*)cf->data;
if (cflag->fl_type==MAILIMAP_FLAG_FETCH_OTHER && cflag->fl_flag!=0) {
diff --git a/noncore/net/mail/libmailwrapper/imapwrapper.h b/noncore/net/mail/libmailwrapper/imapwrapper.h
index aeebda8..f046297 100644
--- a/noncore/net/mail/libmailwrapper/imapwrapper.h
+++ b/noncore/net/mail/libmailwrapper/imapwrapper.h
@@ -1,62 +1,63 @@
#ifndef __IMAPWRAPPER
#define __IMAPWRAPPER
#include <qlist.h>
#include "mailwrapper.h"
#include "abstractmail.h"
+#include <libetpan/clist.h>
struct mailimap;
struct mailimap_body_type_1part;
struct mailimap_body_type_text;
struct mailimap_body_type_basic;
struct mailimap_body_type_msg;
struct mailimap_body_type_mpart;
struct mailimap_body_fields;
struct mailimap_msg_att;
class encodedString;
class IMAPwrapper : public AbstractMail
{
Q_OBJECT
public:
IMAPwrapper( IMAPaccount *a );
virtual ~IMAPwrapper();
virtual QList<Folder>* listFolders();
virtual void listMessages(const QString & mailbox,QList<RecMail>&target );
virtual void deleteMail(const RecMail&mail);
virtual void answeredMail(const RecMail&mail);
virtual RecBody fetchBody(const RecMail&mail);
virtual QString fetchTextPart(const RecMail&mail,const RecPart&part);
virtual encodedString* fetchDecodedPart(const RecMail&mail,const RecPart&part);
virtual encodedString* fetchRawPart(const RecMail&mail,const RecPart&part);
static void imap_progress( size_t current, size_t maximum );
protected:
RecMail*parse_list_result(mailimap_msg_att*);
void login();
void logout();
virtual QString fetchTextPart(const RecMail&mail,const QValueList<int>&path,bool internal_call=false,const QString&enc="");
virtual encodedString*fetchRawPart(const RecMail&mail,const QValueList<int>&path,bool internal_call);
void searchBodyText(const RecMail&mail,mailimap_body_type_1part*mailDescription,RecBody&target_body);
void searchBodyText(const RecMail&mail,mailimap_body_type_mpart*mailDescription,RecBody&target_body,int current_recursion=0,QValueList<int>recList=QValueList<int>());
void fillSinglePart(RecPart&target_part,mailimap_body_type_1part*Description);
void fillSingleTextPart(RecPart&target_part,mailimap_body_type_text*which);
void fillSingleBasicPart(RecPart&target_part,mailimap_body_type_basic*which);
void fillSingleMsgPart(RecPart&target_part,mailimap_body_type_msg*which);
/* just helpers */
static void fillBodyFields(RecPart&target_part,mailimap_body_fields*which);
static QStringList address_list_to_stringlist(clist*list);
IMAPaccount *account;
mailimap *m_imap;
};
#endif
diff --git a/noncore/net/mail/libmailwrapper/mailwrapper.cpp b/noncore/net/mail/libmailwrapper/mailwrapper.cpp
index 75c06f9..c5d4265 100644
--- a/noncore/net/mail/libmailwrapper/mailwrapper.cpp
+++ b/noncore/net/mail/libmailwrapper/mailwrapper.cpp
@@ -1,723 +1,138 @@
#include <stdlib.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>
#include <fcntl.h>
#include <string.h>
#include <qdir.h>
#include "mailwrapper.h"
#include "logindialog.h"
//#include "mail.h"
#include "defines.h"
Attachment::Attachment( DocLnk lnk )
{
doc = lnk;
size = QFileInfo( doc.file() ).size();
}
Folder::Folder(const QString&tmp_name, const QString&sep )
{
name = tmp_name;
nameDisplay = name;
separator = sep;
}
const QString& Folder::Separator()const
{
return separator;
}
IMAPFolder::IMAPFolder(const QString&name,const QString&sep, bool select,const QString&prefix )
: Folder( name,sep ),m_MaySelect(select)
{
// Decode IMAP foldername
nameDisplay = IMAPFolder::decodeFolderName( name );
qDebug( "folder " + name + " - displayed as " + nameDisplay );
if (prefix.length()>0) {
if (nameDisplay.startsWith(prefix) && nameDisplay.length()>prefix.length()) {
nameDisplay=nameDisplay.right(nameDisplay.length()-prefix.length());
}
}
}
static unsigned char base64chars[] =
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+,";
/**
* Decodes base64 encoded parts of the imapfolder name
* Code taken from kde cvs: kdebase/kioslave/imap4/rfcdecoder.cc
*/
QString IMAPFolder::decodeFolderName( const QString &name )
{
unsigned char c, i, bitcount;
unsigned long ucs4, utf16, bitbuf;
unsigned char base64[256], utf8[6];
unsigned long srcPtr = 0;
QCString dst;
QCString src = name.ascii();
/* initialize modified base64 decoding table */
memset(base64, UNDEFINED, sizeof(base64));
for (i = 0; i < sizeof(base64chars); ++i) {
base64[(int)base64chars[i]] = i;
}
/* loop until end of string */
while (srcPtr < src.length ()) {
c = src[srcPtr++];
/* deal with literal characters and &- */
if (c != '&' || src[srcPtr] == '-') {
/* encode literally */
dst += c;
/* skip over the '-' if this is an &- sequence */
if (c == '&')
srcPtr++;
} else {
/* convert modified UTF-7 -> UTF-16 -> UCS-4 -> UTF-8 -> HEX */
bitbuf = 0;
bitcount = 0;
ucs4 = 0;
while ((c = base64[(unsigned char) src[srcPtr]]) != UNDEFINED) {
++srcPtr;
bitbuf = (bitbuf << 6) | c;
bitcount += 6;
/* enough bits for a UTF-16 character? */
if (bitcount >= 16) {
bitcount -= 16;
utf16 = (bitcount ? bitbuf >> bitcount : bitbuf) & 0xffff;
/* convert UTF16 to UCS4 */
if (utf16 >= UTF16HIGHSTART && utf16 <= UTF16HIGHEND) {
ucs4 = (utf16 - UTF16HIGHSTART) << UTF16SHIFT;
continue;
} else if (utf16 >= UTF16LOSTART && utf16 <= UTF16LOEND) {
ucs4 += utf16 - UTF16LOSTART + UTF16BASE;
} else {
ucs4 = utf16;
}
/* convert UTF-16 range of UCS4 to UTF-8 */
if (ucs4 <= 0x7fUL) {
utf8[0] = ucs4;
i = 1;
} else if (ucs4 <= 0x7ffUL) {
utf8[0] = 0xc0 | (ucs4 >> 6);
utf8[1] = 0x80 | (ucs4 & 0x3f);
i = 2;
} else if (ucs4 <= 0xffffUL) {
utf8[0] = 0xe0 | (ucs4 >> 12);
utf8[1] = 0x80 | ((ucs4 >> 6) & 0x3f);
utf8[2] = 0x80 | (ucs4 & 0x3f);
i = 3;
} else {
utf8[0] = 0xf0 | (ucs4 >> 18);
utf8[1] = 0x80 | ((ucs4 >> 12) & 0x3f);
utf8[2] = 0x80 | ((ucs4 >> 6) & 0x3f);
utf8[3] = 0x80 | (ucs4 & 0x3f);
i = 4;
}
/* copy it */
for (c = 0; c < i; ++c) {
dst += utf8[c];
}
}
}
/* skip over trailing '-' in modified UTF-7 encoding */
if (src[srcPtr] == '-')
++srcPtr;
}
}
return QString::fromUtf8( dst.data() );
}
-MailWrapper::MailWrapper( Settings *s )
- : QObject()
-{
- settings = s;
-}
-
-QString MailWrapper::mailsmtpError( int errnum )
-{
- switch ( errnum ) {
- case MAILSMTP_NO_ERROR:
- return tr( "No error" );
- case MAILSMTP_ERROR_UNEXPECTED_CODE:
- return tr( "Unexpected error code" );
- case MAILSMTP_ERROR_SERVICE_NOT_AVAILABLE:
- return tr( "Service not available" );
- case MAILSMTP_ERROR_STREAM:
- return tr( "Stream error" );
- case MAILSMTP_ERROR_HOSTNAME:
- return tr( "gethostname() failed" );
- case MAILSMTP_ERROR_NOT_IMPLEMENTED:
- return tr( "Not implemented" );
- case MAILSMTP_ERROR_ACTION_NOT_TAKEN:
- return tr( "Error, action not taken" );
- case MAILSMTP_ERROR_EXCEED_STORAGE_ALLOCATION:
- return tr( "Data exceeds storage allocation" );
- case MAILSMTP_ERROR_IN_PROCESSING:
- return tr( "Error in processing" );
- // case MAILSMTP_ERROR_INSUFFISANT_SYSTEM_STORAGE:
- // return tr( "Insufficient system storage" );
- case MAILSMTP_ERROR_MAILBOX_UNAVAILABLE:
- return tr( "Mailbox unavailable" );
- case MAILSMTP_ERROR_MAILBOX_NAME_NOT_ALLOWED:
- return tr( "Mailbox name not allowed" );
- case MAILSMTP_ERROR_BAD_SEQUENCE_OF_COMMAND:
- return tr( "Bad command sequence" );
- case MAILSMTP_ERROR_USER_NOT_LOCAL:
- return tr( "User not local" );
- case MAILSMTP_ERROR_TRANSACTION_FAILED:
- return tr( "Transaction failed" );
- case MAILSMTP_ERROR_MEMORY:
- return tr( "Memory error" );
- case MAILSMTP_ERROR_CONNECTION_REFUSED:
- return tr( "Connection refused" );
- default:
- return tr( "Unknown error code" );
- }
-}
-
-mailimf_mailbox *MailWrapper::newMailbox(const QString&name, const QString&mail )
-{
- return mailimf_mailbox_new( strdup( name.latin1() ),
- strdup( mail.latin1() ) );
-}
-
-mailimf_address_list *MailWrapper::parseAddresses(const QString&addr )
-{
- mailimf_address_list *addresses;
-
- if ( addr.isEmpty() ) return NULL;
-
- addresses = mailimf_address_list_new_empty();
-
- QStringList list = QStringList::split( ',', addr );
- QStringList::Iterator it;
- for ( it = list.begin(); it != list.end(); it++ ) {
- char *str = strdup( (*it).latin1() );
- int err = mailimf_address_list_add_parse( addresses, str );
- if ( err != MAILIMF_NO_ERROR ) {
- qDebug( "Error parsing" );
- qDebug( *it );
- free( str );
- } else {
- qDebug( "Parse success! :)" );
- }
- }
-
- return addresses;
-}
-
-mailimf_fields *MailWrapper::createImfFields( Mail *mail )
-{
- mailimf_fields *fields;
- mailimf_field *xmailer;
- mailimf_mailbox *sender, *fromBox;
- mailimf_mailbox_list *from;
- mailimf_address_list *to, *cc, *bcc, *reply;
- char *subject = strdup( mail->getSubject().latin1() );
- int err;
-
- sender = newMailbox( mail->getName(), mail->getMail() );
- if ( sender == NULL ) goto err_free;
-
- fromBox = newMailbox( mail->getName(), mail->getMail() );
- if ( fromBox == NULL ) goto err_free_sender;
-
- from = mailimf_mailbox_list_new_empty();
- if ( from == NULL ) goto err_free_fromBox;
-
- err = mailimf_mailbox_list_add( from, fromBox );
- if ( err != MAILIMF_NO_ERROR ) goto err_free_from;
-
- to = parseAddresses( mail->getTo() );
- if ( to == NULL ) goto err_free_from;
-
- cc = parseAddresses( mail->getCC() );
- bcc = parseAddresses( mail->getBCC() );
- reply = parseAddresses( mail->getReply() );
-
- fields = mailimf_fields_new_with_data( from, sender, reply, to, cc, bcc,
- NULL, NULL, subject );
- if ( fields == NULL ) goto err_free_reply;
-
- xmailer = mailimf_field_new_custom( strdup( "User-Agent" ),
- strdup( USER_AGENT ) );
- if ( xmailer == NULL ) goto err_free_fields;
-
- err = mailimf_fields_add( fields, xmailer );
- if ( err != MAILIMF_NO_ERROR ) goto err_free_xmailer;
-
- return fields; // Success :)
-
-err_free_xmailer:
- mailimf_field_free( xmailer );
-err_free_fields:
- mailimf_fields_free( fields );
-err_free_reply:
- mailimf_address_list_free( reply );
- mailimf_address_list_free( bcc );
- mailimf_address_list_free( cc );
- mailimf_address_list_free( to );
-err_free_from:
- mailimf_mailbox_list_free( from );
-err_free_fromBox:
- mailimf_mailbox_free( fromBox );
-err_free_sender:
- mailimf_mailbox_free( sender );
-err_free:
- free( subject );
- qDebug( "createImfFields - error" );
-
- return NULL; // Error :(
-}
-
-mailmime *MailWrapper::buildTxtPart( QString str )
-{
- mailmime *txtPart;
- mailmime_fields *fields;
- mailmime_content *content;
- mailmime_parameter *param;
- char *txt = strdup( str.latin1() );
- int err;
-
- param = mailmime_parameter_new( strdup( "charset" ),
- strdup( "iso-8859-1" ) );
- if ( param == NULL ) goto err_free;
-
- content = mailmime_content_new_with_str( "text/plain" );
- if ( content == NULL ) goto err_free_param;
-
- err = clist_append( content->ct_parameters, param );
- if ( err != MAILIMF_NO_ERROR ) goto err_free_content;
-
- fields = mailmime_fields_new_encoding( MAILMIME_MECHANISM_8BIT );
- if ( fields == NULL ) goto err_free_content;
-
- txtPart = mailmime_new_empty( content, fields );
- if ( txtPart == NULL ) goto err_free_fields;
-
- err = mailmime_set_body_text( txtPart, txt, strlen( txt ) );
- if ( err != MAILIMF_NO_ERROR ) goto err_free_txtPart;
-
- return txtPart; // Success :)
-
-err_free_txtPart:
- mailmime_free( txtPart );
-err_free_fields:
- mailmime_fields_free( fields );
-err_free_content:
- mailmime_content_free( content );
-err_free_param:
- mailmime_parameter_free( param );
-err_free:
- free( txt );
- qDebug( "buildTxtPart - error" );
-
- return NULL; // Error :(
-}
-
-mailmime *MailWrapper::buildFilePart( QString filename, QString mimetype )
-{
- mailmime * filePart;
- mailmime_fields * fields;
- mailmime_content * content;
- mailmime_parameter * param = NULL;
- int err;
-
- int pos = filename.findRev( '/' );
- QString tmp = filename.right( filename.length() - ( pos + 1 ) );
- char *name = strdup( tmp.latin1() ); // just filename
- char *file = strdup( filename.latin1() ); // full name with path
- char *mime = strdup( mimetype.latin1() ); // mimetype -e.g. text/plain
-
- fields = mailmime_fields_new_filename(
- MAILMIME_DISPOSITION_TYPE_ATTACHMENT, name,
- MAILMIME_MECHANISM_BASE64 );
- if ( fields == NULL ) goto err_free;
-
- content = mailmime_content_new_with_str( mime );
- if ( content == NULL ) goto err_free_fields;
-
- if ( mimetype.compare( "text/plain" ) == 0 ) {
- param = mailmime_parameter_new( strdup( "charset" ),
- strdup( "iso-8859-1" ) );
- if ( param == NULL ) goto err_free_content;
-
- err = clist_append( content->ct_parameters, param );
- if ( err != MAILIMF_NO_ERROR ) goto err_free_param;
- }
-
- filePart = mailmime_new_empty( content, fields );
- if ( filePart == NULL ) goto err_free_param;
-
- err = mailmime_set_body_file( filePart, file );
- if ( err != MAILIMF_NO_ERROR ) goto err_free_filePart;
-
- return filePart; // Success :)
-
-err_free_filePart:
- mailmime_free( filePart );
-err_free_param:
- if ( param != NULL ) mailmime_parameter_free( param );
-err_free_content:
- mailmime_content_free( content );
-err_free_fields:
- mailmime_fields_free( fields );
-err_free:
- free( name );
- free( mime );
- free( file );
- qDebug( "buildFilePart - error" );
-
- return NULL; // Error :(
-}
-
-void MailWrapper::addFileParts( mailmime *message, QList<Attachment> files )
-{
- Attachment *it;
- for ( it = files.first(); it; it = files.next() ) {
- qDebug( "Adding file" );
- mailmime *filePart;
- int err;
-
- filePart = buildFilePart( it->getFileName(), it->getMimeType() );
- if ( filePart == NULL ) goto err_free;
-
- err = mailmime_smart_add_part( message, filePart );
- if ( err != MAILIMF_NO_ERROR ) goto err_free_filePart;
-
- continue; // Success :)
-
- err_free_filePart:
- mailmime_free( filePart );
- err_free:
- qDebug( "addFileParts: error adding file:" );
- qDebug( it->getFileName() );
- }
-}
-
-mailmime *MailWrapper::createMimeMail( Mail *mail )
-{
- mailmime *message, *txtPart;
- mailimf_fields *fields;
- int err;
-
- fields = createImfFields( mail );
- if ( fields == NULL ) goto err_free;
-
- message = mailmime_new_message_data( NULL );
- if ( message == NULL ) goto err_free_fields;
-
- mailmime_set_imf_fields( message, fields );
-
- txtPart = buildTxtPart( mail->getMessage() );
- if ( txtPart == NULL ) goto err_free_message;
-
- err = mailmime_smart_add_part( message, txtPart );
- if ( err != MAILIMF_NO_ERROR ) goto err_free_txtPart;
-
- addFileParts( message, mail->getAttachments() );
-
- return message; // Success :)
-
-err_free_txtPart:
- mailmime_free( txtPart );
-err_free_message:
- mailmime_free( message );
-err_free_fields:
- mailimf_fields_free( fields );
-err_free:
- qDebug( "createMimeMail: error" );
-
- return NULL; // Error :(
-}
-
-mailimf_field *MailWrapper::getField( mailimf_fields *fields, int type )
-{
- mailimf_field *field;
- clistiter *it;
-
- it = clist_begin( fields->fld_list );
- while ( it ) {
- field = (mailimf_field *) it->data;
- if ( field->fld_type == type ) {
- return field;
- }
- it = it->next;
- }
-
- return NULL;
-}
-
-static void addRcpts( clist *list, mailimf_address_list *addr_list )
-{
- clistiter *it, *it2;
-
- for ( it = clist_begin( addr_list->ad_list ); it; it = it->next ) {
- mailimf_address *addr;
- addr = (mailimf_address *) it->data;
-
- if ( addr->ad_type == MAILIMF_ADDRESS_MAILBOX ) {
- esmtp_address_list_add( list, addr->ad_data.ad_mailbox->mb_addr_spec, 0, NULL );
- } else if ( addr->ad_type == MAILIMF_ADDRESS_GROUP ) {
- clist *l = addr->ad_data.ad_group->grp_mb_list->mb_list;
- for ( it2 = clist_begin( l ); it2; it2 = it2->next ) {
- mailimf_mailbox *mbox;
- mbox = (mailimf_mailbox *) it2->data;
- esmtp_address_list_add( list, mbox->mb_addr_spec, 0, NULL );
- }
- }
- }
-}
-
-clist *MailWrapper::createRcptList( mailimf_fields *fields )
-{
- clist *rcptList;
- mailimf_field *field;
-
- rcptList = esmtp_address_list_new();
-
- field = getField( fields, MAILIMF_FIELD_TO );
- if ( field && (field->fld_type == MAILIMF_FIELD_TO)
- && field->fld_data.fld_to->to_addr_list ) {
- addRcpts( rcptList, field->fld_data.fld_to->to_addr_list );
- }
-
- field = getField( fields, MAILIMF_FIELD_CC );
- if ( field && (field->fld_type == MAILIMF_FIELD_CC)
- && field->fld_data.fld_cc->cc_addr_list ) {
- addRcpts( rcptList, field->fld_data.fld_cc->cc_addr_list );
- }
-
- field = getField( fields, MAILIMF_FIELD_BCC );
- if ( field && (field->fld_type == MAILIMF_FIELD_BCC)
- && field->fld_data.fld_bcc->bcc_addr_list ) {
- addRcpts( rcptList, field->fld_data.fld_bcc->bcc_addr_list );
- }
-
- return rcptList;
-}
-
-char *MailWrapper::getFrom( mailmime *mail )
-{
- char *from = NULL;
-
- mailimf_field *ffrom;
- ffrom = getField( mail->mm_data.mm_message.mm_fields, MAILIMF_FIELD_FROM );
- if ( ffrom && (ffrom->fld_type == MAILIMF_FIELD_FROM)
- && ffrom->fld_data.fld_from->frm_mb_list && ffrom->fld_data.fld_from->frm_mb_list->mb_list ) {
- clist *cl = ffrom->fld_data.fld_from->frm_mb_list->mb_list;
- clistiter *it;
- for ( it = clist_begin( cl ); it; it = it->next ) {
- mailimf_mailbox *mb = (mailimf_mailbox *) it->data;
- from = strdup( mb->mb_addr_spec );
- }
- }
-
- return from;
-}
-
-SMTPaccount *MailWrapper::getAccount( QString from )
-{
- SMTPaccount *smtp;
-
- QList<Account> list = settings->getAccounts();
- Account *it;
- for ( it = list.first(); it; it = list.next() ) {
- if ( it->getType().compare( "SMTP" ) == 0 ) {
- smtp = static_cast<SMTPaccount *>(it);
- if ( smtp->getMail().compare( from ) == 0 ) {
- qDebug( "SMTPaccount found for" );
- qDebug( from );
- return smtp;
- }
- }
- }
-
- return NULL;
-}
-
-QString MailWrapper::getTmpFile() {
- int num = 0;
- QString unique;
-
- QDir dir( "/tmp" );
- QStringList::Iterator it;
-
- QStringList list = dir.entryList( "opiemail-tmp-*" );
- do {
- unique.setNum( num++ );
- } while ( list.contains( "opiemail-tmp-" + unique ) > 0 );
-
- return "/tmp/opiemail-tmp-" + unique;
-}
-
-void MailWrapper::writeToFile( QString file, mailmime *mail )
-{
- FILE *f;
- int err, col = 0;
-
- f = fopen( file.latin1(), "w" );
- if ( f == NULL ) {
- qDebug( "writeToFile: error opening file" );
- return;
- }
-
- err = mailmime_write( f, &col, mail );
- if ( err != MAILIMF_NO_ERROR ) {
- fclose( f );
- qDebug( "writeToFile: error writing mailmime" );
- return;
- }
-
- fclose( f );
-}
-
-void MailWrapper::readFromFile( QString file, char **data, size_t *size )
-{
- char *buf;
- struct stat st;
- int fd, count = 0, total = 0;
-
- fd = open( file.latin1(), O_RDONLY, 0 );
- if ( fd == -1 ) return;
-
- if ( fstat( fd, &st ) != 0 ) goto err_close;
- if ( !st.st_size ) goto err_close;
-
- buf = (char *) malloc( st.st_size );
- if ( !buf ) goto err_close;
-
- while ( ( total < st.st_size ) && ( count >= 0 ) ) {
- count = read( fd, buf + total, st.st_size - total );
- total += count;
- }
- if ( count < 0 ) goto err_free;
-
- *data = buf;
- *size = st.st_size;
-
- close( fd );
-
- return; // Success :)
-
-err_free:
- free( buf );
-err_close:
- close( fd );
-}
-
-void progress( size_t current, size_t maximum )
-{
- qDebug( "Current: %i of %i", current, maximum );
-}
-
-void MailWrapper::smtpSend( mailmime *mail )
-{
- mailsmtp *session;
- clist *rcpts;
- char *from, *data, *server, *user = NULL, *pass = NULL;
- size_t size;
- int err;
- bool ssl;
- uint16_t port;
-
-
- from = getFrom( mail );
- SMTPaccount *smtp = getAccount( from );
- if ( smtp == NULL ) {
- free(from);
- return;
- }
- server = strdup( smtp->getServer().latin1() );
- ssl = smtp->getSSL();
- port = smtp->getPort().toUInt();
- rcpts = createRcptList( mail->mm_data.mm_message.mm_fields );
-
- QString file = getTmpFile();
- writeToFile( file, mail );
- readFromFile( file, &data, &size );
- QFile f( file );
- f.remove();
-
- session = mailsmtp_new( 20, &progress );
- if ( session == NULL ) goto free_mem;
-
- qDebug( "Servername %s at port %i", server, port );
- if ( ssl ) {
- qDebug( "SSL session" );
- err = mailsmtp_ssl_connect( session, server, port );
- } else {
- qDebug( "No SSL session" );
- err = mailsmtp_socket_connect( session, server, port );
- }
- if ( err != MAILSMTP_NO_ERROR ) goto free_mem_session;
-
- err = mailsmtp_init( session );
- if ( err != MAILSMTP_NO_ERROR ) goto free_con_session;
-
- qDebug( "INIT OK" );
-
- if ( smtp->getLogin() ) {
- if ( smtp->getUser().isEmpty() || smtp->getPassword().isEmpty() ) {
- // get'em
- LoginDialog login( smtp->getUser(), smtp->getPassword(), NULL, 0, true );
- login.show();
- if ( QDialog::Accepted == login.exec() ) {
- // ok
- user = strdup( login.getUser().latin1() );
- pass = strdup( login.getPassword().latin1() );
- } else {
- goto free_con_session;
- }
- } else {
- user = strdup( smtp->getUser().latin1() );
- pass = strdup( smtp->getPassword().latin1() );
- }
- qDebug( "session->auth: %i", session->auth);
- err = mailsmtp_auth( session, user, pass );
- if ( err == MAILSMTP_NO_ERROR ) qDebug("auth ok");
- qDebug( "Done auth!" );
- }
-
- err = mailsmtp_send( session, from, rcpts, data, size );
- if ( err != MAILSMTP_NO_ERROR ) goto free_con_session;
-
- qDebug( "Mail sent." );
-
-free_con_session:
- mailsmtp_quit( session );
-free_mem_session:
- mailsmtp_free( session );
-free_mem:
- smtp_address_list_free( rcpts );
- free( data );
- free( server );
- if ( smtp->getLogin() ) {
- free( user );
- free( pass );
- }
- free( from );
-}
-
-void MailWrapper::sendMail( Mail mail )
-{
- mailmime *mimeMail;
-
- mimeMail = createMimeMail( &mail );
- if ( mimeMail == NULL ) {
- qDebug( "sendMail: error creating mime mail" );
- } else {
- smtpSend( mimeMail );
- mailmime_free( mimeMail );
- }
-}
-
Mail::Mail()
:name(""), mail(""), to(""), cc(""), bcc(""), reply(""), subject(""), message("")
{
}
diff --git a/noncore/net/mail/libmailwrapper/mailwrapper.h b/noncore/net/mail/libmailwrapper/mailwrapper.h
index 02fe4b7..8fd886f 100644
--- a/noncore/net/mail/libmailwrapper/mailwrapper.h
+++ b/noncore/net/mail/libmailwrapper/mailwrapper.h
@@ -1,126 +1,91 @@
#ifndef MAILWRAPPER_H
#define MAILWRAPPER_H
#include <qpe/applnk.h>
-#include <libetpan/mailmime.h>
-#include <libetpan/mailimf.h>
-#include <libetpan/mailsmtp.h>
-#include <libetpan/mailstorage.h>
-#include <libetpan/maildriver.h>
#include <qbitarray.h>
#include <qdatetime.h>
#include "settings.h"
class Attachment
{
public:
Attachment( DocLnk lnk );
virtual ~Attachment(){}
const QString getFileName()const{ return doc.file(); }
const QString getName()const{ return doc.name(); }
const QString getMimeType()const{ return doc.type(); }
const QPixmap getPixmap()const{ return doc.pixmap(); }
const int getSize()const { return size; }
DocLnk getDocLnk() { return doc; }
protected:
DocLnk doc;
int size;
};
class Mail
{
public:
Mail();
/* Possible that this destructor must not be declared virtual
* 'cause it seems that it will never have some child classes.
* in this case this object will not get a virtual table -> memory and
* speed will be a little bit better?
*/
virtual ~Mail(){}
void addAttachment( Attachment *att ) { attList.append( att ); }
const QList<Attachment>& getAttachments()const { return attList; }
void removeAttachment( Attachment *att ) { attList.remove( att ); }
const QString&getName()const { return name; }
void setName( QString s ) { name = s; }
const QString&getMail()const{ return mail; }
void setMail( const QString&s ) { mail = s; }
const QString&getTo()const{ return to; }
void setTo( const QString&s ) { to = s; }
const QString&getCC()const{ return cc; }
void setCC( const QString&s ) { cc = s; }
const QString&getBCC()const { return bcc; }
void setBCC( const QString&s ) { bcc = s; }
const QString&getMessage()const { return message; }
void setMessage( const QString&s ) { message = s; }
const QString&getSubject()const { return subject; }
void setSubject( const QString&s ) { subject = s; }
const QString&getReply()const{ return reply; }
void setReply( const QString&a ) { reply = a; }
private:
QList<Attachment> attList;
QString name, mail, to, cc, bcc, reply, subject, message;
};
class Folder : public QObject
{
Q_OBJECT
public:
Folder( const QString&init_name,const QString&sep );
const QString&getDisplayName()const { return nameDisplay; }
const QString&getName()const { return name; }
virtual bool may_select()const{return true;};
const QString&Separator()const;
protected:
QString nameDisplay, name, separator;
};
class IMAPFolder : public Folder
{
public:
IMAPFolder(const QString&name, const QString&sep, bool select=true,const QString&prefix="" );
virtual bool may_select()const{return m_MaySelect;}
private:
static QString decodeFolderName( const QString &name );
bool m_MaySelect;
};
-class MailWrapper : public QObject
-{
- Q_OBJECT
-
-public:
- MailWrapper( Settings *s );
- void sendMail( Mail mail );
-
-private:
- mailimf_mailbox *newMailbox(const QString&name,const QString&mail );
- mailimf_address_list *parseAddresses(const QString&addr );
- mailimf_fields *createImfFields( Mail *mail );
- mailmime *buildTxtPart( QString str );
- mailmime *buildFilePart( QString filename, QString mimetype );
- void addFileParts( mailmime *message, QList<Attachment> files );
- mailmime *createMimeMail( Mail *mail );
- void smtpSend( mailmime *mail );
- mailimf_field *getField( mailimf_fields *fields, int type );
- clist *createRcptList( mailimf_fields *fields );
- char *getFrom( mailmime *mail );
- SMTPaccount *getAccount( QString from );
- void writeToFile( QString file, mailmime *mail );
- void readFromFile( QString file, char **data, size_t *size );
- static QString mailsmtpError( int err );
- static QString getTmpFile();
-
- Settings *settings;
-
-};
-
#endif
diff --git a/noncore/net/mail/libmailwrapper/pop3wrapper.h b/noncore/net/mail/libmailwrapper/pop3wrapper.h
index a31a145..75d70f8 100644
--- a/noncore/net/mail/libmailwrapper/pop3wrapper.h
+++ b/noncore/net/mail/libmailwrapper/pop3wrapper.h
@@ -1,63 +1,69 @@
#ifndef __POP3WRAPPER
#define __POP3WRAPPER
+#include <libetpan/clist.h>
#include "mailwrapper.h"
#include "abstractmail.h"
#include <qmap.h>
#include <qstring.h>
class RecMail;
class RecBody;
class encodedString;
struct mailpop3;
struct mailmessage;
struct mailmime;
struct mailmime_mechanism;
+struct mailimf_mailbox_list;
+struct mailimf_mailbox;
+struct mailimf_date_time;
+struct mailimf_group;
+struct mailimf_address_list;
class POP3wrapper : public AbstractMail
{
Q_OBJECT
public:
POP3wrapper( POP3account *a );
virtual ~POP3wrapper();
/* mailbox will be ignored */
virtual void listMessages(const QString & mailbox, QList<RecMail> &target );
virtual QList<Folder>* listFolders();
virtual QString fetchTextPart(const RecMail&mail,const RecPart&part);
virtual encodedString* fetchDecodedPart(const RecMail&mail,const RecPart&part);
virtual encodedString* fetchRawPart(const RecMail&mail,const RecPart&part);
virtual void deleteMail(const RecMail&mail);
virtual void answeredMail(const RecMail&mail);
RecBody fetchBody( const RecMail &mail );
static void pop3_progress( size_t current, size_t maximum );
protected:
void login();
void logout();
RecMail *parseHeader( const char *header );
RecBody parseMail( char *message );
QString parseMailboxList( mailimf_mailbox_list *list );
QString parseMailbox( mailimf_mailbox *box );
QString parseGroup( mailimf_group *group );
QString parseAddressList( mailimf_address_list *list );
QString parseDateTime( mailimf_date_time *date );
void cleanUpCache();
void traverseBody(RecBody&target,mailmessage*message,mailmime*mime,unsigned int current_rek=0);
static void fillSingleBody(RecPart&target,mailmessage*message,mailmime*mime);
static void fillParameters(RecPart&target,clist*parameters);
static QString POP3wrapper::getencoding(mailmime_mechanism*aEnc);
POP3account *account;
mailpop3 *m_pop3;
QString msgTempName;
unsigned int last_msg_id;
QMap<QString,encodedString*> bodyCache;
};
#endif
diff --git a/noncore/net/mail/libmailwrapper/smtpwrapper.cpp b/noncore/net/mail/libmailwrapper/smtpwrapper.cpp
new file mode 100644
index 0000000..162b1b9
--- a/dev/null
+++ b/noncore/net/mail/libmailwrapper/smtpwrapper.cpp
@@ -0,0 +1,604 @@
+#include <stdlib.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <string.h>
+#include <qdir.h>
+
+#include <libetpan/mailmime.h>
+#include <libetpan/mailimf.h>
+#include <libetpan/mailsmtp.h>
+#include <libetpan/mailstorage.h>
+#include <libetpan/maildriver.h>
+
+#include "smtpwrapper.h"
+#include "mailwrapper.h"
+#include "logindialog.h"
+#include "defines.h"
+
+SMTPwrapper::SMTPwrapper( Settings *s )
+ : QObject()
+{
+ settings = s;
+}
+
+QString SMTPwrapper::mailsmtpError( int errnum )
+{
+ switch ( errnum ) {
+ case MAILSMTP_NO_ERROR:
+ return tr( "No error" );
+ case MAILSMTP_ERROR_UNEXPECTED_CODE:
+ return tr( "Unexpected error code" );
+ case MAILSMTP_ERROR_SERVICE_NOT_AVAILABLE:
+ return tr( "Service not available" );
+ case MAILSMTP_ERROR_STREAM:
+ return tr( "Stream error" );
+ case MAILSMTP_ERROR_HOSTNAME:
+ return tr( "gethostname() failed" );
+ case MAILSMTP_ERROR_NOT_IMPLEMENTED:
+ return tr( "Not implemented" );
+ case MAILSMTP_ERROR_ACTION_NOT_TAKEN:
+ return tr( "Error, action not taken" );
+ case MAILSMTP_ERROR_EXCEED_STORAGE_ALLOCATION:
+ return tr( "Data exceeds storage allocation" );
+ case MAILSMTP_ERROR_IN_PROCESSING:
+ return tr( "Error in processing" );
+ // case MAILSMTP_ERROR_INSUFFISANT_SYSTEM_STORAGE:
+ // return tr( "Insufficient system storage" );
+ case MAILSMTP_ERROR_MAILBOX_UNAVAILABLE:
+ return tr( "Mailbox unavailable" );
+ case MAILSMTP_ERROR_MAILBOX_NAME_NOT_ALLOWED:
+ return tr( "Mailbox name not allowed" );
+ case MAILSMTP_ERROR_BAD_SEQUENCE_OF_COMMAND:
+ return tr( "Bad command sequence" );
+ case MAILSMTP_ERROR_USER_NOT_LOCAL:
+ return tr( "User not local" );
+ case MAILSMTP_ERROR_TRANSACTION_FAILED:
+ return tr( "Transaction failed" );
+ case MAILSMTP_ERROR_MEMORY:
+ return tr( "Memory error" );
+ case MAILSMTP_ERROR_CONNECTION_REFUSED:
+ return tr( "Connection refused" );
+ default:
+ return tr( "Unknown error code" );
+ }
+}
+
+mailimf_mailbox *SMTPwrapper::newMailbox(const QString&name, const QString&mail )
+{
+ return mailimf_mailbox_new( strdup( name.latin1() ),
+ strdup( mail.latin1() ) );
+}
+
+mailimf_address_list *SMTPwrapper::parseAddresses(const QString&addr )
+{
+ mailimf_address_list *addresses;
+
+ if ( addr.isEmpty() ) return NULL;
+
+ addresses = mailimf_address_list_new_empty();
+
+ QStringList list = QStringList::split( ',', addr );
+ QStringList::Iterator it;
+ for ( it = list.begin(); it != list.end(); it++ ) {
+ char *str = strdup( (*it).latin1() );
+ int err = mailimf_address_list_add_parse( addresses, str );
+ if ( err != MAILIMF_NO_ERROR ) {
+ qDebug( "Error parsing" );
+ qDebug( *it );
+ free( str );
+ } else {
+ qDebug( "Parse success! :)" );
+ }
+ }
+
+ return addresses;
+}
+
+mailimf_fields *SMTPwrapper::createImfFields(const Mail&mail )
+{
+ mailimf_fields *fields;
+ mailimf_field *xmailer;
+ mailimf_mailbox *sender, *fromBox;
+ mailimf_mailbox_list *from;
+ mailimf_address_list *to, *cc, *bcc, *reply;
+ char *subject = strdup( mail.getSubject().latin1() );
+ int err;
+
+ sender = newMailbox( mail.getName(), mail.getMail() );
+ if ( sender == NULL ) goto err_free;
+
+ fromBox = newMailbox( mail.getName(), mail.getMail() );
+ if ( fromBox == NULL ) goto err_free_sender;
+
+ from = mailimf_mailbox_list_new_empty();
+ if ( from == NULL ) goto err_free_fromBox;
+
+ err = mailimf_mailbox_list_add( from, fromBox );
+ if ( err != MAILIMF_NO_ERROR ) goto err_free_from;
+
+ to = parseAddresses( mail.getTo() );
+ if ( to == NULL ) goto err_free_from;
+
+ cc = parseAddresses( mail.getCC() );
+ bcc = parseAddresses( mail.getBCC() );
+ reply = parseAddresses( mail.getReply() );
+
+ fields = mailimf_fields_new_with_data( from, sender, reply, to, cc, bcc,
+ NULL, NULL, subject );
+ if ( fields == NULL ) goto err_free_reply;
+
+ xmailer = mailimf_field_new_custom( strdup( "User-Agent" ),
+ strdup( USER_AGENT ) );
+ if ( xmailer == NULL ) goto err_free_fields;
+
+ err = mailimf_fields_add( fields, xmailer );
+ if ( err != MAILIMF_NO_ERROR ) goto err_free_xmailer;
+
+ return fields; // Success :)
+
+err_free_xmailer:
+ mailimf_field_free( xmailer );
+err_free_fields:
+ mailimf_fields_free( fields );
+err_free_reply:
+ mailimf_address_list_free( reply );
+ mailimf_address_list_free( bcc );
+ mailimf_address_list_free( cc );
+ mailimf_address_list_free( to );
+err_free_from:
+ mailimf_mailbox_list_free( from );
+err_free_fromBox:
+ mailimf_mailbox_free( fromBox );
+err_free_sender:
+ mailimf_mailbox_free( sender );
+err_free:
+ free( subject );
+ qDebug( "createImfFields - error" );
+
+ return NULL; // Error :(
+}
+
+mailmime *SMTPwrapper::buildTxtPart(const QString&str )
+{
+ mailmime *txtPart;
+ mailmime_fields *fields;
+ mailmime_content *content;
+ mailmime_parameter *param;
+ char *txt = strdup( str.latin1() );
+ int err;
+
+ param = mailmime_parameter_new( strdup( "charset" ),
+ strdup( "iso-8859-1" ) );
+ if ( param == NULL ) goto err_free;
+
+ content = mailmime_content_new_with_str( "text/plain" );
+ if ( content == NULL ) goto err_free_param;
+
+ err = clist_append( content->ct_parameters, param );
+ if ( err != MAILIMF_NO_ERROR ) goto err_free_content;
+
+ fields = mailmime_fields_new_encoding( MAILMIME_MECHANISM_8BIT );
+ if ( fields == NULL ) goto err_free_content;
+
+ txtPart = mailmime_new_empty( content, fields );
+ if ( txtPart == NULL ) goto err_free_fields;
+
+ err = mailmime_set_body_text( txtPart, txt, strlen( txt ) );
+ if ( err != MAILIMF_NO_ERROR ) goto err_free_txtPart;
+
+ return txtPart; // Success :)
+
+err_free_txtPart:
+ mailmime_free( txtPart );
+err_free_fields:
+ mailmime_fields_free( fields );
+err_free_content:
+ mailmime_content_free( content );
+err_free_param:
+ mailmime_parameter_free( param );
+err_free:
+ free( txt );
+ qDebug( "buildTxtPart - error" );
+
+ return NULL; // Error :(
+}
+
+mailmime *SMTPwrapper::buildFilePart(const QString&filename,const QString&mimetype )
+{
+ mailmime * filePart;
+ mailmime_fields * fields;
+ mailmime_content * content;
+ mailmime_parameter * param = NULL;
+ int err;
+
+ int pos = filename.findRev( '/' );
+ QString tmp = filename.right( filename.length() - ( pos + 1 ) );
+ char *name = strdup( tmp.latin1() ); // just filename
+ char *file = strdup( filename.latin1() ); // full name with path
+ char *mime = strdup( mimetype.latin1() ); // mimetype -e.g. text/plain
+
+ fields = mailmime_fields_new_filename(
+ MAILMIME_DISPOSITION_TYPE_ATTACHMENT, name,
+ MAILMIME_MECHANISM_BASE64 );
+ if ( fields == NULL ) goto err_free;
+
+ content = mailmime_content_new_with_str( mime );
+ if ( content == NULL ) goto err_free_fields;
+
+ if ( mimetype.compare( "text/plain" ) == 0 ) {
+ param = mailmime_parameter_new( strdup( "charset" ),
+ strdup( "iso-8859-1" ) );
+ if ( param == NULL ) goto err_free_content;
+
+ err = clist_append( content->ct_parameters, param );
+ if ( err != MAILIMF_NO_ERROR ) goto err_free_param;
+ }
+
+ filePart = mailmime_new_empty( content, fields );
+ if ( filePart == NULL ) goto err_free_param;
+
+ err = mailmime_set_body_file( filePart, file );
+ if ( err != MAILIMF_NO_ERROR ) goto err_free_filePart;
+
+ return filePart; // Success :)
+
+err_free_filePart:
+ mailmime_free( filePart );
+err_free_param:
+ if ( param != NULL ) mailmime_parameter_free( param );
+err_free_content:
+ mailmime_content_free( content );
+err_free_fields:
+ mailmime_fields_free( fields );
+err_free:
+ free( name );
+ free( mime );
+ free( file );
+ qDebug( "buildFilePart - error" );
+
+ return NULL; // Error :(
+}
+
+void SMTPwrapper::addFileParts( mailmime *message,const QList<Attachment>&files )
+{
+ const Attachment *it;
+ /* work around for the brainfucked qlist which can not act with const values */
+ for ( it = ((QList<Attachment>)files).first(); it; it = ((QList<Attachment>)files).next() ) {
+ qDebug( "Adding file" );
+ mailmime *filePart;
+ int err;
+
+ filePart = buildFilePart( it->getFileName(), it->getMimeType() );
+ if ( filePart == NULL ) goto err_free;
+
+ err = mailmime_smart_add_part( message, filePart );
+ if ( err != MAILIMF_NO_ERROR ) goto err_free_filePart;
+
+ continue; // Success :)
+
+ err_free_filePart:
+ mailmime_free( filePart );
+ err_free:
+ qDebug( "addFileParts: error adding file:" );
+ qDebug( it->getFileName() );
+ }
+}
+
+mailmime *SMTPwrapper::createMimeMail(const Mail &mail )
+{
+ mailmime *message, *txtPart;
+ mailimf_fields *fields;
+ int err;
+
+ fields = createImfFields( mail );
+ if ( fields == NULL ) goto err_free;
+
+ message = mailmime_new_message_data( NULL );
+ if ( message == NULL ) goto err_free_fields;
+
+ mailmime_set_imf_fields( message, fields );
+
+ txtPart = buildTxtPart( mail.getMessage() );
+ if ( txtPart == NULL ) goto err_free_message;
+
+ err = mailmime_smart_add_part( message, txtPart );
+ if ( err != MAILIMF_NO_ERROR ) goto err_free_txtPart;
+
+ addFileParts( message, mail.getAttachments() );
+
+ return message; // Success :)
+
+err_free_txtPart:
+ mailmime_free( txtPart );
+err_free_message:
+ mailmime_free( message );
+err_free_fields:
+ mailimf_fields_free( fields );
+err_free:
+ qDebug( "createMimeMail: error" );
+
+ return NULL; // Error :(
+}
+
+mailimf_field *SMTPwrapper::getField( mailimf_fields *fields, int type )
+{
+ mailimf_field *field;
+ clistiter *it;
+
+ it = clist_begin( fields->fld_list );
+ while ( it ) {
+ field = (mailimf_field *) it->data;
+ if ( field->fld_type == type ) {
+ return field;
+ }
+ it = it->next;
+ }
+
+ return NULL;
+}
+
+void SMTPwrapper::addRcpts( clist *list, mailimf_address_list *addr_list )
+{
+ clistiter *it, *it2;
+
+ for ( it = clist_begin( addr_list->ad_list ); it; it = it->next ) {
+ mailimf_address *addr;
+ addr = (mailimf_address *) it->data;
+
+ if ( addr->ad_type == MAILIMF_ADDRESS_MAILBOX ) {
+ esmtp_address_list_add( list, addr->ad_data.ad_mailbox->mb_addr_spec, 0, NULL );
+ } else if ( addr->ad_type == MAILIMF_ADDRESS_GROUP ) {
+ clist *l = addr->ad_data.ad_group->grp_mb_list->mb_list;
+ for ( it2 = clist_begin( l ); it2; it2 = it2->next ) {
+ mailimf_mailbox *mbox;
+ mbox = (mailimf_mailbox *) it2->data;
+ esmtp_address_list_add( list, mbox->mb_addr_spec, 0, NULL );
+ }
+ }
+ }
+}
+
+clist *SMTPwrapper::createRcptList( mailimf_fields *fields )
+{
+ clist *rcptList;
+ mailimf_field *field;
+
+ rcptList = esmtp_address_list_new();
+
+ field = getField( fields, MAILIMF_FIELD_TO );
+ if ( field && (field->fld_type == MAILIMF_FIELD_TO)
+ && field->fld_data.fld_to->to_addr_list ) {
+ addRcpts( rcptList, field->fld_data.fld_to->to_addr_list );
+ }
+
+ field = getField( fields, MAILIMF_FIELD_CC );
+ if ( field && (field->fld_type == MAILIMF_FIELD_CC)
+ && field->fld_data.fld_cc->cc_addr_list ) {
+ addRcpts( rcptList, field->fld_data.fld_cc->cc_addr_list );
+ }
+
+ field = getField( fields, MAILIMF_FIELD_BCC );
+ if ( field && (field->fld_type == MAILIMF_FIELD_BCC)
+ && field->fld_data.fld_bcc->bcc_addr_list ) {
+ addRcpts( rcptList, field->fld_data.fld_bcc->bcc_addr_list );
+ }
+
+ return rcptList;
+}
+
+char *SMTPwrapper::getFrom( mailmime *mail )
+{
+ char *from = NULL;
+
+ mailimf_field *ffrom;
+ ffrom = getField( mail->mm_data.mm_message.mm_fields, MAILIMF_FIELD_FROM );
+ if ( ffrom && (ffrom->fld_type == MAILIMF_FIELD_FROM)
+ && ffrom->fld_data.fld_from->frm_mb_list && ffrom->fld_data.fld_from->frm_mb_list->mb_list ) {
+ clist *cl = ffrom->fld_data.fld_from->frm_mb_list->mb_list;
+ clistiter *it;
+ for ( it = clist_begin( cl ); it; it = it->next ) {
+ mailimf_mailbox *mb = (mailimf_mailbox *) it->data;
+ from = strdup( mb->mb_addr_spec );
+ }
+ }
+
+ return from;
+}
+
+SMTPaccount *SMTPwrapper::getAccount(const QString&from )
+{
+ SMTPaccount *smtp;
+
+ QList<Account> list = settings->getAccounts();
+ Account *it;
+ for ( it = list.first(); it; it = list.next() ) {
+ if ( it->getType().compare( "SMTP" ) == 0 ) {
+ smtp = static_cast<SMTPaccount *>(it);
+ if ( smtp->getMail().compare( from ) == 0 ) {
+ qDebug( "SMTPaccount found for" );
+ qDebug( from );
+ return smtp;
+ }
+ }
+ }
+
+ return NULL;
+}
+
+QString SMTPwrapper::getTmpFile() {
+ int num = 0;
+ QString unique;
+
+ QDir dir( "/tmp" );
+ QStringList::Iterator it;
+
+ QStringList list = dir.entryList( "opiemail-tmp-*" );
+ do {
+ unique.setNum( num++ );
+ } while ( list.contains( "opiemail-tmp-" + unique ) > 0 );
+
+ return "/tmp/opiemail-tmp-" + unique;
+}
+
+void SMTPwrapper::writeToFile(const QString&file, mailmime *mail )
+{
+ FILE *f;
+ int err, col = 0;
+
+ f = fopen( file.latin1(), "w" );
+ if ( f == NULL ) {
+ qDebug( "writeToFile: error opening file" );
+ return;
+ }
+
+ err = mailmime_write( f, &col, mail );
+ if ( err != MAILIMF_NO_ERROR ) {
+ fclose( f );
+ qDebug( "writeToFile: error writing mailmime" );
+ return;
+ }
+
+ fclose( f );
+}
+
+void SMTPwrapper::readFromFile(const QString&file, char **data, size_t *size )
+{
+ char *buf;
+ struct stat st;
+ int fd, count = 0, total = 0;
+
+ fd = open( file.latin1(), O_RDONLY, 0 );
+ if ( fd == -1 ) return;
+
+ if ( fstat( fd, &st ) != 0 ) goto err_close;
+ if ( !st.st_size ) goto err_close;
+
+ buf = (char *) malloc( st.st_size );
+ if ( !buf ) goto err_close;
+
+ while ( ( total < st.st_size ) && ( count >= 0 ) ) {
+ count = read( fd, buf + total, st.st_size - total );
+ total += count;
+ }
+ if ( count < 0 ) goto err_free;
+
+ *data = buf;
+ *size = st.st_size;
+
+ close( fd );
+
+ return; // Success :)
+
+err_free:
+ free( buf );
+err_close:
+ close( fd );
+}
+
+void SMTPwrapper::progress( size_t current, size_t maximum )
+{
+ qDebug( "Current: %i of %i", current, maximum );
+}
+
+void SMTPwrapper::smtpSend( mailmime *mail )
+{
+ mailsmtp *session;
+ clist *rcpts;
+ char *from, *data, *server, *user = NULL, *pass = NULL;
+ size_t size;
+ int err;
+ bool ssl;
+ uint16_t port;
+
+
+ from = getFrom( mail );
+ SMTPaccount *smtp = getAccount( from );
+ if ( smtp == NULL ) {
+ free(from);
+ return;
+ }
+ server = strdup( smtp->getServer().latin1() );
+ ssl = smtp->getSSL();
+ port = smtp->getPort().toUInt();
+ rcpts = createRcptList( mail->mm_data.mm_message.mm_fields );
+
+ QString file = getTmpFile();
+ writeToFile( file, mail );
+ readFromFile( file, &data, &size );
+ QFile f( file );
+ f.remove();
+
+ session = mailsmtp_new( 20, &progress );
+ if ( session == NULL ) goto free_mem;
+
+ qDebug( "Servername %s at port %i", server, port );
+ if ( ssl ) {
+ qDebug( "SSL session" );
+ err = mailsmtp_ssl_connect( session, server, port );
+ } else {
+ qDebug( "No SSL session" );
+ err = mailsmtp_socket_connect( session, server, port );
+ }
+ if ( err != MAILSMTP_NO_ERROR ) goto free_mem_session;
+
+ err = mailsmtp_init( session );
+ if ( err != MAILSMTP_NO_ERROR ) goto free_con_session;
+
+ qDebug( "INIT OK" );
+
+ if ( smtp->getLogin() ) {
+ if ( smtp->getUser().isEmpty() || smtp->getPassword().isEmpty() ) {
+ // get'em
+ LoginDialog login( smtp->getUser(), smtp->getPassword(), NULL, 0, true );
+ login.show();
+ if ( QDialog::Accepted == login.exec() ) {
+ // ok
+ user = strdup( login.getUser().latin1() );
+ pass = strdup( login.getPassword().latin1() );
+ } else {
+ goto free_con_session;
+ }
+ } else {
+ user = strdup( smtp->getUser().latin1() );
+ pass = strdup( smtp->getPassword().latin1() );
+ }
+ qDebug( "session->auth: %i", session->auth);
+ err = mailsmtp_auth( session, user, pass );
+ if ( err == MAILSMTP_NO_ERROR ) qDebug("auth ok");
+ qDebug( "Done auth!" );
+ }
+
+ err = mailsmtp_send( session, from, rcpts, data, size );
+ if ( err != MAILSMTP_NO_ERROR ) goto free_con_session;
+
+ qDebug( "Mail sent." );
+
+free_con_session:
+ mailsmtp_quit( session );
+free_mem_session:
+ mailsmtp_free( session );
+free_mem:
+ smtp_address_list_free( rcpts );
+ free( data );
+ free( server );
+ if ( smtp->getLogin() ) {
+ free( user );
+ free( pass );
+ }
+ free( from );
+}
+
+void SMTPwrapper::sendMail(const Mail&mail )
+{
+ mailmime *mimeMail;
+
+ mimeMail = createMimeMail(mail );
+ if ( mimeMail == NULL ) {
+ qDebug( "sendMail: error creating mime mail" );
+ } else {
+ smtpSend( mimeMail );
+ mailmime_free( mimeMail );
+ }
+}
diff --git a/noncore/net/mail/libmailwrapper/smtpwrapper.h b/noncore/net/mail/libmailwrapper/smtpwrapper.h
new file mode 100644
index 0000000..8fdb07d
--- a/dev/null
+++ b/noncore/net/mail/libmailwrapper/smtpwrapper.h
@@ -0,0 +1,53 @@
+#ifndef SMTPwrapper_H
+#define SMTPwrapper_H
+
+#include <qpe/applnk.h>
+
+#include <qbitarray.h>
+#include <qdatetime.h>
+#include <libetpan/clist.h>
+
+#include "settings.h"
+
+class Mail;
+class Attachment;
+struct mailimf_fields;
+struct mailimf_field;
+struct mailimf_mailbox;
+struct mailmime;
+struct mailimf_address_list;
+
+class SMTPwrapper : public QObject
+{
+ Q_OBJECT
+
+public:
+ SMTPwrapper( Settings *s );
+ virtual ~SMTPwrapper(){}
+ void sendMail(const Mail& mail );
+
+protected:
+ mailimf_mailbox *newMailbox(const QString&name,const QString&mail );
+ mailimf_fields *createImfFields(const Mail &mail );
+ mailmime *createMimeMail(const Mail&mail );
+
+ mailimf_address_list *parseAddresses(const QString&addr );
+ void addFileParts( mailmime *message,const QList<Attachment>&files );
+ mailmime *buildTxtPart(const QString&str );
+ mailmime *buildFilePart(const QString&filename,const QString&mimetype );
+ void smtpSend( mailmime *mail );
+ mailimf_field *getField( mailimf_fields *fields, int type );
+ clist *createRcptList( mailimf_fields *fields );
+ char *getFrom( mailmime *mail );
+ SMTPaccount *getAccount(const QString&from );
+ void writeToFile(const QString&file, mailmime *mail );
+ void readFromFile(const QString&file, char **data, size_t *size );
+
+ static QString mailsmtpError( int err );
+ static QString getTmpFile();
+ static void progress( size_t current, size_t maximum );
+ static void addRcpts( clist *list, mailimf_address_list *addr_list );
+ Settings *settings;
+};
+
+#endif
diff --git a/noncore/net/mail/mail.pro b/noncore/net/mail/mail.pro
index 49be889..2542344 100644
--- a/noncore/net/mail/mail.pro
+++ b/noncore/net/mail/mail.pro
@@ -1,64 +1,66 @@
CONFIG += qt warn_on debug quick-app
HEADERS = defines.h \
logindialog.h \
settings.h \
editaccounts.h \
mailwrapper.h \
composemail.h \
accountview.h \
mainwindow.h \
viewmail.h \
viewmailbase.h \
opiemail.h \
imapwrapper.h \
mailtypes.h \
mailistviewitem.h \
pop3wrapper.h \
abstractmail.h \
settingsdialog.h \
- statuswidget.h
+ statuswidget.h \
+ smtpwrapper.h
SOURCES = main.cpp \
opiemail.cpp \
mainwindow.cpp \
accountview.cpp \
composemail.cpp \
mailwrapper.cpp \
imapwrapper.cpp \
addresspicker.cpp \
editaccounts.cpp \
logindialog.cpp \
viewmail.cpp \
viewmailbase.cpp \
settings.cpp \
mailtypes.cpp \
pop3wrapper.cpp \
abstractmail.cpp \
settingsdialog.cpp \
- statuswidget.cpp
+ statuswidget.cpp \
+ smtpwrapper.cpp
INTERFACES = editaccountsui.ui \
selectmailtypeui.ui \
imapconfigui.ui \
pop3configui.ui \
nntpconfigui.ui \
smtpconfigui.ui \
addresspickerui.ui \
logindialogui.ui \
composemailui.ui \
settingsdialogui.ui \
statuswidgetui.ui
INCLUDEPATH += $(OPIEDIR)/include
CONFTEST = $$system( echo $CONFIG_TARGET_MACOSX )
contains( CONFTEST, y ){
LIBS += -lqpe -letpan -lssl -lcrypto -lopie -liconv
}else{
LIBS += -lqpe -letpan -lssl -lcrypto -lopie
}
TARGET = opiemail
include ( $(OPIEDIR)/include.pro )
diff --git a/noncore/net/mail/mailwrapper.cpp b/noncore/net/mail/mailwrapper.cpp
index 75c06f9..c5d4265 100644
--- a/noncore/net/mail/mailwrapper.cpp
+++ b/noncore/net/mail/mailwrapper.cpp
@@ -1,723 +1,138 @@
#include <stdlib.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>
#include <fcntl.h>
#include <string.h>
#include <qdir.h>
#include "mailwrapper.h"
#include "logindialog.h"
//#include "mail.h"
#include "defines.h"
Attachment::Attachment( DocLnk lnk )
{
doc = lnk;
size = QFileInfo( doc.file() ).size();
}
Folder::Folder(const QString&tmp_name, const QString&sep )
{
name = tmp_name;
nameDisplay = name;
separator = sep;
}
const QString& Folder::Separator()const
{
return separator;
}
IMAPFolder::IMAPFolder(const QString&name,const QString&sep, bool select,const QString&prefix )
: Folder( name,sep ),m_MaySelect(select)
{
// Decode IMAP foldername
nameDisplay = IMAPFolder::decodeFolderName( name );
qDebug( "folder " + name + " - displayed as " + nameDisplay );
if (prefix.length()>0) {
if (nameDisplay.startsWith(prefix) && nameDisplay.length()>prefix.length()) {
nameDisplay=nameDisplay.right(nameDisplay.length()-prefix.length());
}
}
}
static unsigned char base64chars[] =
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+,";
/**
* Decodes base64 encoded parts of the imapfolder name
* Code taken from kde cvs: kdebase/kioslave/imap4/rfcdecoder.cc
*/
QString IMAPFolder::decodeFolderName( const QString &name )
{
unsigned char c, i, bitcount;
unsigned long ucs4, utf16, bitbuf;
unsigned char base64[256], utf8[6];
unsigned long srcPtr = 0;
QCString dst;
QCString src = name.ascii();
/* initialize modified base64 decoding table */
memset(base64, UNDEFINED, sizeof(base64));
for (i = 0; i < sizeof(base64chars); ++i) {
base64[(int)base64chars[i]] = i;
}
/* loop until end of string */
while (srcPtr < src.length ()) {
c = src[srcPtr++];
/* deal with literal characters and &- */
if (c != '&' || src[srcPtr] == '-') {
/* encode literally */
dst += c;
/* skip over the '-' if this is an &- sequence */
if (c == '&')
srcPtr++;
} else {
/* convert modified UTF-7 -> UTF-16 -> UCS-4 -> UTF-8 -> HEX */
bitbuf = 0;
bitcount = 0;
ucs4 = 0;
while ((c = base64[(unsigned char) src[srcPtr]]) != UNDEFINED) {
++srcPtr;
bitbuf = (bitbuf << 6) | c;
bitcount += 6;
/* enough bits for a UTF-16 character? */
if (bitcount >= 16) {
bitcount -= 16;
utf16 = (bitcount ? bitbuf >> bitcount : bitbuf) & 0xffff;
/* convert UTF16 to UCS4 */
if (utf16 >= UTF16HIGHSTART && utf16 <= UTF16HIGHEND) {
ucs4 = (utf16 - UTF16HIGHSTART) << UTF16SHIFT;
continue;
} else if (utf16 >= UTF16LOSTART && utf16 <= UTF16LOEND) {
ucs4 += utf16 - UTF16LOSTART + UTF16BASE;
} else {
ucs4 = utf16;
}
/* convert UTF-16 range of UCS4 to UTF-8 */
if (ucs4 <= 0x7fUL) {
utf8[0] = ucs4;
i = 1;
} else if (ucs4 <= 0x7ffUL) {
utf8[0] = 0xc0 | (ucs4 >> 6);
utf8[1] = 0x80 | (ucs4 & 0x3f);
i = 2;
} else if (ucs4 <= 0xffffUL) {
utf8[0] = 0xe0 | (ucs4 >> 12);
utf8[1] = 0x80 | ((ucs4 >> 6) & 0x3f);
utf8[2] = 0x80 | (ucs4 & 0x3f);
i = 3;
} else {
utf8[0] = 0xf0 | (ucs4 >> 18);
utf8[1] = 0x80 | ((ucs4 >> 12) & 0x3f);
utf8[2] = 0x80 | ((ucs4 >> 6) & 0x3f);
utf8[3] = 0x80 | (ucs4 & 0x3f);
i = 4;
}
/* copy it */
for (c = 0; c < i; ++c) {
dst += utf8[c];
}
}
}
/* skip over trailing '-' in modified UTF-7 encoding */
if (src[srcPtr] == '-')
++srcPtr;
}
}
return QString::fromUtf8( dst.data() );
}
-MailWrapper::MailWrapper( Settings *s )
- : QObject()
-{
- settings = s;
-}
-
-QString MailWrapper::mailsmtpError( int errnum )
-{
- switch ( errnum ) {
- case MAILSMTP_NO_ERROR:
- return tr( "No error" );
- case MAILSMTP_ERROR_UNEXPECTED_CODE:
- return tr( "Unexpected error code" );
- case MAILSMTP_ERROR_SERVICE_NOT_AVAILABLE:
- return tr( "Service not available" );
- case MAILSMTP_ERROR_STREAM:
- return tr( "Stream error" );
- case MAILSMTP_ERROR_HOSTNAME:
- return tr( "gethostname() failed" );
- case MAILSMTP_ERROR_NOT_IMPLEMENTED:
- return tr( "Not implemented" );
- case MAILSMTP_ERROR_ACTION_NOT_TAKEN:
- return tr( "Error, action not taken" );
- case MAILSMTP_ERROR_EXCEED_STORAGE_ALLOCATION:
- return tr( "Data exceeds storage allocation" );
- case MAILSMTP_ERROR_IN_PROCESSING:
- return tr( "Error in processing" );
- // case MAILSMTP_ERROR_INSUFFISANT_SYSTEM_STORAGE:
- // return tr( "Insufficient system storage" );
- case MAILSMTP_ERROR_MAILBOX_UNAVAILABLE:
- return tr( "Mailbox unavailable" );
- case MAILSMTP_ERROR_MAILBOX_NAME_NOT_ALLOWED:
- return tr( "Mailbox name not allowed" );
- case MAILSMTP_ERROR_BAD_SEQUENCE_OF_COMMAND:
- return tr( "Bad command sequence" );
- case MAILSMTP_ERROR_USER_NOT_LOCAL:
- return tr( "User not local" );
- case MAILSMTP_ERROR_TRANSACTION_FAILED:
- return tr( "Transaction failed" );
- case MAILSMTP_ERROR_MEMORY:
- return tr( "Memory error" );
- case MAILSMTP_ERROR_CONNECTION_REFUSED:
- return tr( "Connection refused" );
- default:
- return tr( "Unknown error code" );
- }
-}
-
-mailimf_mailbox *MailWrapper::newMailbox(const QString&name, const QString&mail )
-{
- return mailimf_mailbox_new( strdup( name.latin1() ),
- strdup( mail.latin1() ) );
-}
-
-mailimf_address_list *MailWrapper::parseAddresses(const QString&addr )
-{
- mailimf_address_list *addresses;
-
- if ( addr.isEmpty() ) return NULL;
-
- addresses = mailimf_address_list_new_empty();
-
- QStringList list = QStringList::split( ',', addr );
- QStringList::Iterator it;
- for ( it = list.begin(); it != list.end(); it++ ) {
- char *str = strdup( (*it).latin1() );
- int err = mailimf_address_list_add_parse( addresses, str );
- if ( err != MAILIMF_NO_ERROR ) {
- qDebug( "Error parsing" );
- qDebug( *it );
- free( str );
- } else {
- qDebug( "Parse success! :)" );
- }
- }
-
- return addresses;
-}
-
-mailimf_fields *MailWrapper::createImfFields( Mail *mail )
-{
- mailimf_fields *fields;
- mailimf_field *xmailer;
- mailimf_mailbox *sender, *fromBox;
- mailimf_mailbox_list *from;
- mailimf_address_list *to, *cc, *bcc, *reply;
- char *subject = strdup( mail->getSubject().latin1() );
- int err;
-
- sender = newMailbox( mail->getName(), mail->getMail() );
- if ( sender == NULL ) goto err_free;
-
- fromBox = newMailbox( mail->getName(), mail->getMail() );
- if ( fromBox == NULL ) goto err_free_sender;
-
- from = mailimf_mailbox_list_new_empty();
- if ( from == NULL ) goto err_free_fromBox;
-
- err = mailimf_mailbox_list_add( from, fromBox );
- if ( err != MAILIMF_NO_ERROR ) goto err_free_from;
-
- to = parseAddresses( mail->getTo() );
- if ( to == NULL ) goto err_free_from;
-
- cc = parseAddresses( mail->getCC() );
- bcc = parseAddresses( mail->getBCC() );
- reply = parseAddresses( mail->getReply() );
-
- fields = mailimf_fields_new_with_data( from, sender, reply, to, cc, bcc,
- NULL, NULL, subject );
- if ( fields == NULL ) goto err_free_reply;
-
- xmailer = mailimf_field_new_custom( strdup( "User-Agent" ),
- strdup( USER_AGENT ) );
- if ( xmailer == NULL ) goto err_free_fields;
-
- err = mailimf_fields_add( fields, xmailer );
- if ( err != MAILIMF_NO_ERROR ) goto err_free_xmailer;
-
- return fields; // Success :)
-
-err_free_xmailer:
- mailimf_field_free( xmailer );
-err_free_fields:
- mailimf_fields_free( fields );
-err_free_reply:
- mailimf_address_list_free( reply );
- mailimf_address_list_free( bcc );
- mailimf_address_list_free( cc );
- mailimf_address_list_free( to );
-err_free_from:
- mailimf_mailbox_list_free( from );
-err_free_fromBox:
- mailimf_mailbox_free( fromBox );
-err_free_sender:
- mailimf_mailbox_free( sender );
-err_free:
- free( subject );
- qDebug( "createImfFields - error" );
-
- return NULL; // Error :(
-}
-
-mailmime *MailWrapper::buildTxtPart( QString str )
-{
- mailmime *txtPart;
- mailmime_fields *fields;
- mailmime_content *content;
- mailmime_parameter *param;
- char *txt = strdup( str.latin1() );
- int err;
-
- param = mailmime_parameter_new( strdup( "charset" ),
- strdup( "iso-8859-1" ) );
- if ( param == NULL ) goto err_free;
-
- content = mailmime_content_new_with_str( "text/plain" );
- if ( content == NULL ) goto err_free_param;
-
- err = clist_append( content->ct_parameters, param );
- if ( err != MAILIMF_NO_ERROR ) goto err_free_content;
-
- fields = mailmime_fields_new_encoding( MAILMIME_MECHANISM_8BIT );
- if ( fields == NULL ) goto err_free_content;
-
- txtPart = mailmime_new_empty( content, fields );
- if ( txtPart == NULL ) goto err_free_fields;
-
- err = mailmime_set_body_text( txtPart, txt, strlen( txt ) );
- if ( err != MAILIMF_NO_ERROR ) goto err_free_txtPart;
-
- return txtPart; // Success :)
-
-err_free_txtPart:
- mailmime_free( txtPart );
-err_free_fields:
- mailmime_fields_free( fields );
-err_free_content:
- mailmime_content_free( content );
-err_free_param:
- mailmime_parameter_free( param );
-err_free:
- free( txt );
- qDebug( "buildTxtPart - error" );
-
- return NULL; // Error :(
-}
-
-mailmime *MailWrapper::buildFilePart( QString filename, QString mimetype )
-{
- mailmime * filePart;
- mailmime_fields * fields;
- mailmime_content * content;
- mailmime_parameter * param = NULL;
- int err;
-
- int pos = filename.findRev( '/' );
- QString tmp = filename.right( filename.length() - ( pos + 1 ) );
- char *name = strdup( tmp.latin1() ); // just filename
- char *file = strdup( filename.latin1() ); // full name with path
- char *mime = strdup( mimetype.latin1() ); // mimetype -e.g. text/plain
-
- fields = mailmime_fields_new_filename(
- MAILMIME_DISPOSITION_TYPE_ATTACHMENT, name,
- MAILMIME_MECHANISM_BASE64 );
- if ( fields == NULL ) goto err_free;
-
- content = mailmime_content_new_with_str( mime );
- if ( content == NULL ) goto err_free_fields;
-
- if ( mimetype.compare( "text/plain" ) == 0 ) {
- param = mailmime_parameter_new( strdup( "charset" ),
- strdup( "iso-8859-1" ) );
- if ( param == NULL ) goto err_free_content;
-
- err = clist_append( content->ct_parameters, param );
- if ( err != MAILIMF_NO_ERROR ) goto err_free_param;
- }
-
- filePart = mailmime_new_empty( content, fields );
- if ( filePart == NULL ) goto err_free_param;
-
- err = mailmime_set_body_file( filePart, file );
- if ( err != MAILIMF_NO_ERROR ) goto err_free_filePart;
-
- return filePart; // Success :)
-
-err_free_filePart:
- mailmime_free( filePart );
-err_free_param:
- if ( param != NULL ) mailmime_parameter_free( param );
-err_free_content:
- mailmime_content_free( content );
-err_free_fields:
- mailmime_fields_free( fields );
-err_free:
- free( name );
- free( mime );
- free( file );
- qDebug( "buildFilePart - error" );
-
- return NULL; // Error :(
-}
-
-void MailWrapper::addFileParts( mailmime *message, QList<Attachment> files )
-{
- Attachment *it;
- for ( it = files.first(); it; it = files.next() ) {
- qDebug( "Adding file" );
- mailmime *filePart;
- int err;
-
- filePart = buildFilePart( it->getFileName(), it->getMimeType() );
- if ( filePart == NULL ) goto err_free;
-
- err = mailmime_smart_add_part( message, filePart );
- if ( err != MAILIMF_NO_ERROR ) goto err_free_filePart;
-
- continue; // Success :)
-
- err_free_filePart:
- mailmime_free( filePart );
- err_free:
- qDebug( "addFileParts: error adding file:" );
- qDebug( it->getFileName() );
- }
-}
-
-mailmime *MailWrapper::createMimeMail( Mail *mail )
-{
- mailmime *message, *txtPart;
- mailimf_fields *fields;
- int err;
-
- fields = createImfFields( mail );
- if ( fields == NULL ) goto err_free;
-
- message = mailmime_new_message_data( NULL );
- if ( message == NULL ) goto err_free_fields;
-
- mailmime_set_imf_fields( message, fields );
-
- txtPart = buildTxtPart( mail->getMessage() );
- if ( txtPart == NULL ) goto err_free_message;
-
- err = mailmime_smart_add_part( message, txtPart );
- if ( err != MAILIMF_NO_ERROR ) goto err_free_txtPart;
-
- addFileParts( message, mail->getAttachments() );
-
- return message; // Success :)
-
-err_free_txtPart:
- mailmime_free( txtPart );
-err_free_message:
- mailmime_free( message );
-err_free_fields:
- mailimf_fields_free( fields );
-err_free:
- qDebug( "createMimeMail: error" );
-
- return NULL; // Error :(
-}
-
-mailimf_field *MailWrapper::getField( mailimf_fields *fields, int type )
-{
- mailimf_field *field;
- clistiter *it;
-
- it = clist_begin( fields->fld_list );
- while ( it ) {
- field = (mailimf_field *) it->data;
- if ( field->fld_type == type ) {
- return field;
- }
- it = it->next;
- }
-
- return NULL;
-}
-
-static void addRcpts( clist *list, mailimf_address_list *addr_list )
-{
- clistiter *it, *it2;
-
- for ( it = clist_begin( addr_list->ad_list ); it; it = it->next ) {
- mailimf_address *addr;
- addr = (mailimf_address *) it->data;
-
- if ( addr->ad_type == MAILIMF_ADDRESS_MAILBOX ) {
- esmtp_address_list_add( list, addr->ad_data.ad_mailbox->mb_addr_spec, 0, NULL );
- } else if ( addr->ad_type == MAILIMF_ADDRESS_GROUP ) {
- clist *l = addr->ad_data.ad_group->grp_mb_list->mb_list;
- for ( it2 = clist_begin( l ); it2; it2 = it2->next ) {
- mailimf_mailbox *mbox;
- mbox = (mailimf_mailbox *) it2->data;
- esmtp_address_list_add( list, mbox->mb_addr_spec, 0, NULL );
- }
- }
- }
-}
-
-clist *MailWrapper::createRcptList( mailimf_fields *fields )
-{
- clist *rcptList;
- mailimf_field *field;
-
- rcptList = esmtp_address_list_new();
-
- field = getField( fields, MAILIMF_FIELD_TO );
- if ( field && (field->fld_type == MAILIMF_FIELD_TO)
- && field->fld_data.fld_to->to_addr_list ) {
- addRcpts( rcptList, field->fld_data.fld_to->to_addr_list );
- }
-
- field = getField( fields, MAILIMF_FIELD_CC );
- if ( field && (field->fld_type == MAILIMF_FIELD_CC)
- && field->fld_data.fld_cc->cc_addr_list ) {
- addRcpts( rcptList, field->fld_data.fld_cc->cc_addr_list );
- }
-
- field = getField( fields, MAILIMF_FIELD_BCC );
- if ( field && (field->fld_type == MAILIMF_FIELD_BCC)
- && field->fld_data.fld_bcc->bcc_addr_list ) {
- addRcpts( rcptList, field->fld_data.fld_bcc->bcc_addr_list );
- }
-
- return rcptList;
-}
-
-char *MailWrapper::getFrom( mailmime *mail )
-{
- char *from = NULL;
-
- mailimf_field *ffrom;
- ffrom = getField( mail->mm_data.mm_message.mm_fields, MAILIMF_FIELD_FROM );
- if ( ffrom && (ffrom->fld_type == MAILIMF_FIELD_FROM)
- && ffrom->fld_data.fld_from->frm_mb_list && ffrom->fld_data.fld_from->frm_mb_list->mb_list ) {
- clist *cl = ffrom->fld_data.fld_from->frm_mb_list->mb_list;
- clistiter *it;
- for ( it = clist_begin( cl ); it; it = it->next ) {
- mailimf_mailbox *mb = (mailimf_mailbox *) it->data;
- from = strdup( mb->mb_addr_spec );
- }
- }
-
- return from;
-}
-
-SMTPaccount *MailWrapper::getAccount( QString from )
-{
- SMTPaccount *smtp;
-
- QList<Account> list = settings->getAccounts();
- Account *it;
- for ( it = list.first(); it; it = list.next() ) {
- if ( it->getType().compare( "SMTP" ) == 0 ) {
- smtp = static_cast<SMTPaccount *>(it);
- if ( smtp->getMail().compare( from ) == 0 ) {
- qDebug( "SMTPaccount found for" );
- qDebug( from );
- return smtp;
- }
- }
- }
-
- return NULL;
-}
-
-QString MailWrapper::getTmpFile() {
- int num = 0;
- QString unique;
-
- QDir dir( "/tmp" );
- QStringList::Iterator it;
-
- QStringList list = dir.entryList( "opiemail-tmp-*" );
- do {
- unique.setNum( num++ );
- } while ( list.contains( "opiemail-tmp-" + unique ) > 0 );
-
- return "/tmp/opiemail-tmp-" + unique;
-}
-
-void MailWrapper::writeToFile( QString file, mailmime *mail )
-{
- FILE *f;
- int err, col = 0;
-
- f = fopen( file.latin1(), "w" );
- if ( f == NULL ) {
- qDebug( "writeToFile: error opening file" );
- return;
- }
-
- err = mailmime_write( f, &col, mail );
- if ( err != MAILIMF_NO_ERROR ) {
- fclose( f );
- qDebug( "writeToFile: error writing mailmime" );
- return;
- }
-
- fclose( f );
-}
-
-void MailWrapper::readFromFile( QString file, char **data, size_t *size )
-{
- char *buf;
- struct stat st;
- int fd, count = 0, total = 0;
-
- fd = open( file.latin1(), O_RDONLY, 0 );
- if ( fd == -1 ) return;
-
- if ( fstat( fd, &st ) != 0 ) goto err_close;
- if ( !st.st_size ) goto err_close;
-
- buf = (char *) malloc( st.st_size );
- if ( !buf ) goto err_close;
-
- while ( ( total < st.st_size ) && ( count >= 0 ) ) {
- count = read( fd, buf + total, st.st_size - total );
- total += count;
- }
- if ( count < 0 ) goto err_free;
-
- *data = buf;
- *size = st.st_size;
-
- close( fd );
-
- return; // Success :)
-
-err_free:
- free( buf );
-err_close:
- close( fd );
-}
-
-void progress( size_t current, size_t maximum )
-{
- qDebug( "Current: %i of %i", current, maximum );
-}
-
-void MailWrapper::smtpSend( mailmime *mail )
-{
- mailsmtp *session;
- clist *rcpts;
- char *from, *data, *server, *user = NULL, *pass = NULL;
- size_t size;
- int err;
- bool ssl;
- uint16_t port;
-
-
- from = getFrom( mail );
- SMTPaccount *smtp = getAccount( from );
- if ( smtp == NULL ) {
- free(from);
- return;
- }
- server = strdup( smtp->getServer().latin1() );
- ssl = smtp->getSSL();
- port = smtp->getPort().toUInt();
- rcpts = createRcptList( mail->mm_data.mm_message.mm_fields );
-
- QString file = getTmpFile();
- writeToFile( file, mail );
- readFromFile( file, &data, &size );
- QFile f( file );
- f.remove();
-
- session = mailsmtp_new( 20, &progress );
- if ( session == NULL ) goto free_mem;
-
- qDebug( "Servername %s at port %i", server, port );
- if ( ssl ) {
- qDebug( "SSL session" );
- err = mailsmtp_ssl_connect( session, server, port );
- } else {
- qDebug( "No SSL session" );
- err = mailsmtp_socket_connect( session, server, port );
- }
- if ( err != MAILSMTP_NO_ERROR ) goto free_mem_session;
-
- err = mailsmtp_init( session );
- if ( err != MAILSMTP_NO_ERROR ) goto free_con_session;
-
- qDebug( "INIT OK" );
-
- if ( smtp->getLogin() ) {
- if ( smtp->getUser().isEmpty() || smtp->getPassword().isEmpty() ) {
- // get'em
- LoginDialog login( smtp->getUser(), smtp->getPassword(), NULL, 0, true );
- login.show();
- if ( QDialog::Accepted == login.exec() ) {
- // ok
- user = strdup( login.getUser().latin1() );
- pass = strdup( login.getPassword().latin1() );
- } else {
- goto free_con_session;
- }
- } else {
- user = strdup( smtp->getUser().latin1() );
- pass = strdup( smtp->getPassword().latin1() );
- }
- qDebug( "session->auth: %i", session->auth);
- err = mailsmtp_auth( session, user, pass );
- if ( err == MAILSMTP_NO_ERROR ) qDebug("auth ok");
- qDebug( "Done auth!" );
- }
-
- err = mailsmtp_send( session, from, rcpts, data, size );
- if ( err != MAILSMTP_NO_ERROR ) goto free_con_session;
-
- qDebug( "Mail sent." );
-
-free_con_session:
- mailsmtp_quit( session );
-free_mem_session:
- mailsmtp_free( session );
-free_mem:
- smtp_address_list_free( rcpts );
- free( data );
- free( server );
- if ( smtp->getLogin() ) {
- free( user );
- free( pass );
- }
- free( from );
-}
-
-void MailWrapper::sendMail( Mail mail )
-{
- mailmime *mimeMail;
-
- mimeMail = createMimeMail( &mail );
- if ( mimeMail == NULL ) {
- qDebug( "sendMail: error creating mime mail" );
- } else {
- smtpSend( mimeMail );
- mailmime_free( mimeMail );
- }
-}
-
Mail::Mail()
:name(""), mail(""), to(""), cc(""), bcc(""), reply(""), subject(""), message("")
{
}
diff --git a/noncore/net/mail/mailwrapper.h b/noncore/net/mail/mailwrapper.h
index 02fe4b7..8fd886f 100644
--- a/noncore/net/mail/mailwrapper.h
+++ b/noncore/net/mail/mailwrapper.h
@@ -1,126 +1,91 @@
#ifndef MAILWRAPPER_H
#define MAILWRAPPER_H
#include <qpe/applnk.h>
-#include <libetpan/mailmime.h>
-#include <libetpan/mailimf.h>
-#include <libetpan/mailsmtp.h>
-#include <libetpan/mailstorage.h>
-#include <libetpan/maildriver.h>
#include <qbitarray.h>
#include <qdatetime.h>
#include "settings.h"
class Attachment
{
public:
Attachment( DocLnk lnk );
virtual ~Attachment(){}
const QString getFileName()const{ return doc.file(); }
const QString getName()const{ return doc.name(); }
const QString getMimeType()const{ return doc.type(); }
const QPixmap getPixmap()const{ return doc.pixmap(); }
const int getSize()const { return size; }
DocLnk getDocLnk() { return doc; }
protected:
DocLnk doc;
int size;
};
class Mail
{
public:
Mail();
/* Possible that this destructor must not be declared virtual
* 'cause it seems that it will never have some child classes.
* in this case this object will not get a virtual table -> memory and
* speed will be a little bit better?
*/
virtual ~Mail(){}
void addAttachment( Attachment *att ) { attList.append( att ); }
const QList<Attachment>& getAttachments()const { return attList; }
void removeAttachment( Attachment *att ) { attList.remove( att ); }
const QString&getName()const { return name; }
void setName( QString s ) { name = s; }
const QString&getMail()const{ return mail; }
void setMail( const QString&s ) { mail = s; }
const QString&getTo()const{ return to; }
void setTo( const QString&s ) { to = s; }
const QString&getCC()const{ return cc; }
void setCC( const QString&s ) { cc = s; }
const QString&getBCC()const { return bcc; }
void setBCC( const QString&s ) { bcc = s; }
const QString&getMessage()const { return message; }
void setMessage( const QString&s ) { message = s; }
const QString&getSubject()const { return subject; }
void setSubject( const QString&s ) { subject = s; }
const QString&getReply()const{ return reply; }
void setReply( const QString&a ) { reply = a; }
private:
QList<Attachment> attList;
QString name, mail, to, cc, bcc, reply, subject, message;
};
class Folder : public QObject
{
Q_OBJECT
public:
Folder( const QString&init_name,const QString&sep );
const QString&getDisplayName()const { return nameDisplay; }
const QString&getName()const { return name; }
virtual bool may_select()const{return true;};
const QString&Separator()const;
protected:
QString nameDisplay, name, separator;
};
class IMAPFolder : public Folder
{
public:
IMAPFolder(const QString&name, const QString&sep, bool select=true,const QString&prefix="" );
virtual bool may_select()const{return m_MaySelect;}
private:
static QString decodeFolderName( const QString &name );
bool m_MaySelect;
};
-class MailWrapper : public QObject
-{
- Q_OBJECT
-
-public:
- MailWrapper( Settings *s );
- void sendMail( Mail mail );
-
-private:
- mailimf_mailbox *newMailbox(const QString&name,const QString&mail );
- mailimf_address_list *parseAddresses(const QString&addr );
- mailimf_fields *createImfFields( Mail *mail );
- mailmime *buildTxtPart( QString str );
- mailmime *buildFilePart( QString filename, QString mimetype );
- void addFileParts( mailmime *message, QList<Attachment> files );
- mailmime *createMimeMail( Mail *mail );
- void smtpSend( mailmime *mail );
- mailimf_field *getField( mailimf_fields *fields, int type );
- clist *createRcptList( mailimf_fields *fields );
- char *getFrom( mailmime *mail );
- SMTPaccount *getAccount( QString from );
- void writeToFile( QString file, mailmime *mail );
- void readFromFile( QString file, char **data, size_t *size );
- static QString mailsmtpError( int err );
- static QString getTmpFile();
-
- Settings *settings;
-
-};
-
#endif
diff --git a/noncore/net/mail/pop3wrapper.h b/noncore/net/mail/pop3wrapper.h
index a31a145..75d70f8 100644
--- a/noncore/net/mail/pop3wrapper.h
+++ b/noncore/net/mail/pop3wrapper.h
@@ -1,63 +1,69 @@
#ifndef __POP3WRAPPER
#define __POP3WRAPPER
+#include <libetpan/clist.h>
#include "mailwrapper.h"
#include "abstractmail.h"
#include <qmap.h>
#include <qstring.h>
class RecMail;
class RecBody;
class encodedString;
struct mailpop3;
struct mailmessage;
struct mailmime;
struct mailmime_mechanism;
+struct mailimf_mailbox_list;
+struct mailimf_mailbox;
+struct mailimf_date_time;
+struct mailimf_group;
+struct mailimf_address_list;
class POP3wrapper : public AbstractMail
{
Q_OBJECT
public:
POP3wrapper( POP3account *a );
virtual ~POP3wrapper();
/* mailbox will be ignored */
virtual void listMessages(const QString & mailbox, QList<RecMail> &target );
virtual QList<Folder>* listFolders();
virtual QString fetchTextPart(const RecMail&mail,const RecPart&part);
virtual encodedString* fetchDecodedPart(const RecMail&mail,const RecPart&part);
virtual encodedString* fetchRawPart(const RecMail&mail,const RecPart&part);
virtual void deleteMail(const RecMail&mail);
virtual void answeredMail(const RecMail&mail);
RecBody fetchBody( const RecMail &mail );
static void pop3_progress( size_t current, size_t maximum );
protected:
void login();
void logout();
RecMail *parseHeader( const char *header );
RecBody parseMail( char *message );
QString parseMailboxList( mailimf_mailbox_list *list );
QString parseMailbox( mailimf_mailbox *box );
QString parseGroup( mailimf_group *group );
QString parseAddressList( mailimf_address_list *list );
QString parseDateTime( mailimf_date_time *date );
void cleanUpCache();
void traverseBody(RecBody&target,mailmessage*message,mailmime*mime,unsigned int current_rek=0);
static void fillSingleBody(RecPart&target,mailmessage*message,mailmime*mime);
static void fillParameters(RecPart&target,clist*parameters);
static QString POP3wrapper::getencoding(mailmime_mechanism*aEnc);
POP3account *account;
mailpop3 *m_pop3;
QString msgTempName;
unsigned int last_msg_id;
QMap<QString,encodedString*> bodyCache;
};
#endif
diff --git a/noncore/net/mail/smtpwrapper.cpp b/noncore/net/mail/smtpwrapper.cpp
new file mode 100644
index 0000000..162b1b9
--- a/dev/null
+++ b/noncore/net/mail/smtpwrapper.cpp
@@ -0,0 +1,604 @@
+#include <stdlib.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <string.h>
+#include <qdir.h>
+
+#include <libetpan/mailmime.h>
+#include <libetpan/mailimf.h>
+#include <libetpan/mailsmtp.h>
+#include <libetpan/mailstorage.h>
+#include <libetpan/maildriver.h>
+
+#include "smtpwrapper.h"
+#include "mailwrapper.h"
+#include "logindialog.h"
+#include "defines.h"
+
+SMTPwrapper::SMTPwrapper( Settings *s )
+ : QObject()
+{
+ settings = s;
+}
+
+QString SMTPwrapper::mailsmtpError( int errnum )
+{
+ switch ( errnum ) {
+ case MAILSMTP_NO_ERROR:
+ return tr( "No error" );
+ case MAILSMTP_ERROR_UNEXPECTED_CODE:
+ return tr( "Unexpected error code" );
+ case MAILSMTP_ERROR_SERVICE_NOT_AVAILABLE:
+ return tr( "Service not available" );
+ case MAILSMTP_ERROR_STREAM:
+ return tr( "Stream error" );
+ case MAILSMTP_ERROR_HOSTNAME:
+ return tr( "gethostname() failed" );
+ case MAILSMTP_ERROR_NOT_IMPLEMENTED:
+ return tr( "Not implemented" );
+ case MAILSMTP_ERROR_ACTION_NOT_TAKEN:
+ return tr( "Error, action not taken" );
+ case MAILSMTP_ERROR_EXCEED_STORAGE_ALLOCATION:
+ return tr( "Data exceeds storage allocation" );
+ case MAILSMTP_ERROR_IN_PROCESSING:
+ return tr( "Error in processing" );
+ // case MAILSMTP_ERROR_INSUFFISANT_SYSTEM_STORAGE:
+ // return tr( "Insufficient system storage" );
+ case MAILSMTP_ERROR_MAILBOX_UNAVAILABLE:
+ return tr( "Mailbox unavailable" );
+ case MAILSMTP_ERROR_MAILBOX_NAME_NOT_ALLOWED:
+ return tr( "Mailbox name not allowed" );
+ case MAILSMTP_ERROR_BAD_SEQUENCE_OF_COMMAND:
+ return tr( "Bad command sequence" );
+ case MAILSMTP_ERROR_USER_NOT_LOCAL:
+ return tr( "User not local" );
+ case MAILSMTP_ERROR_TRANSACTION_FAILED:
+ return tr( "Transaction failed" );
+ case MAILSMTP_ERROR_MEMORY:
+ return tr( "Memory error" );
+ case MAILSMTP_ERROR_CONNECTION_REFUSED:
+ return tr( "Connection refused" );
+ default:
+ return tr( "Unknown error code" );
+ }
+}
+
+mailimf_mailbox *SMTPwrapper::newMailbox(const QString&name, const QString&mail )
+{
+ return mailimf_mailbox_new( strdup( name.latin1() ),
+ strdup( mail.latin1() ) );
+}
+
+mailimf_address_list *SMTPwrapper::parseAddresses(const QString&addr )
+{
+ mailimf_address_list *addresses;
+
+ if ( addr.isEmpty() ) return NULL;
+
+ addresses = mailimf_address_list_new_empty();
+
+ QStringList list = QStringList::split( ',', addr );
+ QStringList::Iterator it;
+ for ( it = list.begin(); it != list.end(); it++ ) {
+ char *str = strdup( (*it).latin1() );
+ int err = mailimf_address_list_add_parse( addresses, str );
+ if ( err != MAILIMF_NO_ERROR ) {
+ qDebug( "Error parsing" );
+ qDebug( *it );
+ free( str );
+ } else {
+ qDebug( "Parse success! :)" );
+ }
+ }
+
+ return addresses;
+}
+
+mailimf_fields *SMTPwrapper::createImfFields(const Mail&mail )
+{
+ mailimf_fields *fields;
+ mailimf_field *xmailer;
+ mailimf_mailbox *sender, *fromBox;
+ mailimf_mailbox_list *from;
+ mailimf_address_list *to, *cc, *bcc, *reply;
+ char *subject = strdup( mail.getSubject().latin1() );
+ int err;
+
+ sender = newMailbox( mail.getName(), mail.getMail() );
+ if ( sender == NULL ) goto err_free;
+
+ fromBox = newMailbox( mail.getName(), mail.getMail() );
+ if ( fromBox == NULL ) goto err_free_sender;
+
+ from = mailimf_mailbox_list_new_empty();
+ if ( from == NULL ) goto err_free_fromBox;
+
+ err = mailimf_mailbox_list_add( from, fromBox );
+ if ( err != MAILIMF_NO_ERROR ) goto err_free_from;
+
+ to = parseAddresses( mail.getTo() );
+ if ( to == NULL ) goto err_free_from;
+
+ cc = parseAddresses( mail.getCC() );
+ bcc = parseAddresses( mail.getBCC() );
+ reply = parseAddresses( mail.getReply() );
+
+ fields = mailimf_fields_new_with_data( from, sender, reply, to, cc, bcc,
+ NULL, NULL, subject );
+ if ( fields == NULL ) goto err_free_reply;
+
+ xmailer = mailimf_field_new_custom( strdup( "User-Agent" ),
+ strdup( USER_AGENT ) );
+ if ( xmailer == NULL ) goto err_free_fields;
+
+ err = mailimf_fields_add( fields, xmailer );
+ if ( err != MAILIMF_NO_ERROR ) goto err_free_xmailer;
+
+ return fields; // Success :)
+
+err_free_xmailer:
+ mailimf_field_free( xmailer );
+err_free_fields:
+ mailimf_fields_free( fields );
+err_free_reply:
+ mailimf_address_list_free( reply );
+ mailimf_address_list_free( bcc );
+ mailimf_address_list_free( cc );
+ mailimf_address_list_free( to );
+err_free_from:
+ mailimf_mailbox_list_free( from );
+err_free_fromBox:
+ mailimf_mailbox_free( fromBox );
+err_free_sender:
+ mailimf_mailbox_free( sender );
+err_free:
+ free( subject );
+ qDebug( "createImfFields - error" );
+
+ return NULL; // Error :(
+}
+
+mailmime *SMTPwrapper::buildTxtPart(const QString&str )
+{
+ mailmime *txtPart;
+ mailmime_fields *fields;
+ mailmime_content *content;
+ mailmime_parameter *param;
+ char *txt = strdup( str.latin1() );
+ int err;
+
+ param = mailmime_parameter_new( strdup( "charset" ),
+ strdup( "iso-8859-1" ) );
+ if ( param == NULL ) goto err_free;
+
+ content = mailmime_content_new_with_str( "text/plain" );
+ if ( content == NULL ) goto err_free_param;
+
+ err = clist_append( content->ct_parameters, param );
+ if ( err != MAILIMF_NO_ERROR ) goto err_free_content;
+
+ fields = mailmime_fields_new_encoding( MAILMIME_MECHANISM_8BIT );
+ if ( fields == NULL ) goto err_free_content;
+
+ txtPart = mailmime_new_empty( content, fields );
+ if ( txtPart == NULL ) goto err_free_fields;
+
+ err = mailmime_set_body_text( txtPart, txt, strlen( txt ) );
+ if ( err != MAILIMF_NO_ERROR ) goto err_free_txtPart;
+
+ return txtPart; // Success :)
+
+err_free_txtPart:
+ mailmime_free( txtPart );
+err_free_fields:
+ mailmime_fields_free( fields );
+err_free_content:
+ mailmime_content_free( content );
+err_free_param:
+ mailmime_parameter_free( param );
+err_free:
+ free( txt );
+ qDebug( "buildTxtPart - error" );
+
+ return NULL; // Error :(
+}
+
+mailmime *SMTPwrapper::buildFilePart(const QString&filename,const QString&mimetype )
+{
+ mailmime * filePart;
+ mailmime_fields * fields;
+ mailmime_content * content;
+ mailmime_parameter * param = NULL;
+ int err;
+
+ int pos = filename.findRev( '/' );
+ QString tmp = filename.right( filename.length() - ( pos + 1 ) );
+ char *name = strdup( tmp.latin1() ); // just filename
+ char *file = strdup( filename.latin1() ); // full name with path
+ char *mime = strdup( mimetype.latin1() ); // mimetype -e.g. text/plain
+
+ fields = mailmime_fields_new_filename(
+ MAILMIME_DISPOSITION_TYPE_ATTACHMENT, name,
+ MAILMIME_MECHANISM_BASE64 );
+ if ( fields == NULL ) goto err_free;
+
+ content = mailmime_content_new_with_str( mime );
+ if ( content == NULL ) goto err_free_fields;
+
+ if ( mimetype.compare( "text/plain" ) == 0 ) {
+ param = mailmime_parameter_new( strdup( "charset" ),
+ strdup( "iso-8859-1" ) );
+ if ( param == NULL ) goto err_free_content;
+
+ err = clist_append( content->ct_parameters, param );
+ if ( err != MAILIMF_NO_ERROR ) goto err_free_param;
+ }
+
+ filePart = mailmime_new_empty( content, fields );
+ if ( filePart == NULL ) goto err_free_param;
+
+ err = mailmime_set_body_file( filePart, file );
+ if ( err != MAILIMF_NO_ERROR ) goto err_free_filePart;
+
+ return filePart; // Success :)
+
+err_free_filePart:
+ mailmime_free( filePart );
+err_free_param:
+ if ( param != NULL ) mailmime_parameter_free( param );
+err_free_content:
+ mailmime_content_free( content );
+err_free_fields:
+ mailmime_fields_free( fields );
+err_free:
+ free( name );
+ free( mime );
+ free( file );
+ qDebug( "buildFilePart - error" );
+
+ return NULL; // Error :(
+}
+
+void SMTPwrapper::addFileParts( mailmime *message,const QList<Attachment>&files )
+{
+ const Attachment *it;
+ /* work around for the brainfucked qlist which can not act with const values */
+ for ( it = ((QList<Attachment>)files).first(); it; it = ((QList<Attachment>)files).next() ) {
+ qDebug( "Adding file" );
+ mailmime *filePart;
+ int err;
+
+ filePart = buildFilePart( it->getFileName(), it->getMimeType() );
+ if ( filePart == NULL ) goto err_free;
+
+ err = mailmime_smart_add_part( message, filePart );
+ if ( err != MAILIMF_NO_ERROR ) goto err_free_filePart;
+
+ continue; // Success :)
+
+ err_free_filePart:
+ mailmime_free( filePart );
+ err_free:
+ qDebug( "addFileParts: error adding file:" );
+ qDebug( it->getFileName() );
+ }
+}
+
+mailmime *SMTPwrapper::createMimeMail(const Mail &mail )
+{
+ mailmime *message, *txtPart;
+ mailimf_fields *fields;
+ int err;
+
+ fields = createImfFields( mail );
+ if ( fields == NULL ) goto err_free;
+
+ message = mailmime_new_message_data( NULL );
+ if ( message == NULL ) goto err_free_fields;
+
+ mailmime_set_imf_fields( message, fields );
+
+ txtPart = buildTxtPart( mail.getMessage() );
+ if ( txtPart == NULL ) goto err_free_message;
+
+ err = mailmime_smart_add_part( message, txtPart );
+ if ( err != MAILIMF_NO_ERROR ) goto err_free_txtPart;
+
+ addFileParts( message, mail.getAttachments() );
+
+ return message; // Success :)
+
+err_free_txtPart:
+ mailmime_free( txtPart );
+err_free_message:
+ mailmime_free( message );
+err_free_fields:
+ mailimf_fields_free( fields );
+err_free:
+ qDebug( "createMimeMail: error" );
+
+ return NULL; // Error :(
+}
+
+mailimf_field *SMTPwrapper::getField( mailimf_fields *fields, int type )
+{
+ mailimf_field *field;
+ clistiter *it;
+
+ it = clist_begin( fields->fld_list );
+ while ( it ) {
+ field = (mailimf_field *) it->data;
+ if ( field->fld_type == type ) {
+ return field;
+ }
+ it = it->next;
+ }
+
+ return NULL;
+}
+
+void SMTPwrapper::addRcpts( clist *list, mailimf_address_list *addr_list )
+{
+ clistiter *it, *it2;
+
+ for ( it = clist_begin( addr_list->ad_list ); it; it = it->next ) {
+ mailimf_address *addr;
+ addr = (mailimf_address *) it->data;
+
+ if ( addr->ad_type == MAILIMF_ADDRESS_MAILBOX ) {
+ esmtp_address_list_add( list, addr->ad_data.ad_mailbox->mb_addr_spec, 0, NULL );
+ } else if ( addr->ad_type == MAILIMF_ADDRESS_GROUP ) {
+ clist *l = addr->ad_data.ad_group->grp_mb_list->mb_list;
+ for ( it2 = clist_begin( l ); it2; it2 = it2->next ) {
+ mailimf_mailbox *mbox;
+ mbox = (mailimf_mailbox *) it2->data;
+ esmtp_address_list_add( list, mbox->mb_addr_spec, 0, NULL );
+ }
+ }
+ }
+}
+
+clist *SMTPwrapper::createRcptList( mailimf_fields *fields )
+{
+ clist *rcptList;
+ mailimf_field *field;
+
+ rcptList = esmtp_address_list_new();
+
+ field = getField( fields, MAILIMF_FIELD_TO );
+ if ( field && (field->fld_type == MAILIMF_FIELD_TO)
+ && field->fld_data.fld_to->to_addr_list ) {
+ addRcpts( rcptList, field->fld_data.fld_to->to_addr_list );
+ }
+
+ field = getField( fields, MAILIMF_FIELD_CC );
+ if ( field && (field->fld_type == MAILIMF_FIELD_CC)
+ && field->fld_data.fld_cc->cc_addr_list ) {
+ addRcpts( rcptList, field->fld_data.fld_cc->cc_addr_list );
+ }
+
+ field = getField( fields, MAILIMF_FIELD_BCC );
+ if ( field && (field->fld_type == MAILIMF_FIELD_BCC)
+ && field->fld_data.fld_bcc->bcc_addr_list ) {
+ addRcpts( rcptList, field->fld_data.fld_bcc->bcc_addr_list );
+ }
+
+ return rcptList;
+}
+
+char *SMTPwrapper::getFrom( mailmime *mail )
+{
+ char *from = NULL;
+
+ mailimf_field *ffrom;
+ ffrom = getField( mail->mm_data.mm_message.mm_fields, MAILIMF_FIELD_FROM );
+ if ( ffrom && (ffrom->fld_type == MAILIMF_FIELD_FROM)
+ && ffrom->fld_data.fld_from->frm_mb_list && ffrom->fld_data.fld_from->frm_mb_list->mb_list ) {
+ clist *cl = ffrom->fld_data.fld_from->frm_mb_list->mb_list;
+ clistiter *it;
+ for ( it = clist_begin( cl ); it; it = it->next ) {
+ mailimf_mailbox *mb = (mailimf_mailbox *) it->data;
+ from = strdup( mb->mb_addr_spec );
+ }
+ }
+
+ return from;
+}
+
+SMTPaccount *SMTPwrapper::getAccount(const QString&from )
+{
+ SMTPaccount *smtp;
+
+ QList<Account> list = settings->getAccounts();
+ Account *it;
+ for ( it = list.first(); it; it = list.next() ) {
+ if ( it->getType().compare( "SMTP" ) == 0 ) {
+ smtp = static_cast<SMTPaccount *>(it);
+ if ( smtp->getMail().compare( from ) == 0 ) {
+ qDebug( "SMTPaccount found for" );
+ qDebug( from );
+ return smtp;
+ }
+ }
+ }
+
+ return NULL;
+}
+
+QString SMTPwrapper::getTmpFile() {
+ int num = 0;
+ QString unique;
+
+ QDir dir( "/tmp" );
+ QStringList::Iterator it;
+
+ QStringList list = dir.entryList( "opiemail-tmp-*" );
+ do {
+ unique.setNum( num++ );
+ } while ( list.contains( "opiemail-tmp-" + unique ) > 0 );
+
+ return "/tmp/opiemail-tmp-" + unique;
+}
+
+void SMTPwrapper::writeToFile(const QString&file, mailmime *mail )
+{
+ FILE *f;
+ int err, col = 0;
+
+ f = fopen( file.latin1(), "w" );
+ if ( f == NULL ) {
+ qDebug( "writeToFile: error opening file" );
+ return;
+ }
+
+ err = mailmime_write( f, &col, mail );
+ if ( err != MAILIMF_NO_ERROR ) {
+ fclose( f );
+ qDebug( "writeToFile: error writing mailmime" );
+ return;
+ }
+
+ fclose( f );
+}
+
+void SMTPwrapper::readFromFile(const QString&file, char **data, size_t *size )
+{
+ char *buf;
+ struct stat st;
+ int fd, count = 0, total = 0;
+
+ fd = open( file.latin1(), O_RDONLY, 0 );
+ if ( fd == -1 ) return;
+
+ if ( fstat( fd, &st ) != 0 ) goto err_close;
+ if ( !st.st_size ) goto err_close;
+
+ buf = (char *) malloc( st.st_size );
+ if ( !buf ) goto err_close;
+
+ while ( ( total < st.st_size ) && ( count >= 0 ) ) {
+ count = read( fd, buf + total, st.st_size - total );
+ total += count;
+ }
+ if ( count < 0 ) goto err_free;
+
+ *data = buf;
+ *size = st.st_size;
+
+ close( fd );
+
+ return; // Success :)
+
+err_free:
+ free( buf );
+err_close:
+ close( fd );
+}
+
+void SMTPwrapper::progress( size_t current, size_t maximum )
+{
+ qDebug( "Current: %i of %i", current, maximum );
+}
+
+void SMTPwrapper::smtpSend( mailmime *mail )
+{
+ mailsmtp *session;
+ clist *rcpts;
+ char *from, *data, *server, *user = NULL, *pass = NULL;
+ size_t size;
+ int err;
+ bool ssl;
+ uint16_t port;
+
+
+ from = getFrom( mail );
+ SMTPaccount *smtp = getAccount( from );
+ if ( smtp == NULL ) {
+ free(from);
+ return;
+ }
+ server = strdup( smtp->getServer().latin1() );
+ ssl = smtp->getSSL();
+ port = smtp->getPort().toUInt();
+ rcpts = createRcptList( mail->mm_data.mm_message.mm_fields );
+
+ QString file = getTmpFile();
+ writeToFile( file, mail );
+ readFromFile( file, &data, &size );
+ QFile f( file );
+ f.remove();
+
+ session = mailsmtp_new( 20, &progress );
+ if ( session == NULL ) goto free_mem;
+
+ qDebug( "Servername %s at port %i", server, port );
+ if ( ssl ) {
+ qDebug( "SSL session" );
+ err = mailsmtp_ssl_connect( session, server, port );
+ } else {
+ qDebug( "No SSL session" );
+ err = mailsmtp_socket_connect( session, server, port );
+ }
+ if ( err != MAILSMTP_NO_ERROR ) goto free_mem_session;
+
+ err = mailsmtp_init( session );
+ if ( err != MAILSMTP_NO_ERROR ) goto free_con_session;
+
+ qDebug( "INIT OK" );
+
+ if ( smtp->getLogin() ) {
+ if ( smtp->getUser().isEmpty() || smtp->getPassword().isEmpty() ) {
+ // get'em
+ LoginDialog login( smtp->getUser(), smtp->getPassword(), NULL, 0, true );
+ login.show();
+ if ( QDialog::Accepted == login.exec() ) {
+ // ok
+ user = strdup( login.getUser().latin1() );
+ pass = strdup( login.getPassword().latin1() );
+ } else {
+ goto free_con_session;
+ }
+ } else {
+ user = strdup( smtp->getUser().latin1() );
+ pass = strdup( smtp->getPassword().latin1() );
+ }
+ qDebug( "session->auth: %i", session->auth);
+ err = mailsmtp_auth( session, user, pass );
+ if ( err == MAILSMTP_NO_ERROR ) qDebug("auth ok");
+ qDebug( "Done auth!" );
+ }
+
+ err = mailsmtp_send( session, from, rcpts, data, size );
+ if ( err != MAILSMTP_NO_ERROR ) goto free_con_session;
+
+ qDebug( "Mail sent." );
+
+free_con_session:
+ mailsmtp_quit( session );
+free_mem_session:
+ mailsmtp_free( session );
+free_mem:
+ smtp_address_list_free( rcpts );
+ free( data );
+ free( server );
+ if ( smtp->getLogin() ) {
+ free( user );
+ free( pass );
+ }
+ free( from );
+}
+
+void SMTPwrapper::sendMail(const Mail&mail )
+{
+ mailmime *mimeMail;
+
+ mimeMail = createMimeMail(mail );
+ if ( mimeMail == NULL ) {
+ qDebug( "sendMail: error creating mime mail" );
+ } else {
+ smtpSend( mimeMail );
+ mailmime_free( mimeMail );
+ }
+}
diff --git a/noncore/net/mail/smtpwrapper.h b/noncore/net/mail/smtpwrapper.h
new file mode 100644
index 0000000..8fdb07d
--- a/dev/null
+++ b/noncore/net/mail/smtpwrapper.h
@@ -0,0 +1,53 @@
+#ifndef SMTPwrapper_H
+#define SMTPwrapper_H
+
+#include <qpe/applnk.h>
+
+#include <qbitarray.h>
+#include <qdatetime.h>
+#include <libetpan/clist.h>
+
+#include "settings.h"
+
+class Mail;
+class Attachment;
+struct mailimf_fields;
+struct mailimf_field;
+struct mailimf_mailbox;
+struct mailmime;
+struct mailimf_address_list;
+
+class SMTPwrapper : public QObject
+{
+ Q_OBJECT
+
+public:
+ SMTPwrapper( Settings *s );
+ virtual ~SMTPwrapper(){}
+ void sendMail(const Mail& mail );
+
+protected:
+ mailimf_mailbox *newMailbox(const QString&name,const QString&mail );
+ mailimf_fields *createImfFields(const Mail &mail );
+ mailmime *createMimeMail(const Mail&mail );
+
+ mailimf_address_list *parseAddresses(const QString&addr );
+ void addFileParts( mailmime *message,const QList<Attachment>&files );
+ mailmime *buildTxtPart(const QString&str );
+ mailmime *buildFilePart(const QString&filename,const QString&mimetype );
+ void smtpSend( mailmime *mail );
+ mailimf_field *getField( mailimf_fields *fields, int type );
+ clist *createRcptList( mailimf_fields *fields );
+ char *getFrom( mailmime *mail );
+ SMTPaccount *getAccount(const QString&from );
+ void writeToFile(const QString&file, mailmime *mail );
+ void readFromFile(const QString&file, char **data, size_t *size );
+
+ static QString mailsmtpError( int err );
+ static QString getTmpFile();
+ static void progress( size_t current, size_t maximum );
+ static void addRcpts( clist *list, mailimf_address_list *addr_list );
+ Settings *settings;
+};
+
+#endif