summaryrefslogtreecommitdiff
Side-by-side diff
Diffstat (more/less context) (ignore whitespace changes)
-rw-r--r--noncore/net/mail/libmailwrapper/generatemail.cpp454
-rw-r--r--noncore/net/mail/libmailwrapper/generatemail.h44
-rw-r--r--noncore/net/mail/libmailwrapper/genericwrapper.cpp52
-rw-r--r--noncore/net/mail/libmailwrapper/genericwrapper.h4
-rw-r--r--noncore/net/mail/libmailwrapper/imapwrapper.cpp49
-rw-r--r--noncore/net/mail/libmailwrapper/libmailwrapper.pro16
-rw-r--r--noncore/net/mail/libmailwrapper/mailtypes.cpp19
-rw-r--r--noncore/net/mail/libmailwrapper/mailtypes.h25
-rw-r--r--noncore/net/mail/libmailwrapper/smtpwrapper.cpp464
-rw-r--r--noncore/net/mail/libmailwrapper/smtpwrapper.h32
10 files changed, 625 insertions, 534 deletions
diff --git a/noncore/net/mail/libmailwrapper/generatemail.cpp b/noncore/net/mail/libmailwrapper/generatemail.cpp
new file mode 100644
index 0000000..9272d0c
--- a/dev/null
+++ b/noncore/net/mail/libmailwrapper/generatemail.cpp
@@ -0,0 +1,454 @@
+#include "generatemail.h"
+#include "mailwrapper.h"
+
+#include <libetpan/libetpan.h>
+
+#include <qt.h>
+
+const char* Generatemail::USER_AGENT="OpieMail v0.5";
+
+Generatemail::Generatemail()
+{
+}
+
+Generatemail::~Generatemail()
+{
+}
+
+void Generatemail::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 );
+ }
+ }
+ }
+}
+
+char *Generatemail::getFrom( mailimf_field *ffrom) {
+ char *from = NULL;
+ 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;
+}
+
+char *Generatemail::getFrom( mailmime *mail ) {
+ /* no need to delete - its just a pointer to structure content */
+ mailimf_field *ffrom = 0;
+ ffrom = getField( mail->mm_data.mm_message.mm_fields, MAILIMF_FIELD_FROM );
+ return getFrom(ffrom);
+}
+
+mailimf_field *Generatemail::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;
+}
+
+mailimf_address_list *Generatemail::parseAddresses(const QString&addr ) {
+ mailimf_address_list *addresses;
+
+ if ( addr.isEmpty() )
+ return NULL;
+
+ addresses = mailimf_address_list_new_empty();
+
+ bool literal_open = false;
+ unsigned int startpos = 0;
+ QStringList list;
+ QString s;
+ unsigned int i = 0;
+ for (; i < addr.length();++i) {
+ switch (addr[i]) {
+ case '\"':
+ literal_open = !literal_open;
+ break;
+ case ',':
+ if (!literal_open) {
+ s = addr.mid(startpos,i-startpos);
+ if (!s.isEmpty()) {
+ list.append(s);
+ qDebug("Appended %s",s.latin1());
+ }
+ // !!!! this is a MUST BE!
+ startpos = ++i;
+ }
+ break;
+ default:
+ break;
+ }
+ }
+ s = addr.mid(startpos,i-startpos);
+ if (!s.isEmpty()) {
+ list.append(s);
+ qDebug("Appended %s",s.latin1());
+ }
+ QStringList::Iterator it;
+ for ( it = list.begin(); it != list.end(); it++ ) {
+ int err = mailimf_address_list_add_parse( addresses, (char*)(*it).latin1() );
+ if ( err != MAILIMF_NO_ERROR ) {
+ qDebug( "Error parsing" );
+ qDebug( *it );
+ } else {
+ qDebug( "Parse success! %s",(*it).latin1());
+ }
+ }
+ return addresses;
+}
+
+mailmime *Generatemail::buildFilePart(const QString&filename,const QString&mimetype,const QString&TextContent ) {
+ mailmime * filePart = 0;
+ mailmime_fields * fields = 0;
+ mailmime_content * content = 0;
+ mailmime_parameter * param = 0;
+ char*name = 0;
+ char*file = 0;
+ int err;
+
+ int pos = filename.findRev( '/' );
+
+ if (filename.length()>0) {
+ QString tmp = filename.right( filename.length() - ( pos + 1 ) );
+ name = strdup( tmp.latin1() ); // just filename
+ file = strdup( filename.latin1() ); // full name with path
+ }
+
+ int disptype = MAILMIME_DISPOSITION_TYPE_ATTACHMENT;
+ int mechanism = MAILMIME_MECHANISM_BASE64;
+
+ if ( mimetype.startsWith( "text/" ) ) {
+ param = mailmime_parameter_new( strdup( "charset" ),
+ strdup( "iso-8859-1" ) );
+ mechanism = MAILMIME_MECHANISM_QUOTED_PRINTABLE;
+ }
+
+ fields = mailmime_fields_new_filename(
+ disptype, name,
+ mechanism );
+ content = mailmime_content_new_with_str( (char*)mimetype.latin1() );
+ if (content!=0 && fields != 0) {
+ if (param) {
+ clist_append(content->ct_parameters,param);
+ param = 0;
+ }
+ if (filename.length()>0) {
+ QFileInfo f(filename);
+ param = mailmime_parameter_new(strdup("name"),strdup(f.fileName().latin1()));
+ clist_append(content->ct_parameters,param);
+ param = 0;
+ }
+ filePart = mailmime_new_empty( content, fields );
+ }
+ if (filePart) {
+ if (filename.length()>0) {
+ err = mailmime_set_body_file( filePart, file );
+ } else {
+ err = mailmime_set_body_text(filePart,strdup(TextContent.data()),TextContent.length());
+ }
+ if (err != MAILIMF_NO_ERROR) {
+ qDebug("Error setting body with file %s",file);
+ mailmime_free( filePart );
+ filePart = 0;
+ }
+ }
+
+ if (!filePart) {
+ if ( param != NULL ) {
+ mailmime_parameter_free( param );
+ }
+ if (content) {
+ mailmime_content_free( content );
+ }
+ if (fields) {
+ mailmime_fields_free( fields );
+ } else {
+ if (name) {
+ free( name );
+ }
+ if (file) {
+ free( file );
+ }
+ }
+ }
+ return filePart; // Success :)
+
+}
+
+void Generatemail::addFileParts( mailmime *message,const QList<Attachment>&files ) {
+ const Attachment *it;
+ unsigned int count = files.count();
+ qDebug("List contains %i values",count);
+ for ( unsigned int i = 0; i < count; ++i ) {
+ qDebug( "Adding file" );
+ mailmime *filePart;
+ int err;
+ it = ((QList<Attachment>)files).at(i);
+
+ filePart = buildFilePart( it->getFileName(), it->getMimeType(),"" );
+ if ( filePart == NULL ) {
+ qDebug( "addFileParts: error adding file:" );
+ qDebug( it->getFileName() );
+ continue;
+ }
+ err = mailmime_smart_add_part( message, filePart );
+ if ( err != MAILIMF_NO_ERROR ) {
+ mailmime_free( filePart );
+ qDebug("error smart add");
+ }
+ }
+}
+
+mailmime *Generatemail::buildTxtPart(const QString&str ) {
+ mailmime *txtPart;
+ mailmime_fields *fields;
+ mailmime_content *content;
+ mailmime_parameter *param;
+ 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, (char*)str.data(), str.length() );
+ 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:
+ qDebug( "buildTxtPart - error" );
+
+ return NULL; // Error :(
+}
+
+mailimf_mailbox *Generatemail::newMailbox(const QString&name, const QString&mail ) {
+ return mailimf_mailbox_new( strdup( name.latin1() ),
+ strdup( mail.latin1() ) );
+}
+
+mailimf_fields *Generatemail::createImfFields(const Mail&mail ) {
+ mailimf_fields *fields;
+ mailimf_field *xmailer;
+ mailimf_mailbox *sender=0,*fromBox=0;
+ mailimf_mailbox_list *from=0;
+ mailimf_address_list *to=0, *cc=0, *bcc=0, *reply=0;
+ clist*in_reply_to = 0;
+ 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() );
+
+ if (mail.Inreply().count()>0) {
+ in_reply_to = clist_new();
+ char*c_reply;
+ unsigned int nsize = 0;
+ for (QStringList::ConstIterator it=mail.Inreply().begin();
+ it != mail.Inreply().end();++it) {
+ if ((*it).isEmpty())
+ continue;
+ QString h((*it));
+ while (h.length()>0 && h[0]=='<') {
+ h.remove(0,1);
+ }
+ while (h.length()>0 && h[h.length()-1]=='>') {
+ h.remove(h.length()-1,1);
+ }
+ if (h.isEmpty()) continue;
+ nsize = strlen(h.latin1());
+ /* yes! must be malloc! */
+ c_reply = (char*)malloc( (nsize+1)*sizeof(char));
+ memset(c_reply,0,nsize+1);
+ memcpy(c_reply,h.latin1(),nsize);
+ clist_append(in_reply_to,c_reply);
+ qDebug("In reply to: %s",c_reply);
+ }
+ }
+
+ fields = mailimf_fields_new_with_data( from, sender, reply, to, cc, bcc,
+ in_reply_to, 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:
+ if (xmailer)
+ mailimf_field_free( xmailer );
+err_free_fields:
+ if (fields)
+ mailimf_fields_free( fields );
+err_free_reply:
+ if (reply)
+ mailimf_address_list_free( reply );
+ if (bcc)
+ mailimf_address_list_free( bcc );
+ if (cc)
+ mailimf_address_list_free( cc );
+ if (to)
+ mailimf_address_list_free( to );
+err_free_from:
+ if (from)
+ mailimf_mailbox_list_free( from );
+err_free_fromBox:
+ mailimf_mailbox_free( fromBox );
+err_free_sender:
+ if (sender)
+ mailimf_mailbox_free( sender );
+err_free:
+ if (subject)
+ free( subject );
+ qDebug( "createImfFields - error" );
+
+ return NULL; // Error :(
+}
+
+mailmime *Generatemail::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 :(
+}
+
+clist *Generatemail::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;
+}
diff --git a/noncore/net/mail/libmailwrapper/generatemail.h b/noncore/net/mail/libmailwrapper/generatemail.h
new file mode 100644
index 0000000..8be5a2b
--- a/dev/null
+++ b/noncore/net/mail/libmailwrapper/generatemail.h
@@ -0,0 +1,44 @@
+#ifndef __GENERATE_MAIL_H
+#define __GENERATE_MAIL_H
+
+#include <qpe/applnk.h>
+
+#include <qobject.h>
+#include <libetpan/clist.h>
+
+class Mail;
+class RecMail;
+class Attachment;
+struct mailimf_fields;
+struct mailimf_field;
+struct mailimf_mailbox;
+struct mailmime;
+struct mailimf_address_list;
+class progressMailSend;
+struct mailsmtp;
+
+class Generatemail : public QObject
+{
+ Q_OBJECT
+public:
+ Generatemail();
+ virtual ~Generatemail();
+
+protected:
+ static void addRcpts( clist *list, mailimf_address_list *addr_list );
+ static char *getFrom( mailmime *mail );
+ static char *getFrom( mailimf_field *ffrom);
+ static mailimf_field *getField( mailimf_fields *fields, int type );
+ mailimf_address_list *parseAddresses(const QString&addr );
+ void addFileParts( mailmime *message,const QList<Attachment>&files );
+ mailmime *buildFilePart(const QString&filename,const QString&mimetype,const QString&content);
+ mailmime *buildTxtPart(const QString&str );
+ mailimf_mailbox *newMailbox(const QString&name,const QString&mail );
+ mailimf_fields *createImfFields(const Mail &mail );
+ mailmime *createMimeMail(const Mail&mail );
+ clist *createRcptList( mailimf_fields *fields );
+
+ static const char* USER_AGENT;
+};
+
+#endif
diff --git a/noncore/net/mail/libmailwrapper/genericwrapper.cpp b/noncore/net/mail/libmailwrapper/genericwrapper.cpp
index eb2c031..137a6ef 100644
--- a/noncore/net/mail/libmailwrapper/genericwrapper.cpp
+++ b/noncore/net/mail/libmailwrapper/genericwrapper.cpp
@@ -1,441 +1,467 @@
#include "genericwrapper.h"
#include <libetpan/libetpan.h>
#include "mailtypes.h"
Genericwrapper::Genericwrapper()
: AbstractMail()
{
bodyCache.clear();
m_storage = 0;
m_folder = 0;
}
Genericwrapper::~Genericwrapper()
{
if (m_folder) {
mailfolder_free(m_folder);
}
if (m_storage) {
mailstorage_free(m_storage);
}
cleanMimeCache();
}
void Genericwrapper::fillSingleBody(RecPart&target,mailmessage*,mailmime*mime)
{
if (!mime) {
return;
}
mailmime_field*field = 0;
mailmime_single_fields fields;
memset(&fields, 0, sizeof(struct mailmime_single_fields));
if (mime->mm_mime_fields != NULL) {
mailmime_single_fields_init(&fields, mime->mm_mime_fields,
mime->mm_content_type);
}
-
+
mailmime_content*type = fields.fld_content;
clistcell*current;
if (!type) {
target.setType("text");
target.setSubtype("plain");
} else {
target.setSubtype(type->ct_subtype);
switch(type->ct_type->tp_data.tp_discrete_type->dt_type) {
case MAILMIME_DISCRETE_TYPE_TEXT:
target.setType("text");
break;
case MAILMIME_DISCRETE_TYPE_IMAGE:
target.setType("image");
break;
case MAILMIME_DISCRETE_TYPE_AUDIO:
target.setType("audio");
break;
case MAILMIME_DISCRETE_TYPE_VIDEO:
target.setType("video");
break;
case MAILMIME_DISCRETE_TYPE_APPLICATION:
target.setType("application");
break;
case MAILMIME_DISCRETE_TYPE_EXTENSION:
default:
if (type->ct_type->tp_data.tp_discrete_type->dt_extension) {
target.setType(type->ct_type->tp_data.tp_discrete_type->dt_extension);
}
break;
}
if (type->ct_parameters) {
fillParameters(target,type->ct_parameters);
}
}
if (mime->mm_mime_fields && mime->mm_mime_fields->fld_list) {
for (current=clist_begin(mime->mm_mime_fields->fld_list);current!=0;current=clist_next(current)) {
field = (mailmime_field*)current->data;
switch(field->fld_type) {
case MAILMIME_FIELD_TRANSFER_ENCODING:
target.setEncoding(getencoding(field->fld_data.fld_encoding));
break;
case MAILMIME_FIELD_ID:
target.setIdentifier(field->fld_data.fld_id);
break;
case MAILMIME_FIELD_DESCRIPTION:
target.setDescription(field->fld_data.fld_description);
break;
default:
break;
}
}
}
}
void Genericwrapper::fillParameters(RecPart&target,clist*parameters)
{
if (!parameters) {return;}
clistcell*current=0;
mailmime_parameter*param;
for (current=clist_begin(parameters);current!=0;current=clist_next(current)) {
param = (mailmime_parameter*)current->data;
if (param) {
target.addParameter(QString(param->pa_name).lower(),QString(param->pa_value));
}
}
}
QString Genericwrapper::getencoding(mailmime_mechanism*aEnc)
{
QString enc="7bit";
if (!aEnc) return enc;
switch(aEnc->enc_type) {
case MAILMIME_MECHANISM_7BIT:
enc = "7bit";
break;
case MAILMIME_MECHANISM_8BIT:
enc = "8bit";
break;
case MAILMIME_MECHANISM_BINARY:
enc = "binary";
break;
case MAILMIME_MECHANISM_QUOTED_PRINTABLE:
enc = "quoted-printable";
break;
case MAILMIME_MECHANISM_BASE64:
enc = "base64";
break;
case MAILMIME_MECHANISM_TOKEN:
default:
if (aEnc->enc_token) {
enc = QString(aEnc->enc_token);
}
break;
}
return enc;
}
void Genericwrapper::traverseBody(RecBody&target,mailmessage*message,mailmime*mime,QValueList<int>recList,unsigned int current_rec,int current_count)
{
if (current_rec >= 10) {
qDebug("too deep recursion!");
}
if (!message || !mime) {
return;
}
int r;
char*data = 0;
size_t len;
clistiter * cur = 0;
QString b;
RecPart part;
-
+
switch (mime->mm_type) {
case MAILMIME_SINGLE:
{
QValueList<int>countlist = recList;
countlist.append(current_count);
r = mailmessage_fetch_section(message,mime,&data,&len);
part.setSize(len);
part.setPositionlist(countlist);
b = gen_attachment_id();
part.setIdentifier(b);
fillSingleBody(part,message,mime);
if (part.Type()=="text" && target.Bodytext().isNull()) {
encodedString*r = new encodedString();
r->setContent(data,len);
encodedString*res = decode_String(r,part.Encoding());
if (countlist.count()>2) {
bodyCache[b]=r;
target.addPart(part);
} else {
delete r;
}
b = QString(res->Content());
delete res;
target.setBodytext(b);
target.setDescription(part);
} else {
bodyCache[b]=new encodedString(data,len);
target.addPart(part);
}
}
break;
case MAILMIME_MULTIPLE:
{
unsigned int ccount = 1;
mailmime*cbody=0;
QValueList<int>countlist = recList;
for (cur = clist_begin(mime->mm_data.mm_multipart.mm_mp_list) ; cur != NULL ; cur = clist_next(cur)) {
cbody = (mailmime*)clist_content(cur);
if (cbody->mm_type==MAILMIME_MULTIPLE) {
RecPart targetPart;
targetPart.setType("multipart");
countlist.append(current_count);
targetPart.setPositionlist(countlist);
target.addPart(targetPart);
}
traverseBody(target,message, cbody,countlist,current_rec+1,ccount);
if (cbody->mm_type==MAILMIME_MULTIPLE) {
countlist = recList;
}
++ccount;
}
}
break;
case MAILMIME_MESSAGE:
{
QValueList<int>countlist = recList;
countlist.append(current_count);
/* the own header is always at recursion 0 - we don't need that */
if (current_rec > 0) {
part.setPositionlist(countlist);
r = mailmessage_fetch_section(message,mime,&data,&len);
part.setSize(len);
part.setPositionlist(countlist);
b = gen_attachment_id();
part.setIdentifier(b);
part.setType("message");
part.setSubtype("rfc822");
bodyCache[b]=new encodedString(data,len);
target.addPart(part);
}
if (mime->mm_data.mm_message.mm_msg_mime != NULL) {
traverseBody(target,message,mime->mm_data.mm_message.mm_msg_mime,countlist,current_rec+1);
}
}
break;
}
}
RecBody Genericwrapper::parseMail( mailmessage * msg )
{
int err = MAILIMF_NO_ERROR;
mailmime_single_fields fields;
/* is bound to msg and will be freed there */
mailmime * mime=0;
RecBody body;
memset(&fields, 0, sizeof(struct mailmime_single_fields));
err = mailmessage_get_bodystructure(msg,&mime);
QValueList<int>recList;
traverseBody(body,msg,mime,recList);
return body;
}
QString Genericwrapper::parseDateTime( mailimf_date_time *date )
{
char tmp[23];
-
- snprintf( tmp, 23, "%02i.%02i.%04i %02i:%02i:%02i %+05i",
+
+ snprintf( tmp, 23, "%02i.%02i.%04i %02i:%02i:%02i %+05i",
date->dt_day, date->dt_month, date->dt_year, date->dt_hour, date->dt_min, date->dt_sec, date->dt_zone );
-
+
return QString( tmp );
}
QString Genericwrapper::parseAddressList( mailimf_address_list *list )
{
QString result( "" );
bool first = true;
if (list == 0) return result;
for ( clistiter *current = clist_begin( list->ad_list ); current != NULL; current = current->next ) {
mailimf_address *addr = (mailimf_address *) current->data;
-
+
if ( !first ) {
result.append( "," );
} else {
first = false;
}
switch ( addr->ad_type ) {
case MAILIMF_ADDRESS_MAILBOX:
result.append( parseMailbox( addr->ad_data.ad_mailbox ) );
break;
case MAILIMF_ADDRESS_GROUP:
result.append( parseGroup( addr->ad_data.ad_group ) );
break;
default:
qDebug( "Generic: unkown mailimf address type" );
break;
}
}
-
+
return result;
}
QString Genericwrapper::parseGroup( mailimf_group *group )
{
QString result( "" );
result.append( group->grp_display_name );
result.append( ": " );
if ( group->grp_mb_list != NULL ) {
result.append( parseMailboxList( group->grp_mb_list ) );
}
result.append( ";" );
-
+
return result;
}
QString Genericwrapper::parseMailbox( mailimf_mailbox *box )
{
QString result( "" );
if ( box->mb_display_name == NULL ) {
result.append( box->mb_addr_spec );
} else {
result.append( convert_String(box->mb_display_name).latin1() );
result.append( " <" );
result.append( box->mb_addr_spec );
result.append( ">" );
}
-
+
return result;
}
QString Genericwrapper::parseMailboxList( mailimf_mailbox_list *list )
{
QString result( "" );
bool first = true;
for ( clistiter *current = clist_begin( list->mb_list ); current != NULL; current = current->next ) {
mailimf_mailbox *box = (mailimf_mailbox *) current->data;
if ( !first ) {
result.append( "," );
} else {
first = false;
}
-
+
result.append( parseMailbox( box ) );
}
-
+
return result;
}
encodedString* Genericwrapper::fetchDecodedPart(const RecMail&,const RecPart&part)
{
QMap<QString,encodedString*>::ConstIterator it = bodyCache.find(part.Identifier());
if (it==bodyCache.end()) return new encodedString();
encodedString*t = decode_String(it.data(),part.Encoding());
return t;
}
encodedString* Genericwrapper::fetchRawPart(const RecMail&mail,const RecPart&part)
{
QMap<QString,encodedString*>::ConstIterator it = bodyCache.find(part.Identifier());
if (it==bodyCache.end()) return new encodedString();
encodedString*t = it.data();
return t;
}
QString Genericwrapper::fetchTextPart(const RecMail&mail,const RecPart&part)
{
encodedString*t = fetchDecodedPart(mail,part);
QString text=t->Content();
delete t;
return text;
}
void Genericwrapper::cleanMimeCache()
{
QMap<QString,encodedString*>::Iterator it = bodyCache.begin();
for (;it!=bodyCache.end();++it) {
encodedString*t = it.data();
//it.setValue(0);
if (t) delete t;
}
bodyCache.clear();
qDebug("Genericwrapper: cache cleaned");
}
+QStringList Genericwrapper::parseInreplies(mailimf_in_reply_to * in_replies)
+{
+ QStringList res;
+ if (!in_replies || !in_replies->mid_list) return res;
+ clistiter * current = 0;
+ for ( current = clist_begin( in_replies->mid_list ); current != NULL; current = current->next ) {
+ QString h((char*)current->data);
+ while (h.length()>0 && h[0]=='<') {
+ h.remove(0,1);
+ }
+ while (h.length()>0 && h[h.length()-1]=='>') {
+ h.remove(h.length()-1,1);
+ }
+ if (h.length()>0) {
+ res.append(h);
+ }
+ }
+ return res;
+}
+
void Genericwrapper::parseList(QList<RecMail> &target,mailsession*session,const QString&mailbox,bool mbox_as_to)
{
int r;
mailmessage_list * env_list = 0;
r = mailsession_get_messages_list(session,&env_list);
if (r != MAIL_NO_ERROR) {
qDebug("Error message list");
return;
}
r = mailsession_get_envelopes_list(session, env_list);
if (r != MAIL_NO_ERROR) {
qDebug("Error filling message list");
if (env_list) {
mailmessage_list_free(env_list);
}
return;
}
- mailimf_references * refs;
+ mailimf_references * refs = 0;
+ mailimf_in_reply_to * in_replies = 0;
uint32_t i = 0;
for(; i < carray_count(env_list->msg_tab) ; ++i) {
mailmessage * msg;
QBitArray mFlags(7);
msg = (mailmessage*)carray_get(env_list->msg_tab, i);
if (msg->msg_fields == NULL) {
//qDebug("could not fetch envelope of message %i", i);
continue;
}
RecMail * mail = new RecMail();
mail->setWrapper(this);
mail_flags * flag_result = 0;
r = mailmessage_get_flags(msg,&flag_result);
if (r == MAIL_ERROR_NOT_IMPLEMENTED) {
mFlags.setBit(FLAG_SEEN);
}
mailimf_single_fields single_fields;
mailimf_single_fields_init(&single_fields, msg->msg_fields);
mail->setMsgsize(msg->msg_size);
mail->setFlags(mFlags);
mail->setMbox(mailbox);
mail->setNumber(msg->msg_index);
if (single_fields.fld_subject)
mail->setSubject( convert_String(single_fields.fld_subject->sbj_value));
if (single_fields.fld_from)
mail->setFrom(parseMailboxList(single_fields.fld_from->frm_mb_list));
if (!mbox_as_to) {
if (single_fields.fld_to)
mail->setTo( parseAddressList( single_fields.fld_to->to_addr_list ) );
} else {
mail->setTo(mailbox);
}
if (single_fields.fld_cc)
mail->setCC( parseAddressList( single_fields.fld_cc->cc_addr_list ) );
if (single_fields.fld_bcc)
mail->setBcc( parseAddressList( single_fields.fld_bcc->bcc_addr_list ) );
if (single_fields.fld_orig_date)
mail->setDate( parseDateTime( single_fields.fld_orig_date->dt_date_time ) );
// crashes when accessing pop3 account?
if (single_fields.fld_message_id->mid_value) {
mail->setMsgid(QString(single_fields.fld_message_id->mid_value));
- qDebug("Msqgid == %s",mail->Msgid().latin1());
+ qDebug("Msgid == %s",mail->Msgid().latin1());
}
+
refs = single_fields.fld_references;
if (refs && refs->mid_list && clist_count(refs->mid_list)) {
char * text = (char*)refs->mid_list->first->data;
mail->setReplyto(QString(text));
}
+ if (single_fields.fld_in_reply_to && single_fields.fld_in_reply_to->mid_list &&
+ clist_count(single_fields.fld_in_reply_to->mid_list)) {
+ mail->setInreply(parseInreplies(single_fields.fld_in_reply_to));
+ }
target.append(mail);
}
if (env_list) {
mailmessage_list_free(env_list);
}
}
diff --git a/noncore/net/mail/libmailwrapper/genericwrapper.h b/noncore/net/mail/libmailwrapper/genericwrapper.h
index 0870912..b3cd4fe 100644
--- a/noncore/net/mail/libmailwrapper/genericwrapper.h
+++ b/noncore/net/mail/libmailwrapper/genericwrapper.h
@@ -1,65 +1,67 @@
#ifndef __GENERIC_WRAPPER_H
#define __GENERIC_WRAPPER_H
#include "abstractmail.h"
#include <qmap.h>
#include <qstring.h>
#include <libetpan/clist.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;
struct mailsession;
struct mailstorage;
struct mailfolder;
+struct mailimf_in_reply_to;
/* this class hold just the funs shared between
* mbox and pop3 (later mh, too) mail access.
* it is not desigend to make a instance of it!
*/
class Genericwrapper : public AbstractMail
{
Q_OBJECT
public:
Genericwrapper();
virtual ~Genericwrapper();
virtual encodedString* fetchDecodedPart(const RecMail&mail,const RecPart&part);
virtual encodedString* fetchRawPart(const RecMail&mail,const RecPart&part);
virtual QString fetchTextPart(const RecMail&mail,const RecPart&part);
virtual void cleanMimeCache();
virtual int deleteMbox(const Folder*){return 1;}
virtual void logout(){};
virtual void storeMessage(const char*msg,size_t length, const QString&folder){};
protected:
RecBody parseMail( mailmessage * msg );
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 traverseBody(RecBody&target,mailmessage*message,mailmime*mime,QValueList<int>recList,unsigned int current_rek=0,int current_count=1);
static void fillSingleBody(RecPart&target,mailmessage*message,mailmime*mime);
static void fillParameters(RecPart&target,clist*parameters);
static QString getencoding(mailmime_mechanism*aEnc);
virtual void parseList(QList<RecMail> &target,mailsession*session,const QString&mailbox,bool mbox_as_to=false);
+ QStringList parseInreplies(mailimf_in_reply_to * in_replies);
QString msgTempName;
unsigned int last_msg_id;
QMap<QString,encodedString*> bodyCache;
mailstorage * m_storage;
mailfolder*m_folder;
};
#endif
diff --git a/noncore/net/mail/libmailwrapper/imapwrapper.cpp b/noncore/net/mail/libmailwrapper/imapwrapper.cpp
index 3375e69..e29a0a0 100644
--- a/noncore/net/mail/libmailwrapper/imapwrapper.cpp
+++ b/noncore/net/mail/libmailwrapper/imapwrapper.cpp
@@ -20,208 +20,208 @@ IMAPwrapper::~IMAPwrapper()
}
/* to avoid to often select statements in loops etc.
we trust that we are logged in and connection is established!*/
int IMAPwrapper::selectMbox(const QString&mbox)
{
if (mbox == m_Lastmbox) {
return MAILIMAP_NO_ERROR;
}
int err = mailimap_select( m_imap, (char*)mbox.latin1());
if ( err != MAILIMAP_NO_ERROR ) {
qDebug("error selecting mailbox: %s",m_imap->imap_response);
m_Lastmbox = "";
return err;
}
m_Lastmbox = mbox;
return err;
}
void IMAPwrapper::imap_progress( size_t current, size_t maximum )
{
qDebug( "IMAP: %i of %i", current, maximum );
}
bool IMAPwrapper::start_tls(bool force_tls)
{
int err;
bool try_tls;
mailimap_capability_data * cap_data = 0;
err = mailimap_capability(m_imap,&cap_data);
if (err != MAILIMAP_NO_ERROR) {
Global::statusMessage("error getting capabilities!");
qDebug("error getting capabilities!");
return false;
}
clistiter * cur;
for(cur = clist_begin(cap_data->cap_list) ; cur != NULL;cur = clist_next(cur)) {
struct mailimap_capability * cap;
cap = (struct mailimap_capability *)clist_content(cur);
if (cap->cap_type == MAILIMAP_CAPABILITY_NAME) {
if (strcasecmp(cap->cap_data.cap_name, "STARTTLS") == 0) {
try_tls = true;
break;
}
}
}
if (cap_data) {
mailimap_capability_data_free(cap_data);
}
if (try_tls) {
err = mailimap_starttls(m_imap);
if (err != MAILIMAP_NO_ERROR && force_tls) {
Global::statusMessage(tr("Server has no TLS support!"));
qDebug("Server has no TLS support!");
try_tls = false;
} else {
mailstream_low * low;
mailstream_low * new_low;
low = mailstream_get_low(m_imap->imap_stream);
if (!low) {
try_tls = false;
} else {
int fd = mailstream_low_get_fd(low);
if (fd > -1 && (new_low = mailstream_low_ssl_open(fd))!=0) {
mailstream_low_free(low);
mailstream_set_low(m_imap->imap_stream, new_low);
} else {
try_tls = false;
}
}
}
}
return try_tls;
}
void IMAPwrapper::login()
{
const char *server, *user, *pass;
uint16_t port;
int err = MAILIMAP_NO_ERROR;
if (account->getOffline()) return;
/* we are connected this moment */
/* TODO: setup a timer holding the line or if connection closed - delete the value */
if (m_imap) {
err = mailimap_noop(m_imap);
if (err!=MAILIMAP_NO_ERROR) {
logout();
} else {
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 = login.getUser().latin1();
- pass = login.getPassword().latin1();
- } else {
- // cancel
- qDebug( "IMAP: Login canceled" );
- return;
- }
- } else {
- user = account->getUser().latin1();
- pass = account->getPassword().latin1();
- }
+ 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 = login.getUser().latin1();
+ pass = 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 */
bool ssl = false;
bool try_tls = false;
bool force_tls = false;
if ( account->ConnectionType() == 2 ) {
ssl = true;
}
if (account->ConnectionType()==1) {
force_tls = true;
}
if ( ssl ) {
qDebug( "using ssl" );
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 ) {
QString failure = "";
if (err == MAILIMAP_ERROR_CONNECTION_REFUSED) {
failure="Connection refused";
} else {
failure="Unknown failure";
}
Global::statusMessage(tr("error connecting imap server: %1").arg(failure));
mailimap_free( m_imap );
m_imap = 0;
return;
}
if (!ssl) {
try_tls = start_tls(force_tls);
}
bool ok = true;
if (force_tls && !try_tls) {
Global::statusMessage(tr("Server has no TLS support!"));
qDebug("Server has no TLS support!");
ok = false;
}
/* login */
if (ok) {
err = mailimap_login_simple( m_imap, (char*)user, (char*)pass );
if ( err != MAILIMAP_NO_ERROR ) {
Global::statusMessage(tr("error logging in imap server: %1").arg(m_imap->imap_response));
ok = false;
}
}
if (!ok) {
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;
m_Lastmbox = "";
}
void IMAPwrapper::listMessages(const QString&mailbox,QList<RecMail> &target )
{
int err = MAILIMAP_NO_ERROR;
clist *result = 0;
clistcell *current;
mailimap_fetch_type *fetchType = 0;
mailimap_set *set = 0;
login();
if (!m_imap) {
return;
}
/* select mailbox READONLY for operations */
err = selectMbox(mailbox);
if ( err != MAILIMAP_NO_ERROR ) {
return;
}
int last = m_imap->imap_selection_info->sel_exists;
@@ -345,199 +345,214 @@ QList<Folder>* IMAPwrapper::listFolders()
for(cur_flag=clist_begin(bflags->mbf_oflags);cur_flag;cur_flag=clist_next(cur_flag)) {
if ( ((mailimap_mbx_list_oflag*)cur_flag->data)->of_type==MAILIMAP_MBX_LIST_OFLAG_NOINFERIORS) {
no_inferiors = true;
}
}
}
del = list->mb_delimiter;
folders->append(new IMAPFolder(temp,del,selectable,no_inferiors,account->getPrefix()));
}
} else {
qDebug("error fetching folders %s",m_imap->imap_response);
}
if (result) 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);
}
+ /* reply to address, eg. email. */
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));
+ if (head->env_in_reply_to!=NULL) {
+ QString h(head->env_in_reply_to);
+ while (h.length()>0 && h[0]=='<') {
+ h.remove(0,1);
+ }
+ while (h.length()>0 && h[h.length()-1]=='>') {
+ h.remove(h.length()-1,1);
+ }
+ if (h.length()>0) {
+ m->setInreply(QStringList(h));
+ }
+ }
+ if (head->env_message_id) {
+ 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 = 0;
clistcell *current;
mailimap_fetch_att *fetchAtt = 0;
mailimap_fetch_type *fetchType = 0;
mailimap_set *set = 0;
mailimap_body*body_desc = 0;
mb = mail.getMbox().latin1();
login();
if (!m_imap) {
return body;
}
err = selectMbox(mail.getMbox());
if ( err != MAILIMAP_NO_ERROR ) {
return body;
}
/* 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;
QValueList<int> path;
body_desc = item->att_data.att_static->att_data.att_body;
traverseBody(mail,body_desc,body,0,path);
} else {
qDebug("error fetching body: %s",m_imap->imap_response);
}
if (result) mailimap_fetch_list_free(result);
return body;
}
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+=" ";
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) {
diff --git a/noncore/net/mail/libmailwrapper/libmailwrapper.pro b/noncore/net/mail/libmailwrapper/libmailwrapper.pro
index 8ea04a4..cb1e573 100644
--- a/noncore/net/mail/libmailwrapper/libmailwrapper.pro
+++ b/noncore/net/mail/libmailwrapper/libmailwrapper.pro
@@ -1,50 +1,52 @@
TEMPLATE = lib
-CONFIG += qt warn_on debug
+CONFIG += qt warn_on debug
HEADERS = mailwrapper.h \
imapwrapper.h \
mailtypes.h \
pop3wrapper.h \
abstractmail.h \
smtpwrapper.h \
genericwrapper.h \
mboxwrapper.h \
settings.h \
logindialog.h \
sendmailprogress.h \
statusmail.h \
mhwrapper.h \
- nntpwrapper.h
-
+ nntpwrapper.h \
+ generatemail.h
+
SOURCES = imapwrapper.cpp \
mailwrapper.cpp \
mailtypes.cpp \
pop3wrapper.cpp \
abstractmail.cpp \
smtpwrapper.cpp \
genericwrapper.cpp \
mboxwrapper.cpp \
settings.cpp \
logindialog.cpp \
sendmailprogress.cpp \
statusmail.cpp \
mhwrapper.cpp \
- nntpwrapper.cpp
+ nntpwrapper.cpp \
+ generatemail.cpp
-INTERFACES = logindialogui.ui \
+INTERFACES = logindialogui.ui \
sendmailprogressui.ui
-
+
INCLUDEPATH += $(OPIEDIR)/include
CONFTEST = $$system( echo $CONFIG_TARGET_MACOSX )
contains( CONFTEST, y ){
LIBS += -lqpe -letpan -lssl -lcrypto -liconv
}else{
- LIBS += -lqpe -letpan -lssl -lcrypto
+ LIBS += -lqpe -letpan -lssl -lcrypto
}
DESTDIR = $(OPIEDIR)/lib$(PROJMAK)
TARGET = mailwrapper
include ( $(OPIEDIR)/include.pro )
diff --git a/noncore/net/mail/libmailwrapper/mailtypes.cpp b/noncore/net/mail/libmailwrapper/mailtypes.cpp
index 96e0fd5..e4646d9 100644
--- a/noncore/net/mail/libmailwrapper/mailtypes.cpp
+++ b/noncore/net/mail/libmailwrapper/mailtypes.cpp
@@ -1,357 +1,368 @@
#include "mailtypes.h"
#include <stdlib.h>
RecMail::RecMail()
:subject(""),date(""),from(""),mbox(""),msg_id(""),msg_number(0),msg_size(0),msg_flags(7)
{
init();
}
RecMail::RecMail(const RecMail&old)
:subject(""),date(""),from(""),mbox(""),msg_id(""),msg_number(0),msg_flags(7)
{
init();
copy_old(old);
qDebug("Copy constructor RecMail");
}
RecMail::~RecMail()
{
wrapper = 0;
}
void RecMail::copy_old(const RecMail&old)
{
subject = old.subject;
date = old.date;
mbox = old.mbox;
msg_id = old.msg_id;
msg_size = old.msg_size;
msg_number = old.msg_number;
from = old.from;
msg_flags = old.msg_flags;
to = old.to;
cc = old.cc;
bcc = old.bcc;
wrapper = old.wrapper;
in_reply_to = old.in_reply_to;
+ references = old.references;
}
void RecMail::init()
{
to.clear();
cc.clear();
bcc.clear();
in_reply_to.clear();
+ references.clear();
wrapper = 0;
}
void RecMail::setWrapper(AbstractMail*awrapper)
{
wrapper = awrapper;
}
AbstractMail* RecMail::Wrapper()
{
return wrapper;
}
void RecMail::setTo(const QStringList&list)
{
to = list;
}
const QStringList&RecMail::To()const
{
return to;
}
void RecMail::setCC(const QStringList&list)
{
cc = list;
}
const QStringList&RecMail::CC()const
{
return cc;
}
void RecMail::setBcc(const QStringList&list)
{
bcc = list;
}
const QStringList& RecMail::Bcc()const
{
return bcc;
}
void RecMail::setInreply(const QStringList&list)
{
in_reply_to = list;
}
const QStringList& RecMail::Inreply()const
{
return in_reply_to;
}
+void RecMail::setReferences(const QStringList&list)
+{
+ references = list;
+}
+
+const QStringList& RecMail::References()const
+{
+ return references;
+}
RecPart::RecPart()
: m_type(""),m_subtype(""),m_identifier(""),m_encoding(""),m_description(""),m_lines(0),m_size(0)
{
m_Parameters.clear();
m_poslist.clear();
}
RecPart::~RecPart()
{
}
void RecPart::setSize(unsigned int size)
{
m_size = size;
}
-
+
const unsigned int RecPart::Size()const
{
return m_size;
}
void RecPart::setLines(unsigned int lines)
{
m_lines = lines;
}
-
+
const unsigned int RecPart::Lines()const
{
return m_lines;
}
const QString& RecPart::Type()const
{
return m_type;
}
void RecPart::setType(const QString&type)
{
m_type = type;
}
const QString& RecPart::Subtype()const
{
return m_subtype;
}
void RecPart::setSubtype(const QString&subtype)
{
m_subtype = subtype;
}
const QString& RecPart::Identifier()const
{
return m_identifier;
}
void RecPart::setIdentifier(const QString&identifier)
{
m_identifier = identifier;
}
const QString& RecPart::Encoding()const
{
return m_encoding;
}
void RecPart::setEncoding(const QString&encoding)
{
m_encoding = encoding;
}
const QString& RecPart::Description()const
{
return m_description;
}
void RecPart::setDescription(const QString&desc)
{
m_description = desc;
}
-
+
void RecPart::setParameters(const part_plist_t&list)
{
m_Parameters = list;
}
const part_plist_t& RecPart::Parameters()const
{
return m_Parameters;
}
void RecPart::addParameter(const QString&key,const QString&value)
{
m_Parameters[key]=value;
}
const QString RecPart::searchParamter(const QString&key)const
{
QString value("");
part_plist_t::ConstIterator it = m_Parameters.find(key);
if (it != m_Parameters.end()) {
value = it.data();
}
return value;
}
void RecPart::setPositionlist(const QValueList<int>&poslist)
{
m_poslist = poslist;
}
const QValueList<int>& RecPart::Positionlist()const
{
return m_poslist;
}
RecBody::RecBody()
: m_BodyText(),m_PartsList(),m_description()
{
m_PartsList.clear();
}
RecBody::~RecBody()
{
}
void RecBody::setBodytext(const QString&bodyText)
{
m_BodyText = bodyText;
}
const QString& RecBody::Bodytext()const
{
return m_BodyText;
}
void RecBody::setParts(const QValueList<RecPart>&parts)
{
m_PartsList.clear();
m_PartsList = parts;
}
const QValueList<RecPart>& RecBody::Parts()const
{
return m_PartsList;
}
void RecBody::addPart(const RecPart& part)
{
m_PartsList.append(part);
}
void RecBody::setDescription(const RecPart&des)
{
m_description = des;
}
const RecPart& RecBody::Description()const
{
return m_description;
}
/* handling encoded content */
encodedString::encodedString()
{
init();
}
encodedString::encodedString(const char*nContent,unsigned int nSize)
{
init();
setContent(nContent,nSize);
}
encodedString::encodedString(char*nContent,unsigned int nSize)
{
init();
setContent(nContent,nSize);
}
encodedString::encodedString(const encodedString&old)
{
init();
copy_old(old);
qDebug("encodedeString: copy constructor!");
}
encodedString& encodedString::operator=(const encodedString&old)
{
init();
copy_old(old);
qDebug("encodedString: assign operator!");
return *this;
}
encodedString::~encodedString()
{
clean();
}
void encodedString::init()
{
content = 0;
size = 0;
}
void encodedString::clean()
{
if (content) {
free(content);
}
content = 0;
size = 0;
}
void encodedString::copy_old(const encodedString&old)
{
clean();
if (old.size>0 && old.content) {
content = (char*)malloc(old.size*sizeof(char));
memcpy(content,old.content,size);
size = old.size;
}
}
const char*encodedString::Content()const
{
return content;
}
const int encodedString::Length()const
{
return size;
}
void encodedString::setContent(const char*nContent,int nSize)
{
if (nSize>0 && nContent) {
content = (char*)malloc(nSize*sizeof(char));
memcpy(content,nContent,nSize);
- size = nSize;
+ size = nSize;
}
}
void encodedString::setContent(char*nContent,int nSize)
{
content = nContent;
size = nSize;
}
folderStat&folderStat::operator=(const folderStat&old)
{
message_count = old.message_count;
message_unseen = old.message_unseen;
message_recent = old.message_recent;
return *this;
}
diff --git a/noncore/net/mail/libmailwrapper/mailtypes.h b/noncore/net/mail/libmailwrapper/mailtypes.h
index 1420f79..17c6db9 100644
--- a/noncore/net/mail/libmailwrapper/mailtypes.h
+++ b/noncore/net/mail/libmailwrapper/mailtypes.h
@@ -1,195 +1,198 @@
#ifndef __MAIL_TYPES_H
#define __MAIL_TYPES_H
#define FLAG_ANSWERED 0
#define FLAG_FLAGGED 1
#define FLAG_DELETED 2
#define FLAG_SEEN 3
#define FLAG_DRAFT 4
#define FLAG_RECENT 5
#include <qlist.h>
#include <qbitarray.h>
#include <qstring.h>
#include <qstringlist.h>
#include <qmap.h>
#include <qvaluelist.h>
class AbstractMail;
/* a class to describe mails in a mailbox */
/* Attention!
From programmers point of view it would make sense to
store the mail body into this class, too.
- But: not from the point of view of the device.
- Mailbodies can be real large. So we request them when
+ But: not from the point of view of the device.
+ Mailbodies can be real large. So we request them when
needed from the mail-wrapper class direct from the server itself
(imap) or from a file-based cache (pop3?)
So there is no interface "const QString&body()" but you should
make a request to the mailwrapper with this class as parameter to
get the body. Same words for the attachments.
*/
class RecMail
{
public:
RecMail();
RecMail(const RecMail&old);
virtual ~RecMail();
const int getNumber()const{return msg_number;}
void setNumber(int number){msg_number=number;}
const QString&getDate()const{ return date; }
void setDate( const QString&a ) { date = a; }
const QString&getFrom()const{ return from; }
void setFrom( const QString&a ) { from = a; }
const QString&getSubject()const { return subject; }
void setSubject( const QString&s ) { subject = s; }
const QString&getMbox()const{return mbox;}
void setMbox(const QString&box){mbox = box;}
void setMsgid(const QString&id){msg_id=id;}
const QString&Msgid()const{return msg_id;}
void setReplyto(const QString&reply){replyto=reply;}
const QString&Replyto()const{return replyto;}
void setMsgsize(int size){msg_size = size;}
const int Msgsize()const{return msg_size;}
void setTo(const QStringList&list);
const QStringList&To()const;
void setCC(const QStringList&list);
const QStringList&CC()const;
void setBcc(const QStringList&list);
const QStringList&Bcc()const;
void setInreply(const QStringList&list);
const QStringList&Inreply()const;
+ void setReferences(const QStringList&list);
+ const QStringList&References()const;
+
const QBitArray&getFlags()const{return msg_flags;}
void setFlags(const QBitArray&flags){msg_flags = flags;}
-
+
void setWrapper(AbstractMail*wrapper);
AbstractMail* Wrapper();
protected:
QString subject,date,from,mbox,msg_id,replyto;
int msg_number,msg_size;
QBitArray msg_flags;
- QStringList to,cc,bcc,in_reply_to;
+ QStringList to,cc,bcc,in_reply_to,references;
AbstractMail*wrapper;
void init();
void copy_old(const RecMail&old);
};
typedef QMap<QString,QString> part_plist_t;
class RecPart
{
protected:
QString m_type,m_subtype,m_identifier,m_encoding,m_description;
unsigned int m_lines,m_size;
part_plist_t m_Parameters;
/* describes the position in the mail */
QValueList<int> m_poslist;
public:
RecPart();
virtual ~RecPart();
-
+
const QString&Type()const;
void setType(const QString&type);
const QString&Subtype()const;
void setSubtype(const QString&subtype);
const QString&Identifier()const;
void setIdentifier(const QString&identifier);
const QString&Encoding()const;
void setEncoding(const QString&encoding);
const QString&Description()const;
void setDescription(const QString&desc);
void setLines(unsigned int lines);
const unsigned int Lines()const;
void setSize(unsigned int size);
const unsigned int Size()const;
-
+
void setParameters(const part_plist_t&list);
const part_plist_t&Parameters()const;
void addParameter(const QString&key,const QString&value);
const QString searchParamter(const QString&key)const;
void setPositionlist(const QValueList<int>&poslist);
const QValueList<int>& Positionlist()const;
};
class RecBody
{
protected:
QString m_BodyText;
QValueList<RecPart> m_PartsList;
RecPart m_description;
public:
RecBody();
virtual ~RecBody();
void setBodytext(const QString&);
const QString& Bodytext()const;
void setDescription(const RecPart&des);
const RecPart& Description()const;
-
+
void setParts(const QValueList<RecPart>&parts);
const QValueList<RecPart>& Parts()const;
void addPart(const RecPart&part);
};
class encodedString
{
public:
encodedString();
/*
- creates an new content string.
+ creates an new content string.
it makes a deep copy of it!
*/
encodedString(const char*nContent,unsigned int length);
/*
Take over the nContent. Means: it will just copy the pointer, not the content.
so make sure: No one else frees the string, the string has allocated with
malloc for compatibility with c-based libs
*/
encodedString(char*nContent,unsigned int nSize);
/* copy construkor - makes ALWAYS a deep copy!!!! */
encodedString(const encodedString&old);
/* assign operator - makes ALWAYS a deep copy!!!! */
encodedString& operator=(const encodedString&old);
/* destructor - cleans the content */
virtual ~encodedString();
-
+
/* returns a pointer to the content - do not delete yoursel! */
const char*Content()const;
/* returns the lengths of the content 'cause it must not be a null-terminated string! */
const int Length()const;
-
+
/*
makes a deep copy of nContent!
*/
void setContent(const char*nContent,int nSize);
/*
Take over the nContent. Means: it will just copy the pointer, not the content.
so make sure: No one else frees the string, the string has allocated with
malloc for compatibility with c-based libs
*/
void setContent(char*nContent,int nSize);
protected:
char * content;
unsigned int size;
-
+
void init();
void copy_old(const encodedString&old);
void clean();
};
struct folderStat
{
unsigned int message_count;
unsigned int message_unseen;
unsigned int message_recent;
folderStat&operator=(const folderStat&old);
};
#endif
diff --git a/noncore/net/mail/libmailwrapper/smtpwrapper.cpp b/noncore/net/mail/libmailwrapper/smtpwrapper.cpp
index 63acfd5..a4e0beb 100644
--- a/noncore/net/mail/libmailwrapper/smtpwrapper.cpp
+++ b/noncore/net/mail/libmailwrapper/smtpwrapper.cpp
@@ -1,791 +1,347 @@
-#include <stdlib.h>
-#include <sys/stat.h>
-#include <sys/types.h>
-#include <unistd.h>
-#include <fcntl.h>
-#include <string.h>
-#include <qt.h>
-
-#include <qpe/config.h>
-#include <qpe/qcopenvelope_qws.h>
-
-#include <libetpan/libetpan.h>
-
#include "smtpwrapper.h"
#include "mailwrapper.h"
#include "abstractmail.h"
#include "logindialog.h"
#include "mailtypes.h"
#include "sendmailprogress.h"
-const char* SMTPwrapper::USER_AGENT="OpieMail v0.4";
+#include <qt.h>
+
+#include <qpe/config.h>
+#include <qpe/qcopenvelope_qws.h>
+
+#include <libetpan/libetpan.h>
+
progressMailSend*SMTPwrapper::sendProgress = 0;
SMTPwrapper::SMTPwrapper(SMTPaccount * aSmtp )
- : QObject()
+ : Generatemail()
{
m_SmtpAccount = aSmtp;
Config cfg( "mail" );
cfg.setGroup( "Status" );
m_queuedMail = cfg.readNumEntry( "outgoing", 0 );
emit queuedMails( m_queuedMail );
connect( this, SIGNAL( queuedMails(int) ), this, SLOT( emitQCop(int) ) );
m_smtp = 0;
}
SMTPwrapper::~SMTPwrapper()
{
disc_server();
}
void SMTPwrapper::emitQCop( int queued ) {
QCopEnvelope env( "QPE/Pim", "outgoingMails(int)" );
env << queued;
}
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_STARTTLS_NOT_SUPPORTED:
return tr( "Starttls not supported" );
// 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();
-
- bool literal_open = false;
- unsigned int startpos = 0;
- QStringList list;
- QString s;
- unsigned int i = 0;
- for (; i < addr.length();++i) {
- switch (addr[i]) {
- case '\"':
- literal_open = !literal_open;
- break;
- case ',':
- if (!literal_open) {
- s = addr.mid(startpos,i-startpos);
- if (!s.isEmpty()) {
- list.append(s);
- qDebug("Appended %s",s.latin1());
- }
- // !!!! this is a MUST BE!
- startpos = ++i;
- }
- break;
- default:
- break;
- }
- }
- s = addr.mid(startpos,i-startpos);
- if (!s.isEmpty()) {
- list.append(s);
- qDebug("Appended %s",s.latin1());
- }
- QStringList::Iterator it;
- for ( it = list.begin(); it != list.end(); it++ ) {
- int err = mailimf_address_list_add_parse( addresses, (char*)(*it).latin1() );
- if ( err != MAILIMF_NO_ERROR ) {
- qDebug( "Error parsing" );
- qDebug( *it );
- } else {
- qDebug( "Parse success! %s",(*it).latin1());
- }
- }
- return addresses;
-}
-
-mailimf_fields *SMTPwrapper::createImfFields(const Mail&mail ) {
- mailimf_fields *fields;
- mailimf_field *xmailer;
- mailimf_mailbox *sender=0,*fromBox=0;
- mailimf_mailbox_list *from=0;
- mailimf_address_list *to=0, *cc=0, *bcc=0, *reply=0;
- clist*in_reply_to = 0;
- 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() );
-
- if (mail.Inreply().count()>0) {
- in_reply_to = clist_new();
- char*c_reply;
- unsigned int nsize = 0;
- for (QStringList::ConstIterator it=mail.Inreply().begin();
- it != mail.Inreply().end();++it) {
- /* yes! must be malloc! */
- if ((*it).isEmpty())
- continue;
- QString h((*it));
- while (h.length()>0 && h[0]=='<') {
- h.remove(0,1);
- }
- while (h.length()>0 && h[h.length()-1]=='>') {
- h.remove(h.length()-1,1);
- }
- if (h.isEmpty()) continue;
- nsize = strlen(h.latin1());
- c_reply = (char*)malloc( (nsize+1)*sizeof(char));
- memset(c_reply,0,nsize+1);
- memcpy(c_reply,h.latin1(),nsize);
- clist_append(in_reply_to,c_reply);
- qDebug("In reply to: %s",c_reply);
- }
- }
-
- fields = mailimf_fields_new_with_data( from, sender, reply, to, cc, bcc,
- in_reply_to, 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:
- if (xmailer)
- mailimf_field_free( xmailer );
-err_free_fields:
- if (fields)
- mailimf_fields_free( fields );
-err_free_reply:
- if (reply)
- mailimf_address_list_free( reply );
- if (bcc)
- mailimf_address_list_free( bcc );
- if (cc)
- mailimf_address_list_free( cc );
- if (to)
- mailimf_address_list_free( to );
-err_free_from:
- if (from)
- mailimf_mailbox_list_free( from );
-err_free_fromBox:
- mailimf_mailbox_free( fromBox );
-err_free_sender:
- if (sender)
- mailimf_mailbox_free( sender );
-err_free:
- if (subject)
- 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;
- 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, (char*)str.data(), str.length() );
- 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:
- qDebug( "buildTxtPart - error" );
-
- return NULL; // Error :(
-}
-
-mailmime *SMTPwrapper::buildFilePart(const QString&filename,const QString&mimetype,const QString&TextContent ) {
- mailmime * filePart = 0;
- mailmime_fields * fields = 0;
- mailmime_content * content = 0;
- mailmime_parameter * param = 0;
- char*name = 0;
- char*file = 0;
- int err;
-
- int pos = filename.findRev( '/' );
-
- if (filename.length()>0) {
- QString tmp = filename.right( filename.length() - ( pos + 1 ) );
- name = strdup( tmp.latin1() ); // just filename
- file = strdup( filename.latin1() ); // full name with path
- }
-
- int disptype = MAILMIME_DISPOSITION_TYPE_ATTACHMENT;
- int mechanism = MAILMIME_MECHANISM_BASE64;
-
- if ( mimetype.startsWith( "text/" ) ) {
- param = mailmime_parameter_new( strdup( "charset" ),
- strdup( "iso-8859-1" ) );
- mechanism = MAILMIME_MECHANISM_QUOTED_PRINTABLE;
- }
-
- fields = mailmime_fields_new_filename(
- disptype, name,
- mechanism );
- content = mailmime_content_new_with_str( (char*)mimetype.latin1() );
- if (content!=0 && fields != 0) {
- if (param) {
- clist_append(content->ct_parameters,param);
- param = 0;
- }
- if (filename.length()>0) {
- QFileInfo f(filename);
- param = mailmime_parameter_new(strdup("name"),strdup(f.fileName().latin1()));
- clist_append(content->ct_parameters,param);
- param = 0;
- }
- filePart = mailmime_new_empty( content, fields );
- }
- if (filePart) {
- if (filename.length()>0) {
- err = mailmime_set_body_file( filePart, file );
- } else {
- err = mailmime_set_body_text(filePart,strdup(TextContent.data()),TextContent.length());
- }
- if (err != MAILIMF_NO_ERROR) {
- qDebug("Error setting body with file %s",file);
- mailmime_free( filePart );
- filePart = 0;
- }
- }
-
- if (!filePart) {
- if ( param != NULL ) {
- mailmime_parameter_free( param );
- }
- if (content) {
- mailmime_content_free( content );
- }
- if (fields) {
- mailmime_fields_free( fields );
- } else {
- if (name) {
- free( name );
- }
- if (file) {
- free( file );
- }
- }
- }
- return filePart; // Success :)
-
-}
-
-void SMTPwrapper::addFileParts( mailmime *message,const QList<Attachment>&files ) {
- const Attachment *it;
- unsigned int count = files.count();
- qDebug("List contains %i values",count);
- for ( unsigned int i = 0; i < count; ++i ) {
- qDebug( "Adding file" );
- mailmime *filePart;
- int err;
- it = ((QList<Attachment>)files).at(i);
-
- filePart = buildFilePart( it->getFileName(), it->getMimeType(),"" );
- if ( filePart == NULL ) {
- qDebug( "addFileParts: error adding file:" );
- qDebug( it->getFileName() );
- continue;
- }
- err = mailmime_smart_add_part( message, filePart );
- if ( err != MAILIMF_NO_ERROR ) {
- mailmime_free( filePart );
- qDebug("error smart add");
- }
- }
-}
-
-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( mailimf_field *ffrom) {
- char *from = NULL;
- 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;
-}
-
-char *SMTPwrapper::getFrom( mailmime *mail ) {
- /* no need to delete - its just a pointer to structure content */
- mailimf_field *ffrom = 0;
- ffrom = getField( mail->mm_data.mm_message.mm_fields, MAILIMF_FIELD_FROM );
- return getFrom(ffrom);
-}
void SMTPwrapper::progress( size_t current, size_t maximum ) {
if (SMTPwrapper::sendProgress) {
SMTPwrapper::sendProgress->setSingleMail(current, maximum );
qApp->processEvents();
}
}
void SMTPwrapper::storeMail(const char*mail, size_t length, const QString&box) {
if (!mail)
return;
QString localfolders = AbstractMail::defaultLocalfolder();
AbstractMail*wrap = AbstractMail::getWrapper(localfolders);
wrap->createMbox(box);
wrap->storeMessage(mail,length,box);
delete wrap;
}
void SMTPwrapper::smtpSend( mailmime *mail,bool later) {
clist *rcpts = 0;
char *from, *data;
size_t size;
from = data = 0;
mailmessage * msg = 0;
msg = mime_message_init(mail);
mime_message_set_tmpdir(msg,getenv( "HOME" ));
int r = mailmessage_fetch(msg,&data,&size);
mime_message_detach_mime(msg);
mailmessage_free(msg);
if (r != MAIL_NO_ERROR || !data) {
if (data)
free(data);
qDebug("Error fetching mime...");
return;
}
msg = 0;
if (later) {
storeMail(data,size,"Outgoing");
if (data)
free( data );
Config cfg( "mail" );
cfg.setGroup( "Status" );
cfg.writeEntry( "outgoing", ++m_queuedMail );
emit queuedMails( m_queuedMail );
return;
}
from = getFrom( mail );
rcpts = createRcptList( mail->mm_data.mm_message.mm_fields );
smtpSend(from,rcpts,data,size);
if (data) {
free(data);
}
if (from) {
free(from);
}
if (rcpts)
smtp_address_list_free( rcpts );
}
void SMTPwrapper::storeFailedMail(const char*data,unsigned int size, const char*failuremessage)
{
if (data) {
storeMail(data,size,"Sendfailed");
}
if (failuremessage) {
QMessageBox::critical(0,tr("Error sending mail"),
tr("<center>%1</center>").arg(failuremessage));
}
}
int SMTPwrapper::start_smtp_tls()
{
if (!m_smtp) {
return MAILSMTP_ERROR_IN_PROCESSING;
}
int err = mailesmtp_starttls(m_smtp);
if (err != MAILSMTP_NO_ERROR) return err;
mailstream_low * low;
mailstream_low * new_low;
low = mailstream_get_low(m_smtp->stream);
if (!low) {
return MAILSMTP_ERROR_IN_PROCESSING;
}
int fd = mailstream_low_get_fd(low);
if (fd > -1 && (new_low = mailstream_low_ssl_open(fd))!=0) {
mailstream_low_free(low);
mailstream_set_low(m_smtp->stream, new_low);
} else {
return MAILSMTP_ERROR_IN_PROCESSING;
}
return err;
}
void SMTPwrapper::connect_server()
{
const char *server, *user, *pass;
bool ssl;
uint16_t port;
ssl = false;
bool try_tls = true;
bool force_tls=false;
server = user = pass = 0;
QString failuretext = "";
-
+
if (m_smtp || !m_SmtpAccount) {
return;
}
server = m_SmtpAccount->getServer().latin1();
if ( m_SmtpAccount->ConnectionType() == 2 ) {
ssl = true;
try_tls = false;
} else if (m_SmtpAccount->ConnectionType() == 1) {
force_tls = true;
}
int result = 1;
port = m_SmtpAccount->getPort().toUInt();
m_smtp = mailsmtp_new( 20, &progress );
if ( m_smtp == NULL ) {
/* no failure message cause this happens when problems with memory - than we
we can not display any messagebox */
return;
}
int err = MAILSMTP_NO_ERROR;
qDebug( "Servername %s at port %i", server, port );
if ( ssl ) {
qDebug( "SSL session" );
err = mailsmtp_ssl_connect( m_smtp, server, port );
} else {
qDebug( "No SSL session" );
err = mailsmtp_socket_connect( m_smtp, server, port );
}
if ( err != MAILSMTP_NO_ERROR ) {
qDebug("Error init connection");
failuretext = tr("Error init SMTP connection: %1").arg(mailsmtpError(err));
result = 0;
}
/* switch to tls after init 'cause there it will send the ehlo */
if (result) {
err = mailsmtp_init( m_smtp );
if (err != MAILSMTP_NO_ERROR) {
result = 0;
failuretext = tr("Error init SMTP connection: %1").arg(mailsmtpError(err));
}
}
if (try_tls) {
err = start_smtp_tls();
if (err != MAILSMTP_NO_ERROR) {
try_tls = false;
} else {
err = mailesmtp_ehlo(m_smtp);
}
}
if (!try_tls && force_tls) {
result = 0;
failuretext = tr("Error init SMTP tls: %1").arg(mailsmtpError(err));
}
if (result==1 && m_SmtpAccount->getLogin() ) {
qDebug("smtp with auth");
if ( m_SmtpAccount->getUser().isEmpty() || m_SmtpAccount->getPassword().isEmpty() ) {
// get'em
- LoginDialog login( m_SmtpAccount->getUser(),
+ LoginDialog login( m_SmtpAccount->getUser(),
m_SmtpAccount->getPassword(), NULL, 0, true );
login.show();
if ( QDialog::Accepted == login.exec() ) {
// ok
user = login.getUser().latin1();
pass = login.getPassword().latin1();
} else {
result = 0;
failuretext=tr("Login aborted - storing mail to localfolder");
}
} else {
user = m_SmtpAccount->getUser().latin1();
pass = m_SmtpAccount->getPassword().latin1();
}
qDebug( "session->auth: %i", m_smtp->auth);
if (result) {
err = mailsmtp_auth( m_smtp, (char*)user, (char*)pass );
if ( err == MAILSMTP_NO_ERROR ) {
qDebug("auth ok");
} else {
failuretext = tr("Authentification failed");
result = 0;
}
}
}
}
void SMTPwrapper::disc_server()
{
if (m_smtp) {
mailsmtp_quit( m_smtp );
mailsmtp_free( m_smtp );
m_smtp = 0;
}
}
int SMTPwrapper::smtpSend(char*from,clist*rcpts,const char*data,size_t size )
{
int err,result;
QString failuretext = "";
connect_server();
result = 1;
if (m_smtp) {
err = mailsmtp_send( m_smtp, from, rcpts, data, size );
if ( err != MAILSMTP_NO_ERROR ) {
failuretext=tr("Error sending mail: %1").arg(mailsmtpError(err));
result = 0;
}
} else {
result = 0;
}
if (!result) {
storeFailedMail(data,size,failuretext);
} else {
qDebug( "Mail sent." );
storeMail(data,size,"Sent");
}
return result;
}
void SMTPwrapper::sendMail(const Mail&mail,bool later )
{
mailmime * mimeMail;
mimeMail = createMimeMail(mail );
if ( mimeMail == NULL ) {
qDebug( "sendMail: error creating mime mail" );
} else {
sendProgress = new progressMailSend();
sendProgress->show();
sendProgress->setMaxMails(1);
smtpSend( mimeMail,later);
qDebug("Clean up done");
sendProgress->hide();
delete sendProgress;
sendProgress = 0;
mailmime_free( mimeMail );
}
}
int SMTPwrapper::sendQueuedMail(AbstractMail*wrap,RecMail*which) {
size_t curTok = 0;
mailimf_fields *fields = 0;
mailimf_field*ffrom = 0;
clist *rcpts = 0;
char*from = 0;
int res = 0;
encodedString * data = wrap->fetchRawBody(*which);
if (!data)
return 0;
int err = mailimf_fields_parse( data->Content(), data->Length(), &curTok, &fields );
if (err != MAILIMF_NO_ERROR) {
diff --git a/noncore/net/mail/libmailwrapper/smtpwrapper.h b/noncore/net/mail/libmailwrapper/smtpwrapper.h
index 7f6aac1..1796df7 100644
--- a/noncore/net/mail/libmailwrapper/smtpwrapper.h
+++ b/noncore/net/mail/libmailwrapper/smtpwrapper.h
@@ -1,83 +1,61 @@
// -*- Mode: C++; -*-
#ifndef SMTPwrapper_H
#define SMTPwrapper_H
#include <qpe/applnk.h>
#include <qbitarray.h>
#include <qdatetime.h>
#include <libetpan/clist.h>
#include "settings.h"
+#include "generatemail.h"
-class Mail;
-class AbstractMail;
-class RecMail;
-class Attachment;
-struct mailimf_fields;
-struct mailimf_field;
-struct mailimf_mailbox;
-struct mailmime;
-struct mailimf_address_list;
-class progressMailSend;
-struct mailsmtp;
class SMTPaccount;
+class AbstractMail;
-class SMTPwrapper : public QObject
+class SMTPwrapper : public Generatemail
{
Q_OBJECT
public:
SMTPwrapper(SMTPaccount * aSmtp);
virtual ~SMTPwrapper();
void sendMail(const Mail& mail,bool later=false );
bool flushOutbox();
static progressMailSend*sendProgress;
signals:
void queuedMails( int );
protected:
mailsmtp *m_smtp;
SMTPaccount * m_SmtpAccount;
void connect_server();
void disc_server();
int start_smtp_tls();
-
- 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,const QString&content);
+
+
void smtpSend( mailmime *mail,bool later);
- clist *createRcptList( mailimf_fields *fields );
static void storeMail(const char*mail, size_t length, const QString&box);
static QString mailsmtpError( int err );
static void progress( size_t current, size_t maximum );
- static void addRcpts( clist *list, mailimf_address_list *addr_list );
- static char *getFrom( mailmime *mail );
- static char *getFrom( mailimf_field *ffrom);
- static mailimf_field *getField( mailimf_fields *fields, int type );
int smtpSend(char*from,clist*rcpts,const char*data,size_t size);
void storeMail(mailmime*mail, const QString&box);
int sendQueuedMail(AbstractMail*wrap,RecMail*which);
void storeFailedMail(const char*data,unsigned int size, const char*failuremessage);
int m_queuedMail;
- static const char* USER_AGENT;
protected slots:
void emitQCop( int queued );
};
#endif