summaryrefslogtreecommitdiff
Side-by-side diff
Diffstat (more/less context) (show 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,820 +1,821 @@
#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) {
switch (cflag->fl_flag->fl_type) {
case MAILIMAP_FLAG_ANSWERED: /* \Answered flag */
mFlags.setBit(FLAG_ANSWERED);
break;
case MAILIMAP_FLAG_FLAGGED: /* \Flagged flag */
mFlags.setBit(FLAG_FLAGGED);
break;
case MAILIMAP_FLAG_DELETED: /* \Deleted flag */
mFlags.setBit(FLAG_DELETED);
break;
case MAILIMAP_FLAG_SEEN: /* \Seen flag */
mFlags.setBit(FLAG_SEEN);
break;
case MAILIMAP_FLAG_DRAFT: /* \Draft flag */
mFlags.setBit(FLAG_DRAFT);
break;
case MAILIMAP_FLAG_KEYWORD: /* keyword flag */
break;
case MAILIMAP_FLAG_EXTENSION: /* \extension flag */
break;
default:
break;
}
} else if (cflag->fl_type==MAILIMAP_FLAG_FETCH_RECENT) {
mFlags.setBit(FLAG_RECENT);
}
}
continue;
}
if (item->att_data.att_static->att_type==MAILIMAP_MSG_ATT_ENVELOPE) {
mailimap_envelope * head = item->att_data.att_static->att_data.att_env;
m->setDate(head->env_date);
m->setSubject(convert_String((const char*)head->env_subject));
//m->setSubject(head->env_subject);
if (head->env_from!=NULL) {
addresslist = address_list_to_stringlist(head->env_from->frm_list);
if (addresslist.count()) {
m->setFrom(addresslist.first());
}
}
if (head->env_to!=NULL) {
addresslist = address_list_to_stringlist(head->env_to->to_list);
m->setTo(addresslist);
}
if (head->env_cc!=NULL) {
addresslist = address_list_to_stringlist(head->env_cc->cc_list);
m->setCC(addresslist);
}
if (head->env_bcc!=NULL) {
addresslist = address_list_to_stringlist(head->env_bcc->bcc_list);
m->setBcc(addresslist);
}
if (head->env_reply_to!=NULL) {
addresslist = address_list_to_stringlist(head->env_reply_to->rt_list);
if (addresslist.count()) {
m->setReplyto(addresslist.first());
}
}
m->setMsgid(QString(head->env_message_id));
} else if (item->att_data.att_static->att_type==MAILIMAP_MSG_ATT_INTERNALDATE) {
#if 0
mailimap_date_time*d = item->att_data.att_static->att_data.att_internal_date;
QDateTime da(QDate(d->dt_year,d->dt_month,d->dt_day),QTime(d->dt_hour,d->dt_min,d->dt_sec));
qDebug("%i %i %i - %i %i %i",d->dt_year,d->dt_month,d->dt_day,d->dt_hour,d->dt_min,d->dt_sec);
qDebug(da.toString());
#endif
} else if (item->att_data.att_static->att_type==MAILIMAP_MSG_ATT_RFC822_SIZE) {
size = item->att_data.att_static->att_data.att_rfc822_size;
}
}
/* msg is already deleted */
if (mFlags.testBit(FLAG_DELETED) && m) {
delete m;
m = 0;
}
if (m) {
m->setFlags(mFlags);
m->setMsgsize(size);
}
return m;
}
RecBody IMAPwrapper::fetchBody(const RecMail&mail)
{
RecBody body;
const char *mb;
int err = MAILIMAP_NO_ERROR;
clist *result;
clistcell *current;
mailimap_fetch_att *fetchAtt;
mailimap_fetch_type *fetchType;
mailimap_set *set;
mailimap_body*body_desc;
mb = mail.getMbox().latin1();
login();
if (!m_imap) {
return body;
}
err = mailimap_select( m_imap, (char*)mb);
if ( err != MAILIMAP_NO_ERROR ) {
qDebug("error selecting mailbox: %s",m_imap->imap_response);
return body;
}
result = clist_new();
/* the range has to start at 1!!! not with 0!!!! */
set = mailimap_set_new_interval( mail.getNumber(),mail.getNumber() );
fetchAtt = mailimap_fetch_att_new_bodystructure();
fetchType = mailimap_fetch_type_new_fetch_att(fetchAtt);
err = mailimap_fetch( m_imap, set, fetchType, &result );
mailimap_set_free( set );
mailimap_fetch_type_free( fetchType );
if (err == MAILIMAP_NO_ERROR && (current=clist_begin(result)) ) {
mailimap_msg_att * msg_att;
msg_att = (mailimap_msg_att*)current->data;
mailimap_msg_att_item*item = (mailimap_msg_att_item*)msg_att->att_list->first->data;
body_desc = item->att_data.att_static->att_data.att_body;
if (body_desc->bd_type==MAILIMAP_BODY_1PART) {
searchBodyText(mail,body_desc->bd_data.bd_body_1part,body);
} else if (body_desc->bd_type==MAILIMAP_BODY_MPART) {
qDebug("Mulitpart mail");
searchBodyText(mail,body_desc->bd_data.bd_body_mpart,body);
}
} else {
qDebug("error fetching body: %s",m_imap->imap_response);
}
mailimap_fetch_list_free(result);
return body;
}
/* this routine is just called when the mail has only ONE part.
for filling the parts of a multi-part-message there are other
routines 'cause we can not simply fetch the whole body. */
void IMAPwrapper::searchBodyText(const RecMail&mail,mailimap_body_type_1part*mailDescription,RecBody&target_body)
{
if (!mailDescription) {
return;
}
QString sub,body_text;
RecPart singlePart;
QValueList<int> path;
fillSinglePart(singlePart,mailDescription);
switch (mailDescription->bd_type) {
case MAILIMAP_BODY_TYPE_1PART_MSG:
path.append(1);
body_text = fetchTextPart(mail,path,true,singlePart.Encoding());
target_body.setBodytext(body_text);
target_body.setDescription(singlePart);
break;
case MAILIMAP_BODY_TYPE_1PART_TEXT:
qDebug("Mediatype single: %s",mailDescription->bd_data.bd_type_text->bd_media_text);
path.append(1);
body_text = fetchTextPart(mail,path,true,singlePart.Encoding());
target_body.setBodytext(body_text);
target_body.setDescription(singlePart);
break;
case MAILIMAP_BODY_TYPE_1PART_BASIC:
qDebug("Single attachment");
target_body.setBodytext("");
target_body.addPart(singlePart);
break;
default:
break;
}
return;
}
QStringList IMAPwrapper::address_list_to_stringlist(clist*list)
{
QStringList l;
QString from;
bool named_from;
clistcell *current = NULL;
mailimap_address * current_address=NULL;
if (!list) {
return l;
}
unsigned int count = 0;
for (current=clist_begin(list);current!= NULL;current=clist_next(current)) {
from = "";
named_from = false;
current_address=(mailimap_address*)current->data;
if (current_address->ad_personal_name){
from+=convert_String((const char*)current_address->ad_personal_name);
//from+=QString(current_address->ad_personal_name);
from+=" ";
named_from = true;
}
if (named_from && (current_address->ad_mailbox_name || current_address->ad_host_name)) {
from+="<";
}
if (current_address->ad_mailbox_name) {
from+=QString(current_address->ad_mailbox_name);
from+="@";
}
if (current_address->ad_host_name) {
from+=QString(current_address->ad_host_name);
}
if (named_from && (current_address->ad_mailbox_name || current_address->ad_host_name)) {
from+=">";
}
l.append(QString(from));
if (++count > 99) {
break;
}
}
return l;
}
encodedString*IMAPwrapper::fetchRawPart(const RecMail&mail,const QValueList<int>&path,bool internal_call)
{
encodedString*res=new encodedString;
const char*mb;
int err;
mailimap_fetch_type *fetchType;
mailimap_set *set;
clistcell*current,*cur;
login();
if (!m_imap) {
return res;
}
if (!internal_call) {
mb = mail.getMbox().latin1();
err = mailimap_select( m_imap, (char*)mb);
if ( err != MAILIMAP_NO_ERROR ) {
qDebug("error selecting mailbox: %s",m_imap->imap_response);
return res;
}
}
set = mailimap_set_new_single(mail.getNumber());
clist*id_list=clist_new();
for (unsigned j=0; j < path.count();++j) {
uint32_t * p_id = (uint32_t *)malloc(sizeof(*p_id));
*p_id = path[j];
clist_append(id_list,p_id);
}
mailimap_section_part * section_part = mailimap_section_part_new(id_list);
mailimap_section_spec * section_spec = mailimap_section_spec_new(MAILIMAP_SECTION_SPEC_SECTION_PART, NULL, section_part, NULL);
mailimap_section * section = mailimap_section_new(section_spec);
mailimap_fetch_att * fetch_att = mailimap_fetch_att_new_body_section(section);
fetchType = mailimap_fetch_type_new_fetch_att(fetch_att);
clist*result = clist_new();
err = mailimap_fetch( m_imap, set, fetchType, &result );
mailimap_set_free( set );
mailimap_fetch_type_free( fetchType );
if (err == MAILIMAP_NO_ERROR && (current=clist_begin(result)) ) {
mailimap_msg_att * msg_att;
msg_att = (mailimap_msg_att*)current->data;
mailimap_msg_att_item*msg_att_item;
for(cur = clist_begin(msg_att->att_list) ; cur != NULL ; cur = clist_next(cur)) {
msg_att_item = (mailimap_msg_att_item*)clist_content(cur);
if (msg_att_item->att_type == MAILIMAP_MSG_ATT_ITEM_STATIC) {
if (msg_att_item->att_data.att_static->att_type == MAILIMAP_MSG_ATT_BODY_SECTION) {
char*text = msg_att_item->att_data.att_static->att_data.att_body_section->sec_body_part;
/* detach - we take over the content */
msg_att_item->att_data.att_static->att_data.att_body_section->sec_body_part = 0L;
res->setContent(text,msg_att_item->att_data.att_static->att_data.att_body_section->sec_length);
}
}
}
} else {
qDebug("error fetching text: %s",m_imap->imap_response);
}
mailimap_fetch_list_free(result);
return res;
}
void IMAPwrapper::searchBodyText(const RecMail&mail,mailimap_body_type_mpart*mailDescription,RecBody&target_body,int current_recursion,QValueList<int>recList)
{
/* current_recursion is for avoiding ugly mails which has a to deep body-structure */
if (!mailDescription||current_recursion==10) {
return;
}
clistcell*current;
mailimap_body*current_body;
unsigned int count = 0;
for (current=clist_begin(mailDescription->bd_list);current!=0;current=clist_next(current)) {
/* the point in the message */
++count;
current_body = (mailimap_body*)current->data;
if (current_body->bd_type==MAILIMAP_BODY_MPART) {
QValueList<int>clist = recList;
clist.append(count);
searchBodyText(mail,current_body->bd_data.bd_body_mpart,target_body,current_recursion+1,clist);
} else if (current_body->bd_type==MAILIMAP_BODY_1PART){
RecPart currentPart;
fillSinglePart(currentPart,current_body->bd_data.bd_body_1part);
QValueList<int>clist = recList;
clist.append(count);
/* important: Check for is NULL 'cause a body can be empty! */
if (currentPart.Type()=="text" && target_body.Bodytext().isNull() ) {
QString body_text = fetchTextPart(mail,clist,true,currentPart.Encoding());
target_body.setDescription(currentPart);
target_body.setBodytext(body_text);
} else {
QString id("");
for (unsigned int j = 0; j < clist.count();++j) {
id+=(j>0?" ":"");
id+=QString("%1").arg(clist[j]);
}
qDebug("ID= %s",id.latin1());
currentPart.setIdentifier(id);
currentPart.setPositionlist(clist);
target_body.addPart(currentPart);
}
}
}
}
void IMAPwrapper::fillSinglePart(RecPart&target_part,mailimap_body_type_1part*Description)
{
if (!Description) {
return;
}
switch (Description->bd_type) {
case MAILIMAP_BODY_TYPE_1PART_TEXT:
target_part.setType("text");
fillSingleTextPart(target_part,Description->bd_data.bd_type_text);
break;
case MAILIMAP_BODY_TYPE_1PART_BASIC:
fillSingleBasicPart(target_part,Description->bd_data.bd_type_basic);
break;
case MAILIMAP_BODY_TYPE_1PART_MSG:
fillSingleMsgPart(target_part,Description->bd_data.bd_type_msg);
break;
default:
break;
}
}
void IMAPwrapper::fillSingleTextPart(RecPart&target_part,mailimap_body_type_text*which)
{
if (!which) {
return;
}
QString sub;
sub = which->bd_media_text;
target_part.setSubtype(sub.lower());
target_part.setLines(which->bd_lines);
fillBodyFields(target_part,which->bd_fields);
}
void IMAPwrapper::fillSingleMsgPart(RecPart&target_part,mailimap_body_type_msg*which)
{
if (!which) {
return;
}
// QString sub;
// sub = which->bd_media_text;
// target_part.setSubtype(sub.lower());
qDebug("Message part");
/* we set this type to text/plain */
target_part.setType("text");
target_part.setSubtype("plain");
target_part.setLines(which->bd_lines);
fillBodyFields(target_part,which->bd_fields);
}
void IMAPwrapper::fillSingleBasicPart(RecPart&target_part,mailimap_body_type_basic*which)
{
if (!which) {
return;
}
QString type,sub;
switch (which->bd_media_basic->med_type) {
case MAILIMAP_MEDIA_BASIC_APPLICATION:
type = "application";
break;
case MAILIMAP_MEDIA_BASIC_AUDIO:
type = "audio";
break;
case MAILIMAP_MEDIA_BASIC_IMAGE:
type = "image";
break;
case MAILIMAP_MEDIA_BASIC_MESSAGE:
type = "message";
break;
case MAILIMAP_MEDIA_BASIC_VIDEO:
type = "video";
break;
case MAILIMAP_MEDIA_BASIC_OTHER:
default:
if (which->bd_media_basic->med_basic_type) {
type = which->bd_media_basic->med_basic_type;
} else {
type = "";
}
break;
}
if (which->bd_media_basic->med_subtype) {
sub = which->bd_media_basic->med_subtype;
} else {
sub = "";
}
qDebug("Type = %s/%s",type.latin1(),sub.latin1());
target_part.setType(type.lower());
target_part.setSubtype(sub.lower());
fillBodyFields(target_part,which->bd_fields);
}
void IMAPwrapper::fillBodyFields(RecPart&target_part,mailimap_body_fields*which)
{
if (!which) return;
if (which->bd_parameter && which->bd_parameter->pa_list && which->bd_parameter->pa_list->count>0) {
clistcell*cur;
mailimap_single_body_fld_param*param=0;
for (cur = clist_begin(which->bd_parameter->pa_list);cur!=NULL;cur=clist_next(cur)) {
param = (mailimap_single_body_fld_param*)cur->data;
if (param) {
target_part.addParameter(QString(param->pa_name).lower(),QString(param->pa_value));
}
}
}
mailimap_body_fld_enc*enc = which->bd_encoding;
QString encoding("");
switch (enc->enc_type) {
case MAILIMAP_BODY_FLD_ENC_7BIT:
encoding = "7bit";
break;
case MAILIMAP_BODY_FLD_ENC_8BIT:
encoding = "8bit";
break;
case MAILIMAP_BODY_FLD_ENC_BINARY:
encoding="binary";
break;
case MAILIMAP_BODY_FLD_ENC_BASE64:
encoding="base64";
break;
case MAILIMAP_BODY_FLD_ENC_QUOTED_PRINTABLE:
encoding="quoted-printable";
break;
case MAILIMAP_BODY_FLD_ENC_OTHER:
default:
if (enc->enc_value) {
char*t=enc->enc_value;
encoding=QString(enc->enc_value);
enc->enc_value=0L;
free(t);
}
}
if (which->bd_description) {
target_part.setDescription(QString(which->bd_description));
}
target_part.setEncoding(encoding);
target_part.setSize(which->bd_size);
}
void IMAPwrapper::deleteMail(const RecMail&mail)
{
mailimap_flag_list*flist;
mailimap_set *set;
mailimap_store_att_flags * store_flags;
int err;
login();
if (!m_imap) {
return;
}
const char *mb = mail.getMbox().latin1();
err = mailimap_select( m_imap, (char*)mb);
if ( err != MAILIMAP_NO_ERROR ) {
qDebug("error selecting mailbox for delete: %s",m_imap->imap_response);
return;
}
flist = mailimap_flag_list_new_empty();
mailimap_flag_list_add(flist,mailimap_flag_new_deleted());
store_flags = mailimap_store_att_flags_new_set_flags(flist);
set = mailimap_set_new_single(mail.getNumber());
err = mailimap_store(m_imap,set,store_flags);
mailimap_set_free( set );
mailimap_store_att_flags_free(store_flags);
if (err != MAILIMAP_NO_ERROR) {
qDebug("error deleting mail: %s",m_imap->imap_response);
return;
}
qDebug("deleting mail: %s",m_imap->imap_response);
/* should we realy do that at this moment? */
err = mailimap_expunge(m_imap);
if (err != MAILIMAP_NO_ERROR) {
qDebug("error deleting mail: %s",m_imap->imap_response);
}
qDebug("Delete successfull %s",m_imap->imap_response);
}
void IMAPwrapper::answeredMail(const RecMail&mail)
{
mailimap_flag_list*flist;
mailimap_set *set;
mailimap_store_att_flags * store_flags;
int err;
login();
if (!m_imap) {
return;
}
const char *mb = mail.getMbox().latin1();
err = mailimap_select( m_imap, (char*)mb);
if ( err != MAILIMAP_NO_ERROR ) {
qDebug("error selecting mailbox for mark: %s",m_imap->imap_response);
return;
}
flist = mailimap_flag_list_new_empty();
mailimap_flag_list_add(flist,mailimap_flag_new_answered());
store_flags = mailimap_store_att_flags_new_add_flags(flist);
set = mailimap_set_new_single(mail.getNumber());
err = mailimap_store(m_imap,set,store_flags);
mailimap_set_free( set );
mailimap_store_att_flags_free(store_flags);
if (err != MAILIMAP_NO_ERROR) {
qDebug("error marking mail: %s",m_imap->imap_response);
return;
}
}
QString IMAPwrapper::fetchTextPart(const RecMail&mail,const QValueList<int>&path,bool internal_call,const QString&enc)
{
QString body("");
encodedString*res = fetchRawPart(mail,path,internal_call);
encodedString*r = decode_String(res,enc);
delete res;
if (r) {
if (r->Length()>0) {
body = r->Content();
}
delete r;
}
return body;
}
QString IMAPwrapper::fetchTextPart(const RecMail&mail,const RecPart&part)
{
return fetchTextPart(mail,part.Positionlist(),false,part.Encoding());
}
encodedString* IMAPwrapper::fetchDecodedPart(const RecMail&mail,const RecPart&part)
{
encodedString*res = fetchRawPart(mail,part.Positionlist(),false);
encodedString*r = decode_String(res,part.Encoding());
delete res;
return r;
}
encodedString* IMAPwrapper::fetchRawPart(const RecMail&mail,const RecPart&part)
{
return fetchRawPart(mail,part.Positionlist(),false);
}
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,820 +1,821 @@
#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) {
switch (cflag->fl_flag->fl_type) {
case MAILIMAP_FLAG_ANSWERED: /* \Answered flag */
mFlags.setBit(FLAG_ANSWERED);
break;
case MAILIMAP_FLAG_FLAGGED: /* \Flagged flag */
mFlags.setBit(FLAG_FLAGGED);
break;
case MAILIMAP_FLAG_DELETED: /* \Deleted flag */
mFlags.setBit(FLAG_DELETED);
break;
case MAILIMAP_FLAG_SEEN: /* \Seen flag */
mFlags.setBit(FLAG_SEEN);
break;
case MAILIMAP_FLAG_DRAFT: /* \Draft flag */
mFlags.setBit(FLAG_DRAFT);
break;
case MAILIMAP_FLAG_KEYWORD: /* keyword flag */
break;
case MAILIMAP_FLAG_EXTENSION: /* \extension flag */
break;
default:
break;
}
} else if (cflag->fl_type==MAILIMAP_FLAG_FETCH_RECENT) {
mFlags.setBit(FLAG_RECENT);
}
}
continue;
}
if (item->att_data.att_static->att_type==MAILIMAP_MSG_ATT_ENVELOPE) {
mailimap_envelope * head = item->att_data.att_static->att_data.att_env;
m->setDate(head->env_date);
m->setSubject(convert_String((const char*)head->env_subject));
//m->setSubject(head->env_subject);
if (head->env_from!=NULL) {
addresslist = address_list_to_stringlist(head->env_from->frm_list);
if (addresslist.count()) {
m->setFrom(addresslist.first());
}
}
if (head->env_to!=NULL) {
addresslist = address_list_to_stringlist(head->env_to->to_list);
m->setTo(addresslist);
}
if (head->env_cc!=NULL) {
addresslist = address_list_to_stringlist(head->env_cc->cc_list);
m->setCC(addresslist);
}
if (head->env_bcc!=NULL) {
addresslist = address_list_to_stringlist(head->env_bcc->bcc_list);
m->setBcc(addresslist);
}
if (head->env_reply_to!=NULL) {
addresslist = address_list_to_stringlist(head->env_reply_to->rt_list);
if (addresslist.count()) {
m->setReplyto(addresslist.first());
}
}
m->setMsgid(QString(head->env_message_id));
} else if (item->att_data.att_static->att_type==MAILIMAP_MSG_ATT_INTERNALDATE) {
#if 0
mailimap_date_time*d = item->att_data.att_static->att_data.att_internal_date;
QDateTime da(QDate(d->dt_year,d->dt_month,d->dt_day),QTime(d->dt_hour,d->dt_min,d->dt_sec));
qDebug("%i %i %i - %i %i %i",d->dt_year,d->dt_month,d->dt_day,d->dt_hour,d->dt_min,d->dt_sec);
qDebug(da.toString());
#endif
} else if (item->att_data.att_static->att_type==MAILIMAP_MSG_ATT_RFC822_SIZE) {
size = item->att_data.att_static->att_data.att_rfc822_size;
}
}
/* msg is already deleted */
if (mFlags.testBit(FLAG_DELETED) && m) {
delete m;
m = 0;
}
if (m) {
m->setFlags(mFlags);
m->setMsgsize(size);
}
return m;
}
RecBody IMAPwrapper::fetchBody(const RecMail&mail)
{
RecBody body;
const char *mb;
int err = MAILIMAP_NO_ERROR;
clist *result;
clistcell *current;
mailimap_fetch_att *fetchAtt;
mailimap_fetch_type *fetchType;
mailimap_set *set;
mailimap_body*body_desc;
mb = mail.getMbox().latin1();
login();
if (!m_imap) {
return body;
}
err = mailimap_select( m_imap, (char*)mb);
if ( err != MAILIMAP_NO_ERROR ) {
qDebug("error selecting mailbox: %s",m_imap->imap_response);
return body;
}
result = clist_new();
/* the range has to start at 1!!! not with 0!!!! */
set = mailimap_set_new_interval( mail.getNumber(),mail.getNumber() );
fetchAtt = mailimap_fetch_att_new_bodystructure();
fetchType = mailimap_fetch_type_new_fetch_att(fetchAtt);
err = mailimap_fetch( m_imap, set, fetchType, &result );
mailimap_set_free( set );
mailimap_fetch_type_free( fetchType );
if (err == MAILIMAP_NO_ERROR && (current=clist_begin(result)) ) {
mailimap_msg_att * msg_att;
msg_att = (mailimap_msg_att*)current->data;
mailimap_msg_att_item*item = (mailimap_msg_att_item*)msg_att->att_list->first->data;
body_desc = item->att_data.att_static->att_data.att_body;
if (body_desc->bd_type==MAILIMAP_BODY_1PART) {
searchBodyText(mail,body_desc->bd_data.bd_body_1part,body);
} else if (body_desc->bd_type==MAILIMAP_BODY_MPART) {
qDebug("Mulitpart mail");
searchBodyText(mail,body_desc->bd_data.bd_body_mpart,body);
}
} else {
qDebug("error fetching body: %s",m_imap->imap_response);
}
mailimap_fetch_list_free(result);
return body;
}
/* this routine is just called when the mail has only ONE part.
for filling the parts of a multi-part-message there are other
routines 'cause we can not simply fetch the whole body. */
void IMAPwrapper::searchBodyText(const RecMail&mail,mailimap_body_type_1part*mailDescription,RecBody&target_body)
{
if (!mailDescription) {
return;
}
QString sub,body_text;
RecPart singlePart;
QValueList<int> path;
fillSinglePart(singlePart,mailDescription);
switch (mailDescription->bd_type) {
case MAILIMAP_BODY_TYPE_1PART_MSG:
path.append(1);
body_text = fetchTextPart(mail,path,true,singlePart.Encoding());
target_body.setBodytext(body_text);
target_body.setDescription(singlePart);
break;
case MAILIMAP_BODY_TYPE_1PART_TEXT:
qDebug("Mediatype single: %s",mailDescription->bd_data.bd_type_text->bd_media_text);
path.append(1);
body_text = fetchTextPart(mail,path,true,singlePart.Encoding());
target_body.setBodytext(body_text);
target_body.setDescription(singlePart);
break;
case MAILIMAP_BODY_TYPE_1PART_BASIC:
qDebug("Single attachment");
target_body.setBodytext("");
target_body.addPart(singlePart);
break;
default:
break;
}
return;
}
QStringList IMAPwrapper::address_list_to_stringlist(clist*list)
{
QStringList l;
QString from;
bool named_from;
clistcell *current = NULL;
mailimap_address * current_address=NULL;
if (!list) {
return l;
}
unsigned int count = 0;
for (current=clist_begin(list);current!= NULL;current=clist_next(current)) {
from = "";
named_from = false;
current_address=(mailimap_address*)current->data;
if (current_address->ad_personal_name){
from+=convert_String((const char*)current_address->ad_personal_name);
//from+=QString(current_address->ad_personal_name);
from+=" ";
named_from = true;
}
if (named_from && (current_address->ad_mailbox_name || current_address->ad_host_name)) {
from+="<";
}
if (current_address->ad_mailbox_name) {
from+=QString(current_address->ad_mailbox_name);
from+="@";
}
if (current_address->ad_host_name) {
from+=QString(current_address->ad_host_name);
}
if (named_from && (current_address->ad_mailbox_name || current_address->ad_host_name)) {
from+=">";
}
l.append(QString(from));
if (++count > 99) {
break;
}
}
return l;
}
encodedString*IMAPwrapper::fetchRawPart(const RecMail&mail,const QValueList<int>&path,bool internal_call)
{
encodedString*res=new encodedString;
const char*mb;
int err;
mailimap_fetch_type *fetchType;
mailimap_set *set;
clistcell*current,*cur;
login();
if (!m_imap) {
return res;
}
if (!internal_call) {
mb = mail.getMbox().latin1();
err = mailimap_select( m_imap, (char*)mb);
if ( err != MAILIMAP_NO_ERROR ) {
qDebug("error selecting mailbox: %s",m_imap->imap_response);
return res;
}
}
set = mailimap_set_new_single(mail.getNumber());
clist*id_list=clist_new();
for (unsigned j=0; j < path.count();++j) {
uint32_t * p_id = (uint32_t *)malloc(sizeof(*p_id));
*p_id = path[j];
clist_append(id_list,p_id);
}
mailimap_section_part * section_part = mailimap_section_part_new(id_list);
mailimap_section_spec * section_spec = mailimap_section_spec_new(MAILIMAP_SECTION_SPEC_SECTION_PART, NULL, section_part, NULL);
mailimap_section * section = mailimap_section_new(section_spec);
mailimap_fetch_att * fetch_att = mailimap_fetch_att_new_body_section(section);
fetchType = mailimap_fetch_type_new_fetch_att(fetch_att);
clist*result = clist_new();
err = mailimap_fetch( m_imap, set, fetchType, &result );
mailimap_set_free( set );
mailimap_fetch_type_free( fetchType );
if (err == MAILIMAP_NO_ERROR && (current=clist_begin(result)) ) {
mailimap_msg_att * msg_att;
msg_att = (mailimap_msg_att*)current->data;
mailimap_msg_att_item*msg_att_item;
for(cur = clist_begin(msg_att->att_list) ; cur != NULL ; cur = clist_next(cur)) {
msg_att_item = (mailimap_msg_att_item*)clist_content(cur);
if (msg_att_item->att_type == MAILIMAP_MSG_ATT_ITEM_STATIC) {
if (msg_att_item->att_data.att_static->att_type == MAILIMAP_MSG_ATT_BODY_SECTION) {
char*text = msg_att_item->att_data.att_static->att_data.att_body_section->sec_body_part;
/* detach - we take over the content */
msg_att_item->att_data.att_static->att_data.att_body_section->sec_body_part = 0L;
res->setContent(text,msg_att_item->att_data.att_static->att_data.att_body_section->sec_length);
}
}
}
} else {
qDebug("error fetching text: %s",m_imap->imap_response);
}
mailimap_fetch_list_free(result);
return res;
}
void IMAPwrapper::searchBodyText(const RecMail&mail,mailimap_body_type_mpart*mailDescription,RecBody&target_body,int current_recursion,QValueList<int>recList)
{
/* current_recursion is for avoiding ugly mails which has a to deep body-structure */
if (!mailDescription||current_recursion==10) {
return;
}
clistcell*current;
mailimap_body*current_body;
unsigned int count = 0;
for (current=clist_begin(mailDescription->bd_list);current!=0;current=clist_next(current)) {
/* the point in the message */
++count;
current_body = (mailimap_body*)current->data;
if (current_body->bd_type==MAILIMAP_BODY_MPART) {
QValueList<int>clist = recList;
clist.append(count);
searchBodyText(mail,current_body->bd_data.bd_body_mpart,target_body,current_recursion+1,clist);
} else if (current_body->bd_type==MAILIMAP_BODY_1PART){
RecPart currentPart;
fillSinglePart(currentPart,current_body->bd_data.bd_body_1part);
QValueList<int>clist = recList;
clist.append(count);
/* important: Check for is NULL 'cause a body can be empty! */
if (currentPart.Type()=="text" && target_body.Bodytext().isNull() ) {
QString body_text = fetchTextPart(mail,clist,true,currentPart.Encoding());
target_body.setDescription(currentPart);
target_body.setBodytext(body_text);
} else {
QString id("");
for (unsigned int j = 0; j < clist.count();++j) {
id+=(j>0?" ":"");
id+=QString("%1").arg(clist[j]);
}
qDebug("ID= %s",id.latin1());
currentPart.setIdentifier(id);
currentPart.setPositionlist(clist);
target_body.addPart(currentPart);
}
}
}
}
void IMAPwrapper::fillSinglePart(RecPart&target_part,mailimap_body_type_1part*Description)
{
if (!Description) {
return;
}
switch (Description->bd_type) {
case MAILIMAP_BODY_TYPE_1PART_TEXT:
target_part.setType("text");
fillSingleTextPart(target_part,Description->bd_data.bd_type_text);
break;
case MAILIMAP_BODY_TYPE_1PART_BASIC:
fillSingleBasicPart(target_part,Description->bd_data.bd_type_basic);
break;
case MAILIMAP_BODY_TYPE_1PART_MSG:
fillSingleMsgPart(target_part,Description->bd_data.bd_type_msg);
break;
default:
break;
}
}
void IMAPwrapper::fillSingleTextPart(RecPart&target_part,mailimap_body_type_text*which)
{
if (!which) {
return;
}
QString sub;
sub = which->bd_media_text;
target_part.setSubtype(sub.lower());
target_part.setLines(which->bd_lines);
fillBodyFields(target_part,which->bd_fields);
}
void IMAPwrapper::fillSingleMsgPart(RecPart&target_part,mailimap_body_type_msg*which)
{
if (!which) {
return;
}
// QString sub;
// sub = which->bd_media_text;
// target_part.setSubtype(sub.lower());
qDebug("Message part");
/* we set this type to text/plain */
target_part.setType("text");
target_part.setSubtype("plain");
target_part.setLines(which->bd_lines);
fillBodyFields(target_part,which->bd_fields);
}
void IMAPwrapper::fillSingleBasicPart(RecPart&target_part,mailimap_body_type_basic*which)
{
if (!which) {
return;
}
QString type,sub;
switch (which->bd_media_basic->med_type) {
case MAILIMAP_MEDIA_BASIC_APPLICATION:
type = "application";
break;
case MAILIMAP_MEDIA_BASIC_AUDIO:
type = "audio";
break;
case MAILIMAP_MEDIA_BASIC_IMAGE:
type = "image";
break;
case MAILIMAP_MEDIA_BASIC_MESSAGE:
type = "message";
break;
case MAILIMAP_MEDIA_BASIC_VIDEO:
type = "video";
break;
case MAILIMAP_MEDIA_BASIC_OTHER:
default:
if (which->bd_media_basic->med_basic_type) {
type = which->bd_media_basic->med_basic_type;
} else {
type = "";
}
break;
}
if (which->bd_media_basic->med_subtype) {
sub = which->bd_media_basic->med_subtype;
} else {
sub = "";
}
qDebug("Type = %s/%s",type.latin1(),sub.latin1());
target_part.setType(type.lower());
target_part.setSubtype(sub.lower());
fillBodyFields(target_part,which->bd_fields);
}
void IMAPwrapper::fillBodyFields(RecPart&target_part,mailimap_body_fields*which)
{
if (!which) return;
if (which->bd_parameter && which->bd_parameter->pa_list && which->bd_parameter->pa_list->count>0) {
clistcell*cur;
mailimap_single_body_fld_param*param=0;
for (cur = clist_begin(which->bd_parameter->pa_list);cur!=NULL;cur=clist_next(cur)) {
param = (mailimap_single_body_fld_param*)cur->data;
if (param) {
target_part.addParameter(QString(param->pa_name).lower(),QString(param->pa_value));
}
}
}
mailimap_body_fld_enc*enc = which->bd_encoding;
QString encoding("");
switch (enc->enc_type) {
case MAILIMAP_BODY_FLD_ENC_7BIT:
encoding = "7bit";
break;
case MAILIMAP_BODY_FLD_ENC_8BIT:
encoding = "8bit";
break;
case MAILIMAP_BODY_FLD_ENC_BINARY:
encoding="binary";
break;
case MAILIMAP_BODY_FLD_ENC_BASE64:
encoding="base64";
break;
case MAILIMAP_BODY_FLD_ENC_QUOTED_PRINTABLE:
encoding="quoted-printable";
break;
case MAILIMAP_BODY_FLD_ENC_OTHER:
default:
if (enc->enc_value) {
char*t=enc->enc_value;
encoding=QString(enc->enc_value);
enc->enc_value=0L;
free(t);
}
}
if (which->bd_description) {
target_part.setDescription(QString(which->bd_description));
}
target_part.setEncoding(encoding);
target_part.setSize(which->bd_size);
}
void IMAPwrapper::deleteMail(const RecMail&mail)
{
mailimap_flag_list*flist;
mailimap_set *set;
mailimap_store_att_flags * store_flags;
int err;
login();
if (!m_imap) {
return;
}
const char *mb = mail.getMbox().latin1();
err = mailimap_select( m_imap, (char*)mb);
if ( err != MAILIMAP_NO_ERROR ) {
qDebug("error selecting mailbox for delete: %s",m_imap->imap_response);
return;
}
flist = mailimap_flag_list_new_empty();
mailimap_flag_list_add(flist,mailimap_flag_new_deleted());
store_flags = mailimap_store_att_flags_new_set_flags(flist);
set = mailimap_set_new_single(mail.getNumber());
err = mailimap_store(m_imap,set,store_flags);
mailimap_set_free( set );
mailimap_store_att_flags_free(store_flags);
if (err != MAILIMAP_NO_ERROR) {
qDebug("error deleting mail: %s",m_imap->imap_response);
return;
}
qDebug("deleting mail: %s",m_imap->imap_response);
/* should we realy do that at this moment? */
err = mailimap_expunge(m_imap);
if (err != MAILIMAP_NO_ERROR) {
qDebug("error deleting mail: %s",m_imap->imap_response);
}
qDebug("Delete successfull %s",m_imap->imap_response);
}
void IMAPwrapper::answeredMail(const RecMail&mail)
{
mailimap_flag_list*flist;
mailimap_set *set;
mailimap_store_att_flags * store_flags;
int err;
login();
if (!m_imap) {
return;
}
const char *mb = mail.getMbox().latin1();
err = mailimap_select( m_imap, (char*)mb);
if ( err != MAILIMAP_NO_ERROR ) {
qDebug("error selecting mailbox for mark: %s",m_imap->imap_response);
return;
}
flist = mailimap_flag_list_new_empty();
mailimap_flag_list_add(flist,mailimap_flag_new_answered());
store_flags = mailimap_store_att_flags_new_add_flags(flist);
set = mailimap_set_new_single(mail.getNumber());
err = mailimap_store(m_imap,set,store_flags);
mailimap_set_free( set );
mailimap_store_att_flags_free(store_flags);
if (err != MAILIMAP_NO_ERROR) {
qDebug("error marking mail: %s",m_imap->imap_response);
return;
}
}
QString IMAPwrapper::fetchTextPart(const RecMail&mail,const QValueList<int>&path,bool internal_call,const QString&enc)
{
QString body("");
encodedString*res = fetchRawPart(mail,path,internal_call);
encodedString*r = decode_String(res,enc);
delete res;
if (r) {
if (r->Length()>0) {
body = r->Content();
}
delete r;
}
return body;
}
QString IMAPwrapper::fetchTextPart(const RecMail&mail,const RecPart&part)
{
return fetchTextPart(mail,part.Positionlist(),false,part.Encoding());
}
encodedString* IMAPwrapper::fetchDecodedPart(const RecMail&mail,const RecPart&part)
{
encodedString*res = fetchRawPart(mail,part.Positionlist(),false);
encodedString*r = decode_String(res,part.Encoding());
delete res;
return r;
}
encodedString* IMAPwrapper::fetchRawPart(const RecMail&mail,const RecPart&part)
{
return fetchRawPart(mail,part.Positionlist(),false);
}
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