summaryrefslogtreecommitdiff
Unidiff
Diffstat (more/less context) (ignore whitespace changes)
-rw-r--r--noncore/net/mail/abstractmail.cpp1
-rw-r--r--noncore/net/mail/composemail.cpp3
-rw-r--r--noncore/net/mail/imapwrapper.cpp3
-rw-r--r--noncore/net/mail/imapwrapper.h1
-rw-r--r--noncore/net/mail/libmailwrapper/abstractmail.cpp1
-rw-r--r--noncore/net/mail/libmailwrapper/imapwrapper.cpp3
-rw-r--r--noncore/net/mail/libmailwrapper/imapwrapper.h1
-rw-r--r--noncore/net/mail/libmailwrapper/mailwrapper.cpp585
-rw-r--r--noncore/net/mail/libmailwrapper/mailwrapper.h35
-rw-r--r--noncore/net/mail/libmailwrapper/pop3wrapper.h6
-rw-r--r--noncore/net/mail/libmailwrapper/smtpwrapper.cpp604
-rw-r--r--noncore/net/mail/libmailwrapper/smtpwrapper.h53
-rw-r--r--noncore/net/mail/mail.pro6
-rw-r--r--noncore/net/mail/mailwrapper.cpp585
-rw-r--r--noncore/net/mail/mailwrapper.h35
-rw-r--r--noncore/net/mail/pop3wrapper.h6
-rw-r--r--noncore/net/mail/smtpwrapper.cpp604
-rw-r--r--noncore/net/mail/smtpwrapper.h53
18 files changed, 1340 insertions, 1245 deletions
diff --git a/noncore/net/mail/abstractmail.cpp b/noncore/net/mail/abstractmail.cpp
index 626b9aa..3cb8f7d 100644
--- a/noncore/net/mail/abstractmail.cpp
+++ b/noncore/net/mail/abstractmail.cpp
@@ -1,83 +1,84 @@
1#include "abstractmail.h" 1#include "abstractmail.h"
2#include "imapwrapper.h" 2#include "imapwrapper.h"
3#include "pop3wrapper.h" 3#include "pop3wrapper.h"
4#include "mailtypes.h" 4#include "mailtypes.h"
5 5
6#include <qstring.h> 6#include <qstring.h>
7#include <qfile.h> 7#include <qfile.h>
8#include <qtextstream.h> 8#include <qtextstream.h>
9#include <stdlib.h> 9#include <stdlib.h>
10#include <libetpan/mailmime_content.h> 10#include <libetpan/mailmime_content.h>
11#include <libetpan/mailmime.h>
11 12
12AbstractMail* AbstractMail::getWrapper(IMAPaccount *a) 13AbstractMail* AbstractMail::getWrapper(IMAPaccount *a)
13{ 14{
14 return new IMAPwrapper(a); 15 return new IMAPwrapper(a);
15} 16}
16 17
17AbstractMail* AbstractMail::getWrapper(POP3account *a) 18AbstractMail* AbstractMail::getWrapper(POP3account *a)
18{ 19{
19 return new POP3wrapper(a); 20 return new POP3wrapper(a);
20} 21}
21 22
22encodedString* AbstractMail::decode_String(const encodedString*text,const QString&enc) 23encodedString* AbstractMail::decode_String(const encodedString*text,const QString&enc)
23{ 24{
24 qDebug("Decode string start"); 25 qDebug("Decode string start");
25 char*result_text; 26 char*result_text;
26 size_t index = 0; 27 size_t index = 0;
27 /* reset for recursive use! */ 28 /* reset for recursive use! */
28 size_t target_length = 0; 29 size_t target_length = 0;
29 result_text = 0; 30 result_text = 0;
30 int mimetype = MAILMIME_MECHANISM_7BIT; 31 int mimetype = MAILMIME_MECHANISM_7BIT;
31 if (enc.lower()=="quoted-printable") { 32 if (enc.lower()=="quoted-printable") {
32 mimetype = MAILMIME_MECHANISM_QUOTED_PRINTABLE; 33 mimetype = MAILMIME_MECHANISM_QUOTED_PRINTABLE;
33 } else if (enc.lower()=="base64") { 34 } else if (enc.lower()=="base64") {
34 mimetype = MAILMIME_MECHANISM_BASE64; 35 mimetype = MAILMIME_MECHANISM_BASE64;
35 } else if (enc.lower()=="8bit") { 36 } else if (enc.lower()=="8bit") {
36 mimetype = MAILMIME_MECHANISM_8BIT; 37 mimetype = MAILMIME_MECHANISM_8BIT;
37 } else if (enc.lower()=="binary") { 38 } else if (enc.lower()=="binary") {
38 mimetype = MAILMIME_MECHANISM_BINARY; 39 mimetype = MAILMIME_MECHANISM_BINARY;
39 } 40 }
40 41
41 int err = mailmime_part_parse(text->Content(),text->Length(),&index,mimetype, 42 int err = mailmime_part_parse(text->Content(),text->Length(),&index,mimetype,
42 &result_text,&target_length); 43 &result_text,&target_length);
43 44
44 encodedString* result = new encodedString(); 45 encodedString* result = new encodedString();
45 if (err == MAILIMF_NO_ERROR) { 46 if (err == MAILIMF_NO_ERROR) {
46 result->setContent(result_text,target_length); 47 result->setContent(result_text,target_length);
47 } 48 }
48 qDebug("Decode string finished"); 49 qDebug("Decode string finished");
49 return result; 50 return result;
50} 51}
51 52
52QString AbstractMail::convert_String(const char*text) 53QString AbstractMail::convert_String(const char*text)
53{ 54{
54 size_t index = 0; 55 size_t index = 0;
55 char*res = 0; 56 char*res = 0;
56 57
57 /* attention - doesn't work with arm systems! */ 58 /* attention - doesn't work with arm systems! */
58 int err = mailmime_encoded_phrase_parse("iso-8859-1", 59 int err = mailmime_encoded_phrase_parse("iso-8859-1",
59 text, strlen(text),&index, "iso-8859-1",&res); 60 text, strlen(text),&index, "iso-8859-1",&res);
60 if (err != MAILIMF_NO_ERROR) { 61 if (err != MAILIMF_NO_ERROR) {
61 if (res) free(res); 62 if (res) free(res);
62 return QString(text); 63 return QString(text);
63 } 64 }
64 if (res) { 65 if (res) {
65 QString result(res); 66 QString result(res);
66 free(res); 67 free(res);
67 return result; 68 return result;
68 } 69 }
69 return QString(text); 70 return QString(text);
70} 71}
71 72
72/* cp & paste from launcher */ 73/* cp & paste from launcher */
73QString AbstractMail::gen_attachment_id() 74QString AbstractMail::gen_attachment_id()
74{ 75{
75 QFile file( "/proc/sys/kernel/random/uuid" ); 76 QFile file( "/proc/sys/kernel/random/uuid" );
76 if (!file.open(IO_ReadOnly ) ) 77 if (!file.open(IO_ReadOnly ) )
77 return QString::null; 78 return QString::null;
78 79
79 QTextStream stream(&file); 80 QTextStream stream(&file);
80 81
81 return "{" + stream.read().stripWhiteSpace() + "}"; 82 return "{" + stream.read().stripWhiteSpace() + "}";
82} 83}
83 84
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 @@
1#include <qt.h> 1#include <qt.h>
2 2
3#include <opie/ofiledialog.h> 3#include <opie/ofiledialog.h>
4#include <qpe/resource.h> 4#include <qpe/resource.h>
5 5
6#include "composemail.h" 6#include "composemail.h"
7#include "smtpwrapper.h"
7 8
8ComposeMail::ComposeMail( Settings *s, QWidget *parent, const char *name, bool modal, WFlags flags ) 9ComposeMail::ComposeMail( Settings *s, QWidget *parent, const char *name, bool modal, WFlags flags )
9 : ComposeMailUI( parent, name, modal, flags ) 10 : ComposeMailUI( parent, name, modal, flags )
10{ 11{
11 settings = s; 12 settings = s;
12 13
13 attList->addColumn( tr( "Name" ) ); 14 attList->addColumn( tr( "Name" ) );
14 attList->addColumn( tr( "Size" ) ); 15 attList->addColumn( tr( "Size" ) );
15 16
16 QList<Account> accounts = settings->getAccounts(); 17 QList<Account> accounts = settings->getAccounts();
17 Account *it; 18 Account *it;
18 for ( it = accounts.first(); it; it = accounts.next() ) { 19 for ( it = accounts.first(); it; it = accounts.next() ) {
19 if ( it->getType().compare( "SMTP" ) == 0 ) { 20 if ( it->getType().compare( "SMTP" ) == 0 ) {
20 SMTPaccount *smtp = static_cast<SMTPaccount *>(it); 21 SMTPaccount *smtp = static_cast<SMTPaccount *>(it);
21 fromBox->insertItem( smtp->getMail() ); 22 fromBox->insertItem( smtp->getMail() );
22 smtpAccounts.append( smtp ); 23 smtpAccounts.append( smtp );
23 } 24 }
24 } 25 }
25 26
26 if ( smtpAccounts.count() > 0 ) { 27 if ( smtpAccounts.count() > 0 ) {
27 fillValues( fromBox->currentItem() ); 28 fillValues( fromBox->currentItem() );
28 } else { 29 } else {
29 QMessageBox::information( this, tr( "Problem" ), 30 QMessageBox::information( this, tr( "Problem" ),
30 tr( "<p>Please create an SMTP account first.</p>" ), 31 tr( "<p>Please create an SMTP account first.</p>" ),
31 tr( "Ok" ) ); 32 tr( "Ok" ) );
32 } 33 }
33 34
34 connect( fromBox, SIGNAL( activated( int ) ), SLOT( fillValues( int ) ) ); 35 connect( fromBox, SIGNAL( activated( int ) ), SLOT( fillValues( int ) ) );
35 connect( toButton, SIGNAL( clicked() ), SLOT( pickAddressTo() ) ); 36 connect( toButton, SIGNAL( clicked() ), SLOT( pickAddressTo() ) );
36 connect( ccButton, SIGNAL( clicked() ), SLOT( pickAddressCC() ) ); 37 connect( ccButton, SIGNAL( clicked() ), SLOT( pickAddressCC() ) );
37 connect( bccButton, SIGNAL( clicked() ), SLOT( pickAddressBCC() ) ); 38 connect( bccButton, SIGNAL( clicked() ), SLOT( pickAddressBCC() ) );
38 connect( replyButton, SIGNAL( clicked() ), SLOT( pickAddressReply() ) ); 39 connect( replyButton, SIGNAL( clicked() ), SLOT( pickAddressReply() ) );
39 connect( addButton, SIGNAL( clicked() ), SLOT( addAttachment() ) ); 40 connect( addButton, SIGNAL( clicked() ), SLOT( addAttachment() ) );
40 connect( deleteButton, SIGNAL( clicked() ), SLOT( removeAttachment() ) ); 41 connect( deleteButton, SIGNAL( clicked() ), SLOT( removeAttachment() ) );
41} 42}
42 43
43void ComposeMail::pickAddress( QLineEdit *line ) 44void ComposeMail::pickAddress( QLineEdit *line )
44{ 45{
45 QString names = AddressPicker::getNames(); 46 QString names = AddressPicker::getNames();
46 if ( line->text().isEmpty() ) { 47 if ( line->text().isEmpty() ) {
47 line->setText( names ); 48 line->setText( names );
48 } else if ( !names.isEmpty() ) { 49 } else if ( !names.isEmpty() ) {
49 line->setText( line->text() + ", " + names ); 50 line->setText( line->text() + ", " + names );
50 } 51 }
51} 52}
52 53
53 54
54void ComposeMail::setTo( const QString & to ) 55void ComposeMail::setTo( const QString & to )
55{ 56{
56/* QString toline; 57/* QString toline;
57 QStringList toEntry = to; 58 QStringList toEntry = to;
58 for ( QStringList::Iterator it = toEntry.begin(); it != toEntry.end(); ++it ) { 59 for ( QStringList::Iterator it = toEntry.begin(); it != toEntry.end(); ++it ) {
59 toline += (*it); 60 toline += (*it);
60 } 61 }
61 toLine->setText( toline ); 62 toLine->setText( toline );
62*/ 63*/
63toLine->setText( to ); 64toLine->setText( to );
64} 65}
65 66
66void ComposeMail::setSubject( const QString & subject ) 67void ComposeMail::setSubject( const QString & subject )
67{ 68{
68 subjectLine->setText( subject ); 69 subjectLine->setText( subject );
69} 70}
70 71
71void ComposeMail::setInReplyTo( const QString & messageId ) 72void ComposeMail::setInReplyTo( const QString & messageId )
72{ 73{
73 74
74} 75}
75 76
76void ComposeMail::setMessage( const QString & text ) 77void ComposeMail::setMessage( const QString & text )
77{ 78{
78 message->setText( text ); 79 message->setText( text );
79} 80}
80 81
81 82
82void ComposeMail::pickAddressTo() 83void ComposeMail::pickAddressTo()
83{ 84{
84 pickAddress( toLine ); 85 pickAddress( toLine );
85} 86}
86 87
87void ComposeMail::pickAddressCC() 88void ComposeMail::pickAddressCC()
88{ 89{
89 pickAddress( ccLine ); 90 pickAddress( ccLine );
90} 91}
91 92
92void ComposeMail::pickAddressBCC() 93void ComposeMail::pickAddressBCC()
93{ 94{
94 pickAddress( bccLine ); 95 pickAddress( bccLine );
95} 96}
96 97
97void ComposeMail::pickAddressReply() 98void ComposeMail::pickAddressReply()
98{ 99{
99 pickAddress( replyLine ); 100 pickAddress( replyLine );
100} 101}
101 102
102void ComposeMail::fillValues( int current ) 103void ComposeMail::fillValues( int current )
103{ 104{
104 SMTPaccount *smtp = smtpAccounts.at( current ); 105 SMTPaccount *smtp = smtpAccounts.at( current );
105 106
106 ccLine->clear(); 107 ccLine->clear();
107 if ( smtp->getUseCC() ) { 108 if ( smtp->getUseCC() ) {
108 ccLine->setText( smtp->getCC() ); 109 ccLine->setText( smtp->getCC() );
109 } 110 }
110 bccLine->clear(); 111 bccLine->clear();
111 if ( smtp->getUseBCC() ) { 112 if ( smtp->getUseBCC() ) {
112 bccLine->setText( smtp->getBCC() ); 113 bccLine->setText( smtp->getBCC() );
113 } 114 }
114 replyLine->clear(); 115 replyLine->clear();
115 if ( smtp->getUseReply() ) { 116 if ( smtp->getUseReply() ) {
116 replyLine->setText( smtp->getReply() ); 117 replyLine->setText( smtp->getReply() );
117 } 118 }
118 119
119 sigMultiLine->setText( smtp->getSignature() ); 120 sigMultiLine->setText( smtp->getSignature() );
120} 121}
121 122
122void ComposeMail::slotAdjustColumns() 123void ComposeMail::slotAdjustColumns()
123{ 124{
124 int currPage = tabWidget->currentPageIndex(); 125 int currPage = tabWidget->currentPageIndex();
125 126
126 tabWidget->showPage( attachTab ); 127 tabWidget->showPage( attachTab );
127 attList->setColumnWidth( 0, attList->visibleWidth() - 80 ); 128 attList->setColumnWidth( 0, attList->visibleWidth() - 80 );
128 attList->setColumnWidth( 1, 80 ); 129 attList->setColumnWidth( 1, 80 );
129 130
130 tabWidget->setCurrentPage( currPage ); 131 tabWidget->setCurrentPage( currPage );
131} 132}
132 133
133void ComposeMail::addAttachment() 134void ComposeMail::addAttachment()
134{ 135{
135 DocLnk lnk = OFileDialog::getOpenFileName( 1, "/" ); 136 DocLnk lnk = OFileDialog::getOpenFileName( 1, "/" );
136 if ( !lnk.name().isEmpty() ) { 137 if ( !lnk.name().isEmpty() ) {
137 Attachment *att = new Attachment( lnk ); 138 Attachment *att = new Attachment( lnk );
138 (void) new AttachViewItem( attList, att ); 139 (void) new AttachViewItem( attList, att );
139 } 140 }
140} 141}
141 142
142void ComposeMail::removeAttachment() 143void ComposeMail::removeAttachment()
143{ 144{
144 if ( !attList->currentItem() ) { 145 if ( !attList->currentItem() ) {
145 QMessageBox::information( this, tr( "Error" ), 146 QMessageBox::information( this, tr( "Error" ),
146 tr( "<p>Please select a File.</p>" ), 147 tr( "<p>Please select a File.</p>" ),
147 tr( "Ok" ) ); 148 tr( "Ok" ) );
148 } else { 149 } else {
149 attList->takeItem( attList->currentItem() ); 150 attList->takeItem( attList->currentItem() );
150 } 151 }
151} 152}
152 153
153void ComposeMail::accept() 154void ComposeMail::accept()
154{ 155{
155 qDebug( "Sending Mail with " + 156 qDebug( "Sending Mail with " +
156 smtpAccounts.at( fromBox->currentItem() )->getAccountName() ); 157 smtpAccounts.at( fromBox->currentItem() )->getAccountName() );
157 Mail *mail = new Mail(); 158 Mail *mail = new Mail();
158 SMTPaccount *smtp = smtpAccounts.at( fromBox->currentItem() ); 159 SMTPaccount *smtp = smtpAccounts.at( fromBox->currentItem() );
159 mail->setMail( smtp->getMail() ); 160 mail->setMail( smtp->getMail() );
160 mail->setName( smtp->getName() ); 161 mail->setName( smtp->getName() );
161 162
162 if ( !toLine->text().isEmpty() ) { 163 if ( !toLine->text().isEmpty() ) {
163 mail->setTo( toLine->text() ); 164 mail->setTo( toLine->text() );
164 } else { 165 } else {
165 qDebug( "No Reciever spezified -> returning" ); 166 qDebug( "No Reciever spezified -> returning" );
166 return; 167 return;
167 } 168 }
168 169
169 mail->setCC( ccLine->text() ); 170 mail->setCC( ccLine->text() );
170 mail->setBCC( bccLine->text() ); 171 mail->setBCC( bccLine->text() );
171 mail->setReply( replyLine->text() ); 172 mail->setReply( replyLine->text() );
172 mail->setSubject( subjectLine->text() ); 173 mail->setSubject( subjectLine->text() );
173 QString txt = message->text(); 174 QString txt = message->text();
174 if ( !sigMultiLine->text().isEmpty() ) { 175 if ( !sigMultiLine->text().isEmpty() ) {
175 txt.append( "\n--\n" ); 176 txt.append( "\n--\n" );
176 txt.append( sigMultiLine->text() ); 177 txt.append( sigMultiLine->text() );
177 } 178 }
178 mail->setMessage( txt ); 179 mail->setMessage( txt );
179 AttachViewItem *it = (AttachViewItem *) attList->firstChild(); 180 AttachViewItem *it = (AttachViewItem *) attList->firstChild();
180 while ( it != NULL ) { 181 while ( it != NULL ) {
181 mail->addAttachment( it->getAttachment() ); 182 mail->addAttachment( it->getAttachment() );
182 it = (AttachViewItem *) it->itemBelow(); 183 it = (AttachViewItem *) it->itemBelow();
183 } 184 }
184 185
185 MailWrapper wrapper( settings ); 186 SMTPwrapper wrapper( settings );
186 wrapper.sendMail( *mail ); 187 wrapper.sendMail( *mail );
187 188
188 QDialog::accept(); 189 QDialog::accept();
189} 190}
190 191
191AttachViewItem::AttachViewItem( QListView *parent, Attachment *att ) 192AttachViewItem::AttachViewItem( QListView *parent, Attachment *att )
192 : QListViewItem( parent ) 193 : QListViewItem( parent )
193{ 194{
194 attachment = att; 195 attachment = att;
195 qDebug( att->getMimeType() ); 196 qDebug( att->getMimeType() );
196 setPixmap( 0, attachment->getDocLnk().pixmap().isNull() ? 197 setPixmap( 0, attachment->getDocLnk().pixmap().isNull() ?
197 Resource::loadPixmap( "UnknownDocument-14" ) : 198 Resource::loadPixmap( "UnknownDocument-14" ) :
198 attachment->getDocLnk().pixmap() ); 199 attachment->getDocLnk().pixmap() );
199 setText( 0, att->getName().isEmpty() ? att->getFileName() : att->getName() ); 200 setText( 0, att->getName().isEmpty() ? att->getFileName() : att->getName() );
200 setText( 1, QString::number( att->getSize() ) ); 201 setText( 1, QString::number( att->getSize() ) );
201} 202}
202 203
diff --git a/noncore/net/mail/imapwrapper.cpp b/noncore/net/mail/imapwrapper.cpp
index cce3d34..30eb678 100644
--- a/noncore/net/mail/imapwrapper.cpp
+++ b/noncore/net/mail/imapwrapper.cpp
@@ -1,263 +1,264 @@
1 1
2#include <stdlib.h> 2#include <stdlib.h>
3 3
4#include <libetpan/mailimap.h>
5
4#include "imapwrapper.h" 6#include "imapwrapper.h"
5#include "mailtypes.h" 7#include "mailtypes.h"
6#include "logindialog.h" 8#include "logindialog.h"
7#include <libetpan/mailimap.h>
8 9
9IMAPwrapper::IMAPwrapper( IMAPaccount *a ) 10IMAPwrapper::IMAPwrapper( IMAPaccount *a )
10 : AbstractMail() 11 : AbstractMail()
11{ 12{
12 account = a; 13 account = a;
13 m_imap = 0; 14 m_imap = 0;
14} 15}
15 16
16IMAPwrapper::~IMAPwrapper() 17IMAPwrapper::~IMAPwrapper()
17{ 18{
18 logout(); 19 logout();
19} 20}
20 21
21void IMAPwrapper::imap_progress( size_t current, size_t maximum ) 22void IMAPwrapper::imap_progress( size_t current, size_t maximum )
22{ 23{
23 qDebug( "IMAP: %i of %i", current, maximum ); 24 qDebug( "IMAP: %i of %i", current, maximum );
24} 25}
25 26
26void IMAPwrapper::login() 27void IMAPwrapper::login()
27{ 28{
28 const char *server, *user, *pass; 29 const char *server, *user, *pass;
29 uint16_t port; 30 uint16_t port;
30 int err = MAILIMAP_NO_ERROR; 31 int err = MAILIMAP_NO_ERROR;
31 32
32 /* we are connected this moment */ 33 /* we are connected this moment */
33 /* TODO: setup a timer holding the line or if connection closed - delete the value */ 34 /* TODO: setup a timer holding the line or if connection closed - delete the value */
34 if (m_imap) { 35 if (m_imap) {
35 mailstream_flush(m_imap->imap_stream); 36 mailstream_flush(m_imap->imap_stream);
36 return; 37 return;
37 } 38 }
38 server = account->getServer().latin1(); 39 server = account->getServer().latin1();
39 port = account->getPort().toUInt(); 40 port = account->getPort().toUInt();
40 if ( account->getUser().isEmpty() || account->getPassword().isEmpty() ) { 41 if ( account->getUser().isEmpty() || account->getPassword().isEmpty() ) {
41 LoginDialog login( account->getUser(), account->getPassword(), NULL, 0, true ); 42 LoginDialog login( account->getUser(), account->getPassword(), NULL, 0, true );
42 login.show(); 43 login.show();
43 if ( QDialog::Accepted == login.exec() ) { 44 if ( QDialog::Accepted == login.exec() ) {
44 // ok 45 // ok
45 user = strdup( login.getUser().latin1() ); 46 user = strdup( login.getUser().latin1() );
46 pass = strdup( login.getPassword().latin1() ); 47 pass = strdup( login.getPassword().latin1() );
47 } else { 48 } else {
48 // cancel 49 // cancel
49 qDebug( "IMAP: Login canceled" ); 50 qDebug( "IMAP: Login canceled" );
50 return; 51 return;
51 } 52 }
52 } else { 53 } else {
53 user = account->getUser().latin1(); 54 user = account->getUser().latin1();
54 pass = account->getPassword().latin1(); 55 pass = account->getPassword().latin1();
55 } 56 }
56 57
57 m_imap = mailimap_new( 20, &imap_progress ); 58 m_imap = mailimap_new( 20, &imap_progress );
58 /* connect */ 59 /* connect */
59 if (account->getSSL()) { 60 if (account->getSSL()) {
60 err = mailimap_ssl_connect( m_imap, (char*)server, port ); 61 err = mailimap_ssl_connect( m_imap, (char*)server, port );
61 } else { 62 } else {
62 err = mailimap_socket_connect( m_imap, (char*)server, port ); 63 err = mailimap_socket_connect( m_imap, (char*)server, port );
63 } 64 }
64 65
65 if ( err != MAILIMAP_NO_ERROR && 66 if ( err != MAILIMAP_NO_ERROR &&
66 err != MAILIMAP_NO_ERROR_AUTHENTICATED && 67 err != MAILIMAP_NO_ERROR_AUTHENTICATED &&
67 err != MAILIMAP_NO_ERROR_NON_AUTHENTICATED ) { 68 err != MAILIMAP_NO_ERROR_NON_AUTHENTICATED ) {
68 qDebug("error connecting server: %s",m_imap->imap_response); 69 qDebug("error connecting server: %s",m_imap->imap_response);
69 mailimap_free( m_imap ); 70 mailimap_free( m_imap );
70 m_imap = 0; 71 m_imap = 0;
71 return; 72 return;
72 } 73 }
73 74
74 /* login */ 75 /* login */
75 err = mailimap_login_simple( m_imap, (char*)user, (char*)pass ); 76 err = mailimap_login_simple( m_imap, (char*)user, (char*)pass );
76 if ( err != MAILIMAP_NO_ERROR ) { 77 if ( err != MAILIMAP_NO_ERROR ) {
77 qDebug("error logging in imap: %s",m_imap->imap_response); 78 qDebug("error logging in imap: %s",m_imap->imap_response);
78 err = mailimap_close( m_imap ); 79 err = mailimap_close( m_imap );
79 mailimap_free( m_imap ); 80 mailimap_free( m_imap );
80 m_imap = 0; 81 m_imap = 0;
81 } 82 }
82} 83}
83 84
84void IMAPwrapper::logout() 85void IMAPwrapper::logout()
85{ 86{
86 int err = MAILIMAP_NO_ERROR; 87 int err = MAILIMAP_NO_ERROR;
87 if (!m_imap) return; 88 if (!m_imap) return;
88 err = mailimap_logout( m_imap ); 89 err = mailimap_logout( m_imap );
89 err = mailimap_close( m_imap ); 90 err = mailimap_close( m_imap );
90 mailimap_free( m_imap ); 91 mailimap_free( m_imap );
91 m_imap = 0; 92 m_imap = 0;
92} 93}
93 94
94void IMAPwrapper::listMessages(const QString&mailbox,QList<RecMail> &target ) 95void IMAPwrapper::listMessages(const QString&mailbox,QList<RecMail> &target )
95{ 96{
96 const char *mb; 97 const char *mb;
97 int err = MAILIMAP_NO_ERROR; 98 int err = MAILIMAP_NO_ERROR;
98 clist *result; 99 clist *result;
99 clistcell *current; 100 clistcell *current;
100// mailimap_fetch_att *fetchAtt,*fetchAttFlags,*fetchAttDate,*fetchAttSize; 101// mailimap_fetch_att *fetchAtt,*fetchAttFlags,*fetchAttDate,*fetchAttSize;
101 mailimap_fetch_type *fetchType; 102 mailimap_fetch_type *fetchType;
102 mailimap_set *set; 103 mailimap_set *set;
103 104
104 mb = mailbox.latin1(); 105 mb = mailbox.latin1();
105 login(); 106 login();
106 if (!m_imap) { 107 if (!m_imap) {
107 return; 108 return;
108 } 109 }
109 /* select mailbox READONLY for operations */ 110 /* select mailbox READONLY for operations */
110 err = mailimap_examine( m_imap, (char*)mb); 111 err = mailimap_examine( m_imap, (char*)mb);
111 if ( err != MAILIMAP_NO_ERROR ) { 112 if ( err != MAILIMAP_NO_ERROR ) {
112 qDebug("error selecting mailbox: %s",m_imap->imap_response); 113 qDebug("error selecting mailbox: %s",m_imap->imap_response);
113 return; 114 return;
114 } 115 }
115 116
116 int last = m_imap->imap_selection_info->sel_exists; 117 int last = m_imap->imap_selection_info->sel_exists;
117 118
118 if (last == 0) { 119 if (last == 0) {
119 qDebug("mailbox has no mails"); 120 qDebug("mailbox has no mails");
120 return; 121 return;
121 } 122 }
122 123
123 result = clist_new(); 124 result = clist_new();
124 /* the range has to start at 1!!! not with 0!!!! */ 125 /* the range has to start at 1!!! not with 0!!!! */
125 set = mailimap_set_new_interval( 1, last ); 126 set = mailimap_set_new_interval( 1, last );
126 fetchType = mailimap_fetch_type_new_fetch_att_list_empty(); 127 fetchType = mailimap_fetch_type_new_fetch_att_list_empty();
127 mailimap_fetch_type_new_fetch_att_list_add(fetchType,mailimap_fetch_att_new_envelope()); 128 mailimap_fetch_type_new_fetch_att_list_add(fetchType,mailimap_fetch_att_new_envelope());
128 mailimap_fetch_type_new_fetch_att_list_add(fetchType,mailimap_fetch_att_new_flags()); 129 mailimap_fetch_type_new_fetch_att_list_add(fetchType,mailimap_fetch_att_new_flags());
129 mailimap_fetch_type_new_fetch_att_list_add(fetchType,mailimap_fetch_att_new_internaldate()); 130 mailimap_fetch_type_new_fetch_att_list_add(fetchType,mailimap_fetch_att_new_internaldate());
130 mailimap_fetch_type_new_fetch_att_list_add(fetchType,mailimap_fetch_att_new_rfc822_size()); 131 mailimap_fetch_type_new_fetch_att_list_add(fetchType,mailimap_fetch_att_new_rfc822_size());
131 132
132 err = mailimap_fetch( m_imap, set, fetchType, &result ); 133 err = mailimap_fetch( m_imap, set, fetchType, &result );
133 mailimap_set_free( set ); 134 mailimap_set_free( set );
134 mailimap_fetch_type_free( fetchType ); 135 mailimap_fetch_type_free( fetchType );
135 136
136 QString date,subject,from; 137 QString date,subject,from;
137 138
138 if ( err == MAILIMAP_NO_ERROR ) { 139 if ( err == MAILIMAP_NO_ERROR ) {
139 140
140 mailimap_msg_att * msg_att; 141 mailimap_msg_att * msg_att;
141 int i = 0; 142 int i = 0;
142 for (current = clist_begin(result); current != 0; current=clist_next(current)) { 143 for (current = clist_begin(result); current != 0; current=clist_next(current)) {
143 ++i; 144 ++i;
144 msg_att = (mailimap_msg_att*)current->data; 145 msg_att = (mailimap_msg_att*)current->data;
145 RecMail*m = parse_list_result(msg_att); 146 RecMail*m = parse_list_result(msg_att);
146 if (m) { 147 if (m) {
147 m->setNumber(i); 148 m->setNumber(i);
148 m->setMbox(mailbox); 149 m->setMbox(mailbox);
149 m->setWrapper(this); 150 m->setWrapper(this);
150 target.append(m); 151 target.append(m);
151 } 152 }
152 } 153 }
153 } else { 154 } else {
154 qDebug("Error fetching headers: %s",m_imap->imap_response); 155 qDebug("Error fetching headers: %s",m_imap->imap_response);
155 } 156 }
156 mailimap_fetch_list_free(result); 157 mailimap_fetch_list_free(result);
157} 158}
158 159
159QList<Folder>* IMAPwrapper::listFolders() 160QList<Folder>* IMAPwrapper::listFolders()
160{ 161{
161 const char *path, *mask; 162 const char *path, *mask;
162 int err = MAILIMAP_NO_ERROR; 163 int err = MAILIMAP_NO_ERROR;
163 clist *result; 164 clist *result;
164 clistcell *current; 165 clistcell *current;
165 166
166 QList<Folder> * folders = new QList<Folder>(); 167 QList<Folder> * folders = new QList<Folder>();
167 folders->setAutoDelete( false ); 168 folders->setAutoDelete( false );
168 login(); 169 login();
169 if (!m_imap) { 170 if (!m_imap) {
170 return folders; 171 return folders;
171 } 172 }
172 173
173/* 174/*
174 * First we have to check for INBOX 'cause it sometimes it's not inside the path. 175 * First we have to check for INBOX 'cause it sometimes it's not inside the path.
175 * We must not forget to filter them out in next loop! 176 * We must not forget to filter them out in next loop!
176 * it seems like ugly code. and yes - it is ugly code. but the best way. 177 * it seems like ugly code. and yes - it is ugly code. but the best way.
177 */ 178 */
178 QString temp; 179 QString temp;
179 mask = "INBOX" ; 180 mask = "INBOX" ;
180 result = clist_new(); 181 result = clist_new();
181 mailimap_mailbox_list *list; 182 mailimap_mailbox_list *list;
182 err = mailimap_list( m_imap, (char*)"", (char*)mask, &result ); 183 err = mailimap_list( m_imap, (char*)"", (char*)mask, &result );
183 QString del; 184 QString del;
184 if ( err == MAILIMAP_NO_ERROR ) { 185 if ( err == MAILIMAP_NO_ERROR ) {
185 current = result->first; 186 current = result->first;
186 for ( int i = result->count; i > 0; i-- ) { 187 for ( int i = result->count; i > 0; i-- ) {
187 list = (mailimap_mailbox_list *) current->data; 188 list = (mailimap_mailbox_list *) current->data;
188 // it is better use the deep copy mechanism of qt itself 189 // it is better use the deep copy mechanism of qt itself
189 // instead of using strdup! 190 // instead of using strdup!
190 temp = list->mb_name; 191 temp = list->mb_name;
191 del = list->mb_delimiter; 192 del = list->mb_delimiter;
192 folders->append( new IMAPFolder(temp,del,true,account->getPrefix())); 193 folders->append( new IMAPFolder(temp,del,true,account->getPrefix()));
193 current = current->next; 194 current = current->next;
194 } 195 }
195 } else { 196 } else {
196 qDebug("error fetching folders: %s",m_imap->imap_response); 197 qDebug("error fetching folders: %s",m_imap->imap_response);
197 } 198 }
198 mailimap_list_result_free( result ); 199 mailimap_list_result_free( result );
199 200
200/* 201/*
201 * second stage - get the other then inbox folders 202 * second stage - get the other then inbox folders
202 */ 203 */
203 mask = "*" ; 204 mask = "*" ;
204 path = account->getPrefix().latin1(); 205 path = account->getPrefix().latin1();
205 if (!path) path = ""; 206 if (!path) path = "";
206 result = clist_new(); 207 result = clist_new();
207 qDebug(path); 208 qDebug(path);
208 bool selectable = true; 209 bool selectable = true;
209 mailimap_mbx_list_flags*bflags; 210 mailimap_mbx_list_flags*bflags;
210 err = mailimap_list( m_imap, (char*)path, (char*)mask, &result ); 211 err = mailimap_list( m_imap, (char*)path, (char*)mask, &result );
211 if ( err == MAILIMAP_NO_ERROR ) { 212 if ( err == MAILIMAP_NO_ERROR ) {
212 current = result->first; 213 current = result->first;
213 for ( current=clist_begin(result);current!=NULL;current=clist_next(current)) { 214 for ( current=clist_begin(result);current!=NULL;current=clist_next(current)) {
214 list = (mailimap_mailbox_list *) current->data; 215 list = (mailimap_mailbox_list *) current->data;
215 // it is better use the deep copy mechanism of qt itself 216 // it is better use the deep copy mechanism of qt itself
216 // instead of using strdup! 217 // instead of using strdup!
217 temp = list->mb_name; 218 temp = list->mb_name;
218 if (temp.lower()=="inbox") 219 if (temp.lower()=="inbox")
219 continue; 220 continue;
220 if (temp.lower()==account->getPrefix().lower()) 221 if (temp.lower()==account->getPrefix().lower())
221 continue; 222 continue;
222 if ( (bflags = list->mb_flag) ) { 223 if ( (bflags = list->mb_flag) ) {
223 selectable = !(bflags->mbf_type==MAILIMAP_MBX_LIST_FLAGS_SFLAG&& 224 selectable = !(bflags->mbf_type==MAILIMAP_MBX_LIST_FLAGS_SFLAG&&
224 bflags->mbf_sflag==MAILIMAP_MBX_LIST_SFLAG_NOSELECT); 225 bflags->mbf_sflag==MAILIMAP_MBX_LIST_SFLAG_NOSELECT);
225 } 226 }
226 del = list->mb_delimiter; 227 del = list->mb_delimiter;
227 folders->append(new IMAPFolder(temp,del,selectable,account->getPrefix())); 228 folders->append(new IMAPFolder(temp,del,selectable,account->getPrefix()));
228 } 229 }
229 } else { 230 } else {
230 qDebug("error fetching folders %s",m_imap->imap_response); 231 qDebug("error fetching folders %s",m_imap->imap_response);
231 } 232 }
232 mailimap_list_result_free( result ); 233 mailimap_list_result_free( result );
233 return folders; 234 return folders;
234} 235}
235 236
236RecMail*IMAPwrapper::parse_list_result(mailimap_msg_att* m_att) 237RecMail*IMAPwrapper::parse_list_result(mailimap_msg_att* m_att)
237{ 238{
238 RecMail * m = 0; 239 RecMail * m = 0;
239 mailimap_msg_att_item *item=0; 240 mailimap_msg_att_item *item=0;
240 clistcell *current,*c,*cf; 241 clistcell *current,*c,*cf;
241 mailimap_msg_att_dynamic*flist; 242 mailimap_msg_att_dynamic*flist;
242 mailimap_flag_fetch*cflag; 243 mailimap_flag_fetch*cflag;
243 int size; 244 int size;
244 QBitArray mFlags(7); 245 QBitArray mFlags(7);
245 QStringList addresslist; 246 QStringList addresslist;
246 247
247 if (!m_att) { 248 if (!m_att) {
248 return m; 249 return m;
249 } 250 }
250 m = new RecMail(); 251 m = new RecMail();
251 for (c = clist_begin(m_att->att_list); c!=NULL;c=clist_next(c) ) { 252 for (c = clist_begin(m_att->att_list); c!=NULL;c=clist_next(c) ) {
252 current = c; 253 current = c;
253 size = 0; 254 size = 0;
254 item = (mailimap_msg_att_item*)current->data; 255 item = (mailimap_msg_att_item*)current->data;
255 if (item->att_type!=MAILIMAP_MSG_ATT_ITEM_STATIC) { 256 if (item->att_type!=MAILIMAP_MSG_ATT_ITEM_STATIC) {
256 flist = (mailimap_msg_att_dynamic*)item->att_data.att_dyn; 257 flist = (mailimap_msg_att_dynamic*)item->att_data.att_dyn;
257 if (!flist->att_list) { 258 if (!flist->att_list) {
258 continue; 259 continue;
259 } 260 }
260 cf = flist->att_list->first; 261 cf = flist->att_list->first;
261 for (cf = clist_begin(flist->att_list); cf!=NULL; cf = clist_next(cf)) { 262 for (cf = clist_begin(flist->att_list); cf!=NULL; cf = clist_next(cf)) {
262 cflag = (mailimap_flag_fetch*)cf->data; 263 cflag = (mailimap_flag_fetch*)cf->data;
263 if (cflag->fl_type==MAILIMAP_FLAG_FETCH_OTHER && cflag->fl_flag!=0) { 264 if (cflag->fl_type==MAILIMAP_FLAG_FETCH_OTHER && cflag->fl_flag!=0) {
diff --git a/noncore/net/mail/imapwrapper.h b/noncore/net/mail/imapwrapper.h
index aeebda8..f046297 100644
--- a/noncore/net/mail/imapwrapper.h
+++ b/noncore/net/mail/imapwrapper.h
@@ -1,62 +1,63 @@
1#ifndef __IMAPWRAPPER 1#ifndef __IMAPWRAPPER
2#define __IMAPWRAPPER 2#define __IMAPWRAPPER
3 3
4#include <qlist.h> 4#include <qlist.h>
5#include "mailwrapper.h" 5#include "mailwrapper.h"
6#include "abstractmail.h" 6#include "abstractmail.h"
7#include <libetpan/clist.h>
7 8
8struct mailimap; 9struct mailimap;
9struct mailimap_body_type_1part; 10struct mailimap_body_type_1part;
10struct mailimap_body_type_text; 11struct mailimap_body_type_text;
11struct mailimap_body_type_basic; 12struct mailimap_body_type_basic;
12struct mailimap_body_type_msg; 13struct mailimap_body_type_msg;
13struct mailimap_body_type_mpart; 14struct mailimap_body_type_mpart;
14struct mailimap_body_fields; 15struct mailimap_body_fields;
15struct mailimap_msg_att; 16struct mailimap_msg_att;
16class encodedString; 17class encodedString;
17 18
18class IMAPwrapper : public AbstractMail 19class IMAPwrapper : public AbstractMail
19{ 20{
20 Q_OBJECT 21 Q_OBJECT
21public: 22public:
22 IMAPwrapper( IMAPaccount *a ); 23 IMAPwrapper( IMAPaccount *a );
23 virtual ~IMAPwrapper(); 24 virtual ~IMAPwrapper();
24 virtual QList<Folder>* listFolders(); 25 virtual QList<Folder>* listFolders();
25 virtual void listMessages(const QString & mailbox,QList<RecMail>&target ); 26 virtual void listMessages(const QString & mailbox,QList<RecMail>&target );
26 27
27 virtual void deleteMail(const RecMail&mail); 28 virtual void deleteMail(const RecMail&mail);
28 virtual void answeredMail(const RecMail&mail); 29 virtual void answeredMail(const RecMail&mail);
29 30
30 virtual RecBody fetchBody(const RecMail&mail); 31 virtual RecBody fetchBody(const RecMail&mail);
31 virtual QString fetchTextPart(const RecMail&mail,const RecPart&part); 32 virtual QString fetchTextPart(const RecMail&mail,const RecPart&part);
32 virtual encodedString* fetchDecodedPart(const RecMail&mail,const RecPart&part); 33 virtual encodedString* fetchDecodedPart(const RecMail&mail,const RecPart&part);
33 virtual encodedString* fetchRawPart(const RecMail&mail,const RecPart&part); 34 virtual encodedString* fetchRawPart(const RecMail&mail,const RecPart&part);
34 35
35 static void imap_progress( size_t current, size_t maximum ); 36 static void imap_progress( size_t current, size_t maximum );
36 37
37protected: 38protected:
38 RecMail*parse_list_result(mailimap_msg_att*); 39 RecMail*parse_list_result(mailimap_msg_att*);
39 void login(); 40 void login();
40 void logout(); 41 void logout();
41 42
42 virtual QString fetchTextPart(const RecMail&mail,const QValueList<int>&path,bool internal_call=false,const QString&enc=""); 43 virtual QString fetchTextPart(const RecMail&mail,const QValueList<int>&path,bool internal_call=false,const QString&enc="");
43 virtual encodedString*fetchRawPart(const RecMail&mail,const QValueList<int>&path,bool internal_call); 44 virtual encodedString*fetchRawPart(const RecMail&mail,const QValueList<int>&path,bool internal_call);
44 45
45 void searchBodyText(const RecMail&mail,mailimap_body_type_1part*mailDescription,RecBody&target_body); 46 void searchBodyText(const RecMail&mail,mailimap_body_type_1part*mailDescription,RecBody&target_body);
46 void searchBodyText(const RecMail&mail,mailimap_body_type_mpart*mailDescription,RecBody&target_body,int current_recursion=0,QValueList<int>recList=QValueList<int>()); 47 void searchBodyText(const RecMail&mail,mailimap_body_type_mpart*mailDescription,RecBody&target_body,int current_recursion=0,QValueList<int>recList=QValueList<int>());
47 48
48 void fillSinglePart(RecPart&target_part,mailimap_body_type_1part*Description); 49 void fillSinglePart(RecPart&target_part,mailimap_body_type_1part*Description);
49 void fillSingleTextPart(RecPart&target_part,mailimap_body_type_text*which); 50 void fillSingleTextPart(RecPart&target_part,mailimap_body_type_text*which);
50 void fillSingleBasicPart(RecPart&target_part,mailimap_body_type_basic*which); 51 void fillSingleBasicPart(RecPart&target_part,mailimap_body_type_basic*which);
51 void fillSingleMsgPart(RecPart&target_part,mailimap_body_type_msg*which); 52 void fillSingleMsgPart(RecPart&target_part,mailimap_body_type_msg*which);
52 53
53 /* just helpers */ 54 /* just helpers */
54 static void fillBodyFields(RecPart&target_part,mailimap_body_fields*which); 55 static void fillBodyFields(RecPart&target_part,mailimap_body_fields*which);
55 static QStringList address_list_to_stringlist(clist*list); 56 static QStringList address_list_to_stringlist(clist*list);
56 57
57 58
58 IMAPaccount *account; 59 IMAPaccount *account;
59 mailimap *m_imap; 60 mailimap *m_imap;
60}; 61};
61 62
62#endif 63#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 @@
1#include "abstractmail.h" 1#include "abstractmail.h"
2#include "imapwrapper.h" 2#include "imapwrapper.h"
3#include "pop3wrapper.h" 3#include "pop3wrapper.h"
4#include "mailtypes.h" 4#include "mailtypes.h"
5 5
6#include <qstring.h> 6#include <qstring.h>
7#include <qfile.h> 7#include <qfile.h>
8#include <qtextstream.h> 8#include <qtextstream.h>
9#include <stdlib.h> 9#include <stdlib.h>
10#include <libetpan/mailmime_content.h> 10#include <libetpan/mailmime_content.h>
11#include <libetpan/mailmime.h>
11 12
12AbstractMail* AbstractMail::getWrapper(IMAPaccount *a) 13AbstractMail* AbstractMail::getWrapper(IMAPaccount *a)
13{ 14{
14 return new IMAPwrapper(a); 15 return new IMAPwrapper(a);
15} 16}
16 17
17AbstractMail* AbstractMail::getWrapper(POP3account *a) 18AbstractMail* AbstractMail::getWrapper(POP3account *a)
18{ 19{
19 return new POP3wrapper(a); 20 return new POP3wrapper(a);
20} 21}
21 22
22encodedString* AbstractMail::decode_String(const encodedString*text,const QString&enc) 23encodedString* AbstractMail::decode_String(const encodedString*text,const QString&enc)
23{ 24{
24 qDebug("Decode string start"); 25 qDebug("Decode string start");
25 char*result_text; 26 char*result_text;
26 size_t index = 0; 27 size_t index = 0;
27 /* reset for recursive use! */ 28 /* reset for recursive use! */
28 size_t target_length = 0; 29 size_t target_length = 0;
29 result_text = 0; 30 result_text = 0;
30 int mimetype = MAILMIME_MECHANISM_7BIT; 31 int mimetype = MAILMIME_MECHANISM_7BIT;
31 if (enc.lower()=="quoted-printable") { 32 if (enc.lower()=="quoted-printable") {
32 mimetype = MAILMIME_MECHANISM_QUOTED_PRINTABLE; 33 mimetype = MAILMIME_MECHANISM_QUOTED_PRINTABLE;
33 } else if (enc.lower()=="base64") { 34 } else if (enc.lower()=="base64") {
34 mimetype = MAILMIME_MECHANISM_BASE64; 35 mimetype = MAILMIME_MECHANISM_BASE64;
35 } else if (enc.lower()=="8bit") { 36 } else if (enc.lower()=="8bit") {
36 mimetype = MAILMIME_MECHANISM_8BIT; 37 mimetype = MAILMIME_MECHANISM_8BIT;
37 } else if (enc.lower()=="binary") { 38 } else if (enc.lower()=="binary") {
38 mimetype = MAILMIME_MECHANISM_BINARY; 39 mimetype = MAILMIME_MECHANISM_BINARY;
39 } 40 }
40 41
41 int err = mailmime_part_parse(text->Content(),text->Length(),&index,mimetype, 42 int err = mailmime_part_parse(text->Content(),text->Length(),&index,mimetype,
42 &result_text,&target_length); 43 &result_text,&target_length);
43 44
44 encodedString* result = new encodedString(); 45 encodedString* result = new encodedString();
45 if (err == MAILIMF_NO_ERROR) { 46 if (err == MAILIMF_NO_ERROR) {
46 result->setContent(result_text,target_length); 47 result->setContent(result_text,target_length);
47 } 48 }
48 qDebug("Decode string finished"); 49 qDebug("Decode string finished");
49 return result; 50 return result;
50} 51}
51 52
52QString AbstractMail::convert_String(const char*text) 53QString AbstractMail::convert_String(const char*text)
53{ 54{
54 size_t index = 0; 55 size_t index = 0;
55 char*res = 0; 56 char*res = 0;
56 57
57 /* attention - doesn't work with arm systems! */ 58 /* attention - doesn't work with arm systems! */
58 int err = mailmime_encoded_phrase_parse("iso-8859-1", 59 int err = mailmime_encoded_phrase_parse("iso-8859-1",
59 text, strlen(text),&index, "iso-8859-1",&res); 60 text, strlen(text),&index, "iso-8859-1",&res);
60 if (err != MAILIMF_NO_ERROR) { 61 if (err != MAILIMF_NO_ERROR) {
61 if (res) free(res); 62 if (res) free(res);
62 return QString(text); 63 return QString(text);
63 } 64 }
64 if (res) { 65 if (res) {
65 QString result(res); 66 QString result(res);
66 free(res); 67 free(res);
67 return result; 68 return result;
68 } 69 }
69 return QString(text); 70 return QString(text);
70} 71}
71 72
72/* cp & paste from launcher */ 73/* cp & paste from launcher */
73QString AbstractMail::gen_attachment_id() 74QString AbstractMail::gen_attachment_id()
74{ 75{
75 QFile file( "/proc/sys/kernel/random/uuid" ); 76 QFile file( "/proc/sys/kernel/random/uuid" );
76 if (!file.open(IO_ReadOnly ) ) 77 if (!file.open(IO_ReadOnly ) )
77 return QString::null; 78 return QString::null;
78 79
79 QTextStream stream(&file); 80 QTextStream stream(&file);
80 81
81 return "{" + stream.read().stripWhiteSpace() + "}"; 82 return "{" + stream.read().stripWhiteSpace() + "}";
82} 83}
83 84
diff --git a/noncore/net/mail/libmailwrapper/imapwrapper.cpp b/noncore/net/mail/libmailwrapper/imapwrapper.cpp
index cce3d34..30eb678 100644
--- a/noncore/net/mail/libmailwrapper/imapwrapper.cpp
+++ b/noncore/net/mail/libmailwrapper/imapwrapper.cpp
@@ -1,263 +1,264 @@
1 1
2#include <stdlib.h> 2#include <stdlib.h>
3 3
4#include <libetpan/mailimap.h>
5
4#include "imapwrapper.h" 6#include "imapwrapper.h"
5#include "mailtypes.h" 7#include "mailtypes.h"
6#include "logindialog.h" 8#include "logindialog.h"
7#include <libetpan/mailimap.h>
8 9
9IMAPwrapper::IMAPwrapper( IMAPaccount *a ) 10IMAPwrapper::IMAPwrapper( IMAPaccount *a )
10 : AbstractMail() 11 : AbstractMail()
11{ 12{
12 account = a; 13 account = a;
13 m_imap = 0; 14 m_imap = 0;
14} 15}
15 16
16IMAPwrapper::~IMAPwrapper() 17IMAPwrapper::~IMAPwrapper()
17{ 18{
18 logout(); 19 logout();
19} 20}
20 21
21void IMAPwrapper::imap_progress( size_t current, size_t maximum ) 22void IMAPwrapper::imap_progress( size_t current, size_t maximum )
22{ 23{
23 qDebug( "IMAP: %i of %i", current, maximum ); 24 qDebug( "IMAP: %i of %i", current, maximum );
24} 25}
25 26
26void IMAPwrapper::login() 27void IMAPwrapper::login()
27{ 28{
28 const char *server, *user, *pass; 29 const char *server, *user, *pass;
29 uint16_t port; 30 uint16_t port;
30 int err = MAILIMAP_NO_ERROR; 31 int err = MAILIMAP_NO_ERROR;
31 32
32 /* we are connected this moment */ 33 /* we are connected this moment */
33 /* TODO: setup a timer holding the line or if connection closed - delete the value */ 34 /* TODO: setup a timer holding the line or if connection closed - delete the value */
34 if (m_imap) { 35 if (m_imap) {
35 mailstream_flush(m_imap->imap_stream); 36 mailstream_flush(m_imap->imap_stream);
36 return; 37 return;
37 } 38 }
38 server = account->getServer().latin1(); 39 server = account->getServer().latin1();
39 port = account->getPort().toUInt(); 40 port = account->getPort().toUInt();
40 if ( account->getUser().isEmpty() || account->getPassword().isEmpty() ) { 41 if ( account->getUser().isEmpty() || account->getPassword().isEmpty() ) {
41 LoginDialog login( account->getUser(), account->getPassword(), NULL, 0, true ); 42 LoginDialog login( account->getUser(), account->getPassword(), NULL, 0, true );
42 login.show(); 43 login.show();
43 if ( QDialog::Accepted == login.exec() ) { 44 if ( QDialog::Accepted == login.exec() ) {
44 // ok 45 // ok
45 user = strdup( login.getUser().latin1() ); 46 user = strdup( login.getUser().latin1() );
46 pass = strdup( login.getPassword().latin1() ); 47 pass = strdup( login.getPassword().latin1() );
47 } else { 48 } else {
48 // cancel 49 // cancel
49 qDebug( "IMAP: Login canceled" ); 50 qDebug( "IMAP: Login canceled" );
50 return; 51 return;
51 } 52 }
52 } else { 53 } else {
53 user = account->getUser().latin1(); 54 user = account->getUser().latin1();
54 pass = account->getPassword().latin1(); 55 pass = account->getPassword().latin1();
55 } 56 }
56 57
57 m_imap = mailimap_new( 20, &imap_progress ); 58 m_imap = mailimap_new( 20, &imap_progress );
58 /* connect */ 59 /* connect */
59 if (account->getSSL()) { 60 if (account->getSSL()) {
60 err = mailimap_ssl_connect( m_imap, (char*)server, port ); 61 err = mailimap_ssl_connect( m_imap, (char*)server, port );
61 } else { 62 } else {
62 err = mailimap_socket_connect( m_imap, (char*)server, port ); 63 err = mailimap_socket_connect( m_imap, (char*)server, port );
63 } 64 }
64 65
65 if ( err != MAILIMAP_NO_ERROR && 66 if ( err != MAILIMAP_NO_ERROR &&
66 err != MAILIMAP_NO_ERROR_AUTHENTICATED && 67 err != MAILIMAP_NO_ERROR_AUTHENTICATED &&
67 err != MAILIMAP_NO_ERROR_NON_AUTHENTICATED ) { 68 err != MAILIMAP_NO_ERROR_NON_AUTHENTICATED ) {
68 qDebug("error connecting server: %s",m_imap->imap_response); 69 qDebug("error connecting server: %s",m_imap->imap_response);
69 mailimap_free( m_imap ); 70 mailimap_free( m_imap );
70 m_imap = 0; 71 m_imap = 0;
71 return; 72 return;
72 } 73 }
73 74
74 /* login */ 75 /* login */
75 err = mailimap_login_simple( m_imap, (char*)user, (char*)pass ); 76 err = mailimap_login_simple( m_imap, (char*)user, (char*)pass );
76 if ( err != MAILIMAP_NO_ERROR ) { 77 if ( err != MAILIMAP_NO_ERROR ) {
77 qDebug("error logging in imap: %s",m_imap->imap_response); 78 qDebug("error logging in imap: %s",m_imap->imap_response);
78 err = mailimap_close( m_imap ); 79 err = mailimap_close( m_imap );
79 mailimap_free( m_imap ); 80 mailimap_free( m_imap );
80 m_imap = 0; 81 m_imap = 0;
81 } 82 }
82} 83}
83 84
84void IMAPwrapper::logout() 85void IMAPwrapper::logout()
85{ 86{
86 int err = MAILIMAP_NO_ERROR; 87 int err = MAILIMAP_NO_ERROR;
87 if (!m_imap) return; 88 if (!m_imap) return;
88 err = mailimap_logout( m_imap ); 89 err = mailimap_logout( m_imap );
89 err = mailimap_close( m_imap ); 90 err = mailimap_close( m_imap );
90 mailimap_free( m_imap ); 91 mailimap_free( m_imap );
91 m_imap = 0; 92 m_imap = 0;
92} 93}
93 94
94void IMAPwrapper::listMessages(const QString&mailbox,QList<RecMail> &target ) 95void IMAPwrapper::listMessages(const QString&mailbox,QList<RecMail> &target )
95{ 96{
96 const char *mb; 97 const char *mb;
97 int err = MAILIMAP_NO_ERROR; 98 int err = MAILIMAP_NO_ERROR;
98 clist *result; 99 clist *result;
99 clistcell *current; 100 clistcell *current;
100// mailimap_fetch_att *fetchAtt,*fetchAttFlags,*fetchAttDate,*fetchAttSize; 101// mailimap_fetch_att *fetchAtt,*fetchAttFlags,*fetchAttDate,*fetchAttSize;
101 mailimap_fetch_type *fetchType; 102 mailimap_fetch_type *fetchType;
102 mailimap_set *set; 103 mailimap_set *set;
103 104
104 mb = mailbox.latin1(); 105 mb = mailbox.latin1();
105 login(); 106 login();
106 if (!m_imap) { 107 if (!m_imap) {
107 return; 108 return;
108 } 109 }
109 /* select mailbox READONLY for operations */ 110 /* select mailbox READONLY for operations */
110 err = mailimap_examine( m_imap, (char*)mb); 111 err = mailimap_examine( m_imap, (char*)mb);
111 if ( err != MAILIMAP_NO_ERROR ) { 112 if ( err != MAILIMAP_NO_ERROR ) {
112 qDebug("error selecting mailbox: %s",m_imap->imap_response); 113 qDebug("error selecting mailbox: %s",m_imap->imap_response);
113 return; 114 return;
114 } 115 }
115 116
116 int last = m_imap->imap_selection_info->sel_exists; 117 int last = m_imap->imap_selection_info->sel_exists;
117 118
118 if (last == 0) { 119 if (last == 0) {
119 qDebug("mailbox has no mails"); 120 qDebug("mailbox has no mails");
120 return; 121 return;
121 } 122 }
122 123
123 result = clist_new(); 124 result = clist_new();
124 /* the range has to start at 1!!! not with 0!!!! */ 125 /* the range has to start at 1!!! not with 0!!!! */
125 set = mailimap_set_new_interval( 1, last ); 126 set = mailimap_set_new_interval( 1, last );
126 fetchType = mailimap_fetch_type_new_fetch_att_list_empty(); 127 fetchType = mailimap_fetch_type_new_fetch_att_list_empty();
127 mailimap_fetch_type_new_fetch_att_list_add(fetchType,mailimap_fetch_att_new_envelope()); 128 mailimap_fetch_type_new_fetch_att_list_add(fetchType,mailimap_fetch_att_new_envelope());
128 mailimap_fetch_type_new_fetch_att_list_add(fetchType,mailimap_fetch_att_new_flags()); 129 mailimap_fetch_type_new_fetch_att_list_add(fetchType,mailimap_fetch_att_new_flags());
129 mailimap_fetch_type_new_fetch_att_list_add(fetchType,mailimap_fetch_att_new_internaldate()); 130 mailimap_fetch_type_new_fetch_att_list_add(fetchType,mailimap_fetch_att_new_internaldate());
130 mailimap_fetch_type_new_fetch_att_list_add(fetchType,mailimap_fetch_att_new_rfc822_size()); 131 mailimap_fetch_type_new_fetch_att_list_add(fetchType,mailimap_fetch_att_new_rfc822_size());
131 132
132 err = mailimap_fetch( m_imap, set, fetchType, &result ); 133 err = mailimap_fetch( m_imap, set, fetchType, &result );
133 mailimap_set_free( set ); 134 mailimap_set_free( set );
134 mailimap_fetch_type_free( fetchType ); 135 mailimap_fetch_type_free( fetchType );
135 136
136 QString date,subject,from; 137 QString date,subject,from;
137 138
138 if ( err == MAILIMAP_NO_ERROR ) { 139 if ( err == MAILIMAP_NO_ERROR ) {
139 140
140 mailimap_msg_att * msg_att; 141 mailimap_msg_att * msg_att;
141 int i = 0; 142 int i = 0;
142 for (current = clist_begin(result); current != 0; current=clist_next(current)) { 143 for (current = clist_begin(result); current != 0; current=clist_next(current)) {
143 ++i; 144 ++i;
144 msg_att = (mailimap_msg_att*)current->data; 145 msg_att = (mailimap_msg_att*)current->data;
145 RecMail*m = parse_list_result(msg_att); 146 RecMail*m = parse_list_result(msg_att);
146 if (m) { 147 if (m) {
147 m->setNumber(i); 148 m->setNumber(i);
148 m->setMbox(mailbox); 149 m->setMbox(mailbox);
149 m->setWrapper(this); 150 m->setWrapper(this);
150 target.append(m); 151 target.append(m);
151 } 152 }
152 } 153 }
153 } else { 154 } else {
154 qDebug("Error fetching headers: %s",m_imap->imap_response); 155 qDebug("Error fetching headers: %s",m_imap->imap_response);
155 } 156 }
156 mailimap_fetch_list_free(result); 157 mailimap_fetch_list_free(result);
157} 158}
158 159
159QList<Folder>* IMAPwrapper::listFolders() 160QList<Folder>* IMAPwrapper::listFolders()
160{ 161{
161 const char *path, *mask; 162 const char *path, *mask;
162 int err = MAILIMAP_NO_ERROR; 163 int err = MAILIMAP_NO_ERROR;
163 clist *result; 164 clist *result;
164 clistcell *current; 165 clistcell *current;
165 166
166 QList<Folder> * folders = new QList<Folder>(); 167 QList<Folder> * folders = new QList<Folder>();
167 folders->setAutoDelete( false ); 168 folders->setAutoDelete( false );
168 login(); 169 login();
169 if (!m_imap) { 170 if (!m_imap) {
170 return folders; 171 return folders;
171 } 172 }
172 173
173/* 174/*
174 * First we have to check for INBOX 'cause it sometimes it's not inside the path. 175 * First we have to check for INBOX 'cause it sometimes it's not inside the path.
175 * We must not forget to filter them out in next loop! 176 * We must not forget to filter them out in next loop!
176 * it seems like ugly code. and yes - it is ugly code. but the best way. 177 * it seems like ugly code. and yes - it is ugly code. but the best way.
177 */ 178 */
178 QString temp; 179 QString temp;
179 mask = "INBOX" ; 180 mask = "INBOX" ;
180 result = clist_new(); 181 result = clist_new();
181 mailimap_mailbox_list *list; 182 mailimap_mailbox_list *list;
182 err = mailimap_list( m_imap, (char*)"", (char*)mask, &result ); 183 err = mailimap_list( m_imap, (char*)"", (char*)mask, &result );
183 QString del; 184 QString del;
184 if ( err == MAILIMAP_NO_ERROR ) { 185 if ( err == MAILIMAP_NO_ERROR ) {
185 current = result->first; 186 current = result->first;
186 for ( int i = result->count; i > 0; i-- ) { 187 for ( int i = result->count; i > 0; i-- ) {
187 list = (mailimap_mailbox_list *) current->data; 188 list = (mailimap_mailbox_list *) current->data;
188 // it is better use the deep copy mechanism of qt itself 189 // it is better use the deep copy mechanism of qt itself
189 // instead of using strdup! 190 // instead of using strdup!
190 temp = list->mb_name; 191 temp = list->mb_name;
191 del = list->mb_delimiter; 192 del = list->mb_delimiter;
192 folders->append( new IMAPFolder(temp,del,true,account->getPrefix())); 193 folders->append( new IMAPFolder(temp,del,true,account->getPrefix()));
193 current = current->next; 194 current = current->next;
194 } 195 }
195 } else { 196 } else {
196 qDebug("error fetching folders: %s",m_imap->imap_response); 197 qDebug("error fetching folders: %s",m_imap->imap_response);
197 } 198 }
198 mailimap_list_result_free( result ); 199 mailimap_list_result_free( result );
199 200
200/* 201/*
201 * second stage - get the other then inbox folders 202 * second stage - get the other then inbox folders
202 */ 203 */
203 mask = "*" ; 204 mask = "*" ;
204 path = account->getPrefix().latin1(); 205 path = account->getPrefix().latin1();
205 if (!path) path = ""; 206 if (!path) path = "";
206 result = clist_new(); 207 result = clist_new();
207 qDebug(path); 208 qDebug(path);
208 bool selectable = true; 209 bool selectable = true;
209 mailimap_mbx_list_flags*bflags; 210 mailimap_mbx_list_flags*bflags;
210 err = mailimap_list( m_imap, (char*)path, (char*)mask, &result ); 211 err = mailimap_list( m_imap, (char*)path, (char*)mask, &result );
211 if ( err == MAILIMAP_NO_ERROR ) { 212 if ( err == MAILIMAP_NO_ERROR ) {
212 current = result->first; 213 current = result->first;
213 for ( current=clist_begin(result);current!=NULL;current=clist_next(current)) { 214 for ( current=clist_begin(result);current!=NULL;current=clist_next(current)) {
214 list = (mailimap_mailbox_list *) current->data; 215 list = (mailimap_mailbox_list *) current->data;
215 // it is better use the deep copy mechanism of qt itself 216 // it is better use the deep copy mechanism of qt itself
216 // instead of using strdup! 217 // instead of using strdup!
217 temp = list->mb_name; 218 temp = list->mb_name;
218 if (temp.lower()=="inbox") 219 if (temp.lower()=="inbox")
219 continue; 220 continue;
220 if (temp.lower()==account->getPrefix().lower()) 221 if (temp.lower()==account->getPrefix().lower())
221 continue; 222 continue;
222 if ( (bflags = list->mb_flag) ) { 223 if ( (bflags = list->mb_flag) ) {
223 selectable = !(bflags->mbf_type==MAILIMAP_MBX_LIST_FLAGS_SFLAG&& 224 selectable = !(bflags->mbf_type==MAILIMAP_MBX_LIST_FLAGS_SFLAG&&
224 bflags->mbf_sflag==MAILIMAP_MBX_LIST_SFLAG_NOSELECT); 225 bflags->mbf_sflag==MAILIMAP_MBX_LIST_SFLAG_NOSELECT);
225 } 226 }
226 del = list->mb_delimiter; 227 del = list->mb_delimiter;
227 folders->append(new IMAPFolder(temp,del,selectable,account->getPrefix())); 228 folders->append(new IMAPFolder(temp,del,selectable,account->getPrefix()));
228 } 229 }
229 } else { 230 } else {
230 qDebug("error fetching folders %s",m_imap->imap_response); 231 qDebug("error fetching folders %s",m_imap->imap_response);
231 } 232 }
232 mailimap_list_result_free( result ); 233 mailimap_list_result_free( result );
233 return folders; 234 return folders;
234} 235}
235 236
236RecMail*IMAPwrapper::parse_list_result(mailimap_msg_att* m_att) 237RecMail*IMAPwrapper::parse_list_result(mailimap_msg_att* m_att)
237{ 238{
238 RecMail * m = 0; 239 RecMail * m = 0;
239 mailimap_msg_att_item *item=0; 240 mailimap_msg_att_item *item=0;
240 clistcell *current,*c,*cf; 241 clistcell *current,*c,*cf;
241 mailimap_msg_att_dynamic*flist; 242 mailimap_msg_att_dynamic*flist;
242 mailimap_flag_fetch*cflag; 243 mailimap_flag_fetch*cflag;
243 int size; 244 int size;
244 QBitArray mFlags(7); 245 QBitArray mFlags(7);
245 QStringList addresslist; 246 QStringList addresslist;
246 247
247 if (!m_att) { 248 if (!m_att) {
248 return m; 249 return m;
249 } 250 }
250 m = new RecMail(); 251 m = new RecMail();
251 for (c = clist_begin(m_att->att_list); c!=NULL;c=clist_next(c) ) { 252 for (c = clist_begin(m_att->att_list); c!=NULL;c=clist_next(c) ) {
252 current = c; 253 current = c;
253 size = 0; 254 size = 0;
254 item = (mailimap_msg_att_item*)current->data; 255 item = (mailimap_msg_att_item*)current->data;
255 if (item->att_type!=MAILIMAP_MSG_ATT_ITEM_STATIC) { 256 if (item->att_type!=MAILIMAP_MSG_ATT_ITEM_STATIC) {
256 flist = (mailimap_msg_att_dynamic*)item->att_data.att_dyn; 257 flist = (mailimap_msg_att_dynamic*)item->att_data.att_dyn;
257 if (!flist->att_list) { 258 if (!flist->att_list) {
258 continue; 259 continue;
259 } 260 }
260 cf = flist->att_list->first; 261 cf = flist->att_list->first;
261 for (cf = clist_begin(flist->att_list); cf!=NULL; cf = clist_next(cf)) { 262 for (cf = clist_begin(flist->att_list); cf!=NULL; cf = clist_next(cf)) {
262 cflag = (mailimap_flag_fetch*)cf->data; 263 cflag = (mailimap_flag_fetch*)cf->data;
263 if (cflag->fl_type==MAILIMAP_FLAG_FETCH_OTHER && cflag->fl_flag!=0) { 264 if (cflag->fl_type==MAILIMAP_FLAG_FETCH_OTHER && cflag->fl_flag!=0) {
diff --git a/noncore/net/mail/libmailwrapper/imapwrapper.h b/noncore/net/mail/libmailwrapper/imapwrapper.h
index aeebda8..f046297 100644
--- a/noncore/net/mail/libmailwrapper/imapwrapper.h
+++ b/noncore/net/mail/libmailwrapper/imapwrapper.h
@@ -1,62 +1,63 @@
1#ifndef __IMAPWRAPPER 1#ifndef __IMAPWRAPPER
2#define __IMAPWRAPPER 2#define __IMAPWRAPPER
3 3
4#include <qlist.h> 4#include <qlist.h>
5#include "mailwrapper.h" 5#include "mailwrapper.h"
6#include "abstractmail.h" 6#include "abstractmail.h"
7#include <libetpan/clist.h>
7 8
8struct mailimap; 9struct mailimap;
9struct mailimap_body_type_1part; 10struct mailimap_body_type_1part;
10struct mailimap_body_type_text; 11struct mailimap_body_type_text;
11struct mailimap_body_type_basic; 12struct mailimap_body_type_basic;
12struct mailimap_body_type_msg; 13struct mailimap_body_type_msg;
13struct mailimap_body_type_mpart; 14struct mailimap_body_type_mpart;
14struct mailimap_body_fields; 15struct mailimap_body_fields;
15struct mailimap_msg_att; 16struct mailimap_msg_att;
16class encodedString; 17class encodedString;
17 18
18class IMAPwrapper : public AbstractMail 19class IMAPwrapper : public AbstractMail
19{ 20{
20 Q_OBJECT 21 Q_OBJECT
21public: 22public:
22 IMAPwrapper( IMAPaccount *a ); 23 IMAPwrapper( IMAPaccount *a );
23 virtual ~IMAPwrapper(); 24 virtual ~IMAPwrapper();
24 virtual QList<Folder>* listFolders(); 25 virtual QList<Folder>* listFolders();
25 virtual void listMessages(const QString & mailbox,QList<RecMail>&target ); 26 virtual void listMessages(const QString & mailbox,QList<RecMail>&target );
26 27
27 virtual void deleteMail(const RecMail&mail); 28 virtual void deleteMail(const RecMail&mail);
28 virtual void answeredMail(const RecMail&mail); 29 virtual void answeredMail(const RecMail&mail);
29 30
30 virtual RecBody fetchBody(const RecMail&mail); 31 virtual RecBody fetchBody(const RecMail&mail);
31 virtual QString fetchTextPart(const RecMail&mail,const RecPart&part); 32 virtual QString fetchTextPart(const RecMail&mail,const RecPart&part);
32 virtual encodedString* fetchDecodedPart(const RecMail&mail,const RecPart&part); 33 virtual encodedString* fetchDecodedPart(const RecMail&mail,const RecPart&part);
33 virtual encodedString* fetchRawPart(const RecMail&mail,const RecPart&part); 34 virtual encodedString* fetchRawPart(const RecMail&mail,const RecPart&part);
34 35
35 static void imap_progress( size_t current, size_t maximum ); 36 static void imap_progress( size_t current, size_t maximum );
36 37
37protected: 38protected:
38 RecMail*parse_list_result(mailimap_msg_att*); 39 RecMail*parse_list_result(mailimap_msg_att*);
39 void login(); 40 void login();
40 void logout(); 41 void logout();
41 42
42 virtual QString fetchTextPart(const RecMail&mail,const QValueList<int>&path,bool internal_call=false,const QString&enc=""); 43 virtual QString fetchTextPart(const RecMail&mail,const QValueList<int>&path,bool internal_call=false,const QString&enc="");
43 virtual encodedString*fetchRawPart(const RecMail&mail,const QValueList<int>&path,bool internal_call); 44 virtual encodedString*fetchRawPart(const RecMail&mail,const QValueList<int>&path,bool internal_call);
44 45
45 void searchBodyText(const RecMail&mail,mailimap_body_type_1part*mailDescription,RecBody&target_body); 46 void searchBodyText(const RecMail&mail,mailimap_body_type_1part*mailDescription,RecBody&target_body);
46 void searchBodyText(const RecMail&mail,mailimap_body_type_mpart*mailDescription,RecBody&target_body,int current_recursion=0,QValueList<int>recList=QValueList<int>()); 47 void searchBodyText(const RecMail&mail,mailimap_body_type_mpart*mailDescription,RecBody&target_body,int current_recursion=0,QValueList<int>recList=QValueList<int>());
47 48
48 void fillSinglePart(RecPart&target_part,mailimap_body_type_1part*Description); 49 void fillSinglePart(RecPart&target_part,mailimap_body_type_1part*Description);
49 void fillSingleTextPart(RecPart&target_part,mailimap_body_type_text*which); 50 void fillSingleTextPart(RecPart&target_part,mailimap_body_type_text*which);
50 void fillSingleBasicPart(RecPart&target_part,mailimap_body_type_basic*which); 51 void fillSingleBasicPart(RecPart&target_part,mailimap_body_type_basic*which);
51 void fillSingleMsgPart(RecPart&target_part,mailimap_body_type_msg*which); 52 void fillSingleMsgPart(RecPart&target_part,mailimap_body_type_msg*which);
52 53
53 /* just helpers */ 54 /* just helpers */
54 static void fillBodyFields(RecPart&target_part,mailimap_body_fields*which); 55 static void fillBodyFields(RecPart&target_part,mailimap_body_fields*which);
55 static QStringList address_list_to_stringlist(clist*list); 56 static QStringList address_list_to_stringlist(clist*list);
56 57
57 58
58 IMAPaccount *account; 59 IMAPaccount *account;
59 mailimap *m_imap; 60 mailimap *m_imap;
60}; 61};
61 62
62#endif 63#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 @@
1#include <stdlib.h> 1#include <stdlib.h>
2#include <sys/stat.h> 2#include <sys/stat.h>
3#include <sys/types.h> 3#include <sys/types.h>
4#include <unistd.h> 4#include <unistd.h>
5#include <fcntl.h> 5#include <fcntl.h>
6#include <string.h> 6#include <string.h>
7#include <qdir.h> 7#include <qdir.h>
8 8
9#include "mailwrapper.h" 9#include "mailwrapper.h"
10#include "logindialog.h" 10#include "logindialog.h"
11//#include "mail.h" 11//#include "mail.h"
12#include "defines.h" 12#include "defines.h"
13 13
14Attachment::Attachment( DocLnk lnk ) 14Attachment::Attachment( DocLnk lnk )
15{ 15{
16 doc = lnk; 16 doc = lnk;
17 size = QFileInfo( doc.file() ).size(); 17 size = QFileInfo( doc.file() ).size();
18} 18}
19 19
20Folder::Folder(const QString&tmp_name, const QString&sep ) 20Folder::Folder(const QString&tmp_name, const QString&sep )
21{ 21{
22 name = tmp_name; 22 name = tmp_name;
23 nameDisplay = name; 23 nameDisplay = name;
24 separator = sep; 24 separator = sep;
25} 25}
26 26
27const QString& Folder::Separator()const 27const QString& Folder::Separator()const
28{ 28{
29 return separator; 29 return separator;
30} 30}
31 31
32IMAPFolder::IMAPFolder(const QString&name,const QString&sep, bool select,const QString&prefix ) 32IMAPFolder::IMAPFolder(const QString&name,const QString&sep, bool select,const QString&prefix )
33 : Folder( name,sep ),m_MaySelect(select) 33 : Folder( name,sep ),m_MaySelect(select)
34{ 34{
35 // Decode IMAP foldername 35 // Decode IMAP foldername
36 nameDisplay = IMAPFolder::decodeFolderName( name ); 36 nameDisplay = IMAPFolder::decodeFolderName( name );
37 qDebug( "folder " + name + " - displayed as " + nameDisplay ); 37 qDebug( "folder " + name + " - displayed as " + nameDisplay );
38 38
39 if (prefix.length()>0) { 39 if (prefix.length()>0) {
40 if (nameDisplay.startsWith(prefix) && nameDisplay.length()>prefix.length()) { 40 if (nameDisplay.startsWith(prefix) && nameDisplay.length()>prefix.length()) {
41 nameDisplay=nameDisplay.right(nameDisplay.length()-prefix.length()); 41 nameDisplay=nameDisplay.right(nameDisplay.length()-prefix.length());
42 } 42 }
43 } 43 }
44} 44}
45 45
46static unsigned char base64chars[] = 46static unsigned char base64chars[] =
47 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+,"; 47 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+,";
48 48
49/** 49/**
50 * Decodes base64 encoded parts of the imapfolder name 50 * Decodes base64 encoded parts of the imapfolder name
51 * Code taken from kde cvs: kdebase/kioslave/imap4/rfcdecoder.cc 51 * Code taken from kde cvs: kdebase/kioslave/imap4/rfcdecoder.cc
52 */ 52 */
53QString IMAPFolder::decodeFolderName( const QString &name ) 53QString IMAPFolder::decodeFolderName( const QString &name )
54{ 54{
55 unsigned char c, i, bitcount; 55 unsigned char c, i, bitcount;
56 unsigned long ucs4, utf16, bitbuf; 56 unsigned long ucs4, utf16, bitbuf;
57 unsigned char base64[256], utf8[6]; 57 unsigned char base64[256], utf8[6];
58 unsigned long srcPtr = 0; 58 unsigned long srcPtr = 0;
59 QCString dst; 59 QCString dst;
60 QCString src = name.ascii(); 60 QCString src = name.ascii();
61 61
62 /* initialize modified base64 decoding table */ 62 /* initialize modified base64 decoding table */
63 memset(base64, UNDEFINED, sizeof(base64)); 63 memset(base64, UNDEFINED, sizeof(base64));
64 for (i = 0; i < sizeof(base64chars); ++i) { 64 for (i = 0; i < sizeof(base64chars); ++i) {
65 base64[(int)base64chars[i]] = i; 65 base64[(int)base64chars[i]] = i;
66 } 66 }
67 67
68 /* loop until end of string */ 68 /* loop until end of string */
69 while (srcPtr < src.length ()) { 69 while (srcPtr < src.length ()) {
70 c = src[srcPtr++]; 70 c = src[srcPtr++];
71 /* deal with literal characters and &- */ 71 /* deal with literal characters and &- */
72 if (c != '&' || src[srcPtr] == '-') { 72 if (c != '&' || src[srcPtr] == '-') {
73 /* encode literally */ 73 /* encode literally */
74 dst += c; 74 dst += c;
75 /* skip over the '-' if this is an &- sequence */ 75 /* skip over the '-' if this is an &- sequence */
76 if (c == '&') 76 if (c == '&')
77 srcPtr++; 77 srcPtr++;
78 } else { 78 } else {
79 /* convert modified UTF-7 -> UTF-16 -> UCS-4 -> UTF-8 -> HEX */ 79 /* convert modified UTF-7 -> UTF-16 -> UCS-4 -> UTF-8 -> HEX */
80 bitbuf = 0; 80 bitbuf = 0;
81 bitcount = 0; 81 bitcount = 0;
82 ucs4 = 0; 82 ucs4 = 0;
83 while ((c = base64[(unsigned char) src[srcPtr]]) != UNDEFINED) { 83 while ((c = base64[(unsigned char) src[srcPtr]]) != UNDEFINED) {
84 ++srcPtr; 84 ++srcPtr;
85 bitbuf = (bitbuf << 6) | c; 85 bitbuf = (bitbuf << 6) | c;
86 bitcount += 6; 86 bitcount += 6;
87 /* enough bits for a UTF-16 character? */ 87 /* enough bits for a UTF-16 character? */
88 if (bitcount >= 16) { 88 if (bitcount >= 16) {
89 bitcount -= 16; 89 bitcount -= 16;
90 utf16 = (bitcount ? bitbuf >> bitcount : bitbuf) & 0xffff; 90 utf16 = (bitcount ? bitbuf >> bitcount : bitbuf) & 0xffff;
91 /* convert UTF16 to UCS4 */ 91 /* convert UTF16 to UCS4 */
92 if (utf16 >= UTF16HIGHSTART && utf16 <= UTF16HIGHEND) { 92 if (utf16 >= UTF16HIGHSTART && utf16 <= UTF16HIGHEND) {
93 ucs4 = (utf16 - UTF16HIGHSTART) << UTF16SHIFT; 93 ucs4 = (utf16 - UTF16HIGHSTART) << UTF16SHIFT;
94 continue; 94 continue;
95 } else if (utf16 >= UTF16LOSTART && utf16 <= UTF16LOEND) { 95 } else if (utf16 >= UTF16LOSTART && utf16 <= UTF16LOEND) {
96 ucs4 += utf16 - UTF16LOSTART + UTF16BASE; 96 ucs4 += utf16 - UTF16LOSTART + UTF16BASE;
97 } else { 97 } else {
98 ucs4 = utf16; 98 ucs4 = utf16;
99 } 99 }
100 /* convert UTF-16 range of UCS4 to UTF-8 */ 100 /* convert UTF-16 range of UCS4 to UTF-8 */
101 if (ucs4 <= 0x7fUL) { 101 if (ucs4 <= 0x7fUL) {
102 utf8[0] = ucs4; 102 utf8[0] = ucs4;
103 i = 1; 103 i = 1;
104 } else if (ucs4 <= 0x7ffUL) { 104 } else if (ucs4 <= 0x7ffUL) {
105 utf8[0] = 0xc0 | (ucs4 >> 6); 105 utf8[0] = 0xc0 | (ucs4 >> 6);
106 utf8[1] = 0x80 | (ucs4 & 0x3f); 106 utf8[1] = 0x80 | (ucs4 & 0x3f);
107 i = 2; 107 i = 2;
108 } else if (ucs4 <= 0xffffUL) { 108 } else if (ucs4 <= 0xffffUL) {
109 utf8[0] = 0xe0 | (ucs4 >> 12); 109 utf8[0] = 0xe0 | (ucs4 >> 12);
110 utf8[1] = 0x80 | ((ucs4 >> 6) & 0x3f); 110 utf8[1] = 0x80 | ((ucs4 >> 6) & 0x3f);
111 utf8[2] = 0x80 | (ucs4 & 0x3f); 111 utf8[2] = 0x80 | (ucs4 & 0x3f);
112 i = 3; 112 i = 3;
113 } else { 113 } else {
114 utf8[0] = 0xf0 | (ucs4 >> 18); 114 utf8[0] = 0xf0 | (ucs4 >> 18);
115 utf8[1] = 0x80 | ((ucs4 >> 12) & 0x3f); 115 utf8[1] = 0x80 | ((ucs4 >> 12) & 0x3f);
116 utf8[2] = 0x80 | ((ucs4 >> 6) & 0x3f); 116 utf8[2] = 0x80 | ((ucs4 >> 6) & 0x3f);
117 utf8[3] = 0x80 | (ucs4 & 0x3f); 117 utf8[3] = 0x80 | (ucs4 & 0x3f);
118 i = 4; 118 i = 4;
119 } 119 }
120 /* copy it */ 120 /* copy it */
121 for (c = 0; c < i; ++c) { 121 for (c = 0; c < i; ++c) {
122 dst += utf8[c]; 122 dst += utf8[c];
123 } 123 }
124 } 124 }
125 } 125 }
126 /* skip over trailing '-' in modified UTF-7 encoding */ 126 /* skip over trailing '-' in modified UTF-7 encoding */
127 if (src[srcPtr] == '-') 127 if (src[srcPtr] == '-')
128 ++srcPtr; 128 ++srcPtr;
129 } 129 }
130 } 130 }
131 131
132 return QString::fromUtf8( dst.data() ); 132 return QString::fromUtf8( dst.data() );
133} 133}
134 134
135MailWrapper::MailWrapper( Settings *s )
136 : QObject()
137{
138 settings = s;
139}
140
141QString MailWrapper::mailsmtpError( int errnum )
142{
143 switch ( errnum ) {
144 case MAILSMTP_NO_ERROR:
145 return tr( "No error" );
146 case MAILSMTP_ERROR_UNEXPECTED_CODE:
147 return tr( "Unexpected error code" );
148 case MAILSMTP_ERROR_SERVICE_NOT_AVAILABLE:
149 return tr( "Service not available" );
150 case MAILSMTP_ERROR_STREAM:
151 return tr( "Stream error" );
152 case MAILSMTP_ERROR_HOSTNAME:
153 return tr( "gethostname() failed" );
154 case MAILSMTP_ERROR_NOT_IMPLEMENTED:
155 return tr( "Not implemented" );
156 case MAILSMTP_ERROR_ACTION_NOT_TAKEN:
157 return tr( "Error, action not taken" );
158 case MAILSMTP_ERROR_EXCEED_STORAGE_ALLOCATION:
159 return tr( "Data exceeds storage allocation" );
160 case MAILSMTP_ERROR_IN_PROCESSING:
161 return tr( "Error in processing" );
162 // case MAILSMTP_ERROR_INSUFFISANT_SYSTEM_STORAGE:
163 // return tr( "Insufficient system storage" );
164 case MAILSMTP_ERROR_MAILBOX_UNAVAILABLE:
165 return tr( "Mailbox unavailable" );
166 case MAILSMTP_ERROR_MAILBOX_NAME_NOT_ALLOWED:
167 return tr( "Mailbox name not allowed" );
168 case MAILSMTP_ERROR_BAD_SEQUENCE_OF_COMMAND:
169 return tr( "Bad command sequence" );
170 case MAILSMTP_ERROR_USER_NOT_LOCAL:
171 return tr( "User not local" );
172 case MAILSMTP_ERROR_TRANSACTION_FAILED:
173 return tr( "Transaction failed" );
174 case MAILSMTP_ERROR_MEMORY:
175 return tr( "Memory error" );
176 case MAILSMTP_ERROR_CONNECTION_REFUSED:
177 return tr( "Connection refused" );
178 default:
179 return tr( "Unknown error code" );
180 }
181}
182
183mailimf_mailbox *MailWrapper::newMailbox(const QString&name, const QString&mail )
184{
185 return mailimf_mailbox_new( strdup( name.latin1() ),
186 strdup( mail.latin1() ) );
187}
188
189mailimf_address_list *MailWrapper::parseAddresses(const QString&addr )
190{
191 mailimf_address_list *addresses;
192
193 if ( addr.isEmpty() ) return NULL;
194
195 addresses = mailimf_address_list_new_empty();
196
197 QStringList list = QStringList::split( ',', addr );
198 QStringList::Iterator it;
199 for ( it = list.begin(); it != list.end(); it++ ) {
200 char *str = strdup( (*it).latin1() );
201 int err = mailimf_address_list_add_parse( addresses, str );
202 if ( err != MAILIMF_NO_ERROR ) {
203 qDebug( "Error parsing" );
204 qDebug( *it );
205 free( str );
206 } else {
207 qDebug( "Parse success! :)" );
208 }
209 }
210
211 return addresses;
212}
213
214mailimf_fields *MailWrapper::createImfFields( Mail *mail )
215{
216 mailimf_fields *fields;
217 mailimf_field *xmailer;
218 mailimf_mailbox *sender, *fromBox;
219 mailimf_mailbox_list *from;
220 mailimf_address_list *to, *cc, *bcc, *reply;
221 char *subject = strdup( mail->getSubject().latin1() );
222 int err;
223
224 sender = newMailbox( mail->getName(), mail->getMail() );
225 if ( sender == NULL ) goto err_free;
226
227 fromBox = newMailbox( mail->getName(), mail->getMail() );
228 if ( fromBox == NULL ) goto err_free_sender;
229
230 from = mailimf_mailbox_list_new_empty();
231 if ( from == NULL ) goto err_free_fromBox;
232
233 err = mailimf_mailbox_list_add( from, fromBox );
234 if ( err != MAILIMF_NO_ERROR ) goto err_free_from;
235
236 to = parseAddresses( mail->getTo() );
237 if ( to == NULL ) goto err_free_from;
238
239 cc = parseAddresses( mail->getCC() );
240 bcc = parseAddresses( mail->getBCC() );
241 reply = parseAddresses( mail->getReply() );
242
243 fields = mailimf_fields_new_with_data( from, sender, reply, to, cc, bcc,
244 NULL, NULL, subject );
245 if ( fields == NULL ) goto err_free_reply;
246
247 xmailer = mailimf_field_new_custom( strdup( "User-Agent" ),
248 strdup( USER_AGENT ) );
249 if ( xmailer == NULL ) goto err_free_fields;
250
251 err = mailimf_fields_add( fields, xmailer );
252 if ( err != MAILIMF_NO_ERROR ) goto err_free_xmailer;
253
254 return fields; // Success :)
255
256err_free_xmailer:
257 mailimf_field_free( xmailer );
258err_free_fields:
259 mailimf_fields_free( fields );
260err_free_reply:
261 mailimf_address_list_free( reply );
262 mailimf_address_list_free( bcc );
263 mailimf_address_list_free( cc );
264 mailimf_address_list_free( to );
265err_free_from:
266 mailimf_mailbox_list_free( from );
267err_free_fromBox:
268 mailimf_mailbox_free( fromBox );
269err_free_sender:
270 mailimf_mailbox_free( sender );
271err_free:
272 free( subject );
273 qDebug( "createImfFields - error" );
274
275 return NULL; // Error :(
276}
277
278mailmime *MailWrapper::buildTxtPart( QString str )
279{
280 mailmime *txtPart;
281 mailmime_fields *fields;
282 mailmime_content *content;
283 mailmime_parameter *param;
284 char *txt = strdup( str.latin1() );
285 int err;
286
287 param = mailmime_parameter_new( strdup( "charset" ),
288 strdup( "iso-8859-1" ) );
289 if ( param == NULL ) goto err_free;
290
291 content = mailmime_content_new_with_str( "text/plain" );
292 if ( content == NULL ) goto err_free_param;
293
294 err = clist_append( content->ct_parameters, param );
295 if ( err != MAILIMF_NO_ERROR ) goto err_free_content;
296
297 fields = mailmime_fields_new_encoding( MAILMIME_MECHANISM_8BIT );
298 if ( fields == NULL ) goto err_free_content;
299
300 txtPart = mailmime_new_empty( content, fields );
301 if ( txtPart == NULL ) goto err_free_fields;
302
303 err = mailmime_set_body_text( txtPart, txt, strlen( txt ) );
304 if ( err != MAILIMF_NO_ERROR ) goto err_free_txtPart;
305
306 return txtPart; // Success :)
307
308err_free_txtPart:
309 mailmime_free( txtPart );
310err_free_fields:
311 mailmime_fields_free( fields );
312err_free_content:
313 mailmime_content_free( content );
314err_free_param:
315 mailmime_parameter_free( param );
316err_free:
317 free( txt );
318 qDebug( "buildTxtPart - error" );
319
320 return NULL; // Error :(
321}
322
323mailmime *MailWrapper::buildFilePart( QString filename, QString mimetype )
324{
325 mailmime * filePart;
326 mailmime_fields * fields;
327 mailmime_content * content;
328 mailmime_parameter * param = NULL;
329 int err;
330
331 int pos = filename.findRev( '/' );
332 QString tmp = filename.right( filename.length() - ( pos + 1 ) );
333 char *name = strdup( tmp.latin1() ); // just filename
334 char *file = strdup( filename.latin1() ); // full name with path
335 char *mime = strdup( mimetype.latin1() ); // mimetype -e.g. text/plain
336
337 fields = mailmime_fields_new_filename(
338 MAILMIME_DISPOSITION_TYPE_ATTACHMENT, name,
339 MAILMIME_MECHANISM_BASE64 );
340 if ( fields == NULL ) goto err_free;
341
342 content = mailmime_content_new_with_str( mime );
343 if ( content == NULL ) goto err_free_fields;
344
345 if ( mimetype.compare( "text/plain" ) == 0 ) {
346 param = mailmime_parameter_new( strdup( "charset" ),
347 strdup( "iso-8859-1" ) );
348 if ( param == NULL ) goto err_free_content;
349
350 err = clist_append( content->ct_parameters, param );
351 if ( err != MAILIMF_NO_ERROR ) goto err_free_param;
352 }
353
354 filePart = mailmime_new_empty( content, fields );
355 if ( filePart == NULL ) goto err_free_param;
356
357 err = mailmime_set_body_file( filePart, file );
358 if ( err != MAILIMF_NO_ERROR ) goto err_free_filePart;
359
360 return filePart; // Success :)
361
362err_free_filePart:
363 mailmime_free( filePart );
364err_free_param:
365 if ( param != NULL ) mailmime_parameter_free( param );
366err_free_content:
367 mailmime_content_free( content );
368err_free_fields:
369 mailmime_fields_free( fields );
370err_free:
371 free( name );
372 free( mime );
373 free( file );
374 qDebug( "buildFilePart - error" );
375
376 return NULL; // Error :(
377}
378
379void MailWrapper::addFileParts( mailmime *message, QList<Attachment> files )
380{
381 Attachment *it;
382 for ( it = files.first(); it; it = files.next() ) {
383 qDebug( "Adding file" );
384 mailmime *filePart;
385 int err;
386
387 filePart = buildFilePart( it->getFileName(), it->getMimeType() );
388 if ( filePart == NULL ) goto err_free;
389
390 err = mailmime_smart_add_part( message, filePart );
391 if ( err != MAILIMF_NO_ERROR ) goto err_free_filePart;
392
393 continue; // Success :)
394
395 err_free_filePart:
396 mailmime_free( filePart );
397 err_free:
398 qDebug( "addFileParts: error adding file:" );
399 qDebug( it->getFileName() );
400 }
401}
402
403mailmime *MailWrapper::createMimeMail( Mail *mail )
404{
405 mailmime *message, *txtPart;
406 mailimf_fields *fields;
407 int err;
408
409 fields = createImfFields( mail );
410 if ( fields == NULL ) goto err_free;
411
412 message = mailmime_new_message_data( NULL );
413 if ( message == NULL ) goto err_free_fields;
414
415 mailmime_set_imf_fields( message, fields );
416
417 txtPart = buildTxtPart( mail->getMessage() );
418 if ( txtPart == NULL ) goto err_free_message;
419
420 err = mailmime_smart_add_part( message, txtPart );
421 if ( err != MAILIMF_NO_ERROR ) goto err_free_txtPart;
422
423 addFileParts( message, mail->getAttachments() );
424
425 return message; // Success :)
426
427err_free_txtPart:
428 mailmime_free( txtPart );
429err_free_message:
430 mailmime_free( message );
431err_free_fields:
432 mailimf_fields_free( fields );
433err_free:
434 qDebug( "createMimeMail: error" );
435
436 return NULL; // Error :(
437}
438
439mailimf_field *MailWrapper::getField( mailimf_fields *fields, int type )
440{
441 mailimf_field *field;
442 clistiter *it;
443
444 it = clist_begin( fields->fld_list );
445 while ( it ) {
446 field = (mailimf_field *) it->data;
447 if ( field->fld_type == type ) {
448 return field;
449 }
450 it = it->next;
451 }
452
453 return NULL;
454}
455
456static void addRcpts( clist *list, mailimf_address_list *addr_list )
457{
458 clistiter *it, *it2;
459
460 for ( it = clist_begin( addr_list->ad_list ); it; it = it->next ) {
461 mailimf_address *addr;
462 addr = (mailimf_address *) it->data;
463
464 if ( addr->ad_type == MAILIMF_ADDRESS_MAILBOX ) {
465 esmtp_address_list_add( list, addr->ad_data.ad_mailbox->mb_addr_spec, 0, NULL );
466 } else if ( addr->ad_type == MAILIMF_ADDRESS_GROUP ) {
467 clist *l = addr->ad_data.ad_group->grp_mb_list->mb_list;
468 for ( it2 = clist_begin( l ); it2; it2 = it2->next ) {
469 mailimf_mailbox *mbox;
470 mbox = (mailimf_mailbox *) it2->data;
471 esmtp_address_list_add( list, mbox->mb_addr_spec, 0, NULL );
472 }
473 }
474 }
475}
476
477clist *MailWrapper::createRcptList( mailimf_fields *fields )
478{
479 clist *rcptList;
480 mailimf_field *field;
481
482 rcptList = esmtp_address_list_new();
483
484 field = getField( fields, MAILIMF_FIELD_TO );
485 if ( field && (field->fld_type == MAILIMF_FIELD_TO)
486 && field->fld_data.fld_to->to_addr_list ) {
487 addRcpts( rcptList, field->fld_data.fld_to->to_addr_list );
488 }
489
490 field = getField( fields, MAILIMF_FIELD_CC );
491 if ( field && (field->fld_type == MAILIMF_FIELD_CC)
492 && field->fld_data.fld_cc->cc_addr_list ) {
493 addRcpts( rcptList, field->fld_data.fld_cc->cc_addr_list );
494 }
495
496 field = getField( fields, MAILIMF_FIELD_BCC );
497 if ( field && (field->fld_type == MAILIMF_FIELD_BCC)
498 && field->fld_data.fld_bcc->bcc_addr_list ) {
499 addRcpts( rcptList, field->fld_data.fld_bcc->bcc_addr_list );
500 }
501
502 return rcptList;
503}
504
505char *MailWrapper::getFrom( mailmime *mail )
506{
507 char *from = NULL;
508
509 mailimf_field *ffrom;
510 ffrom = getField( mail->mm_data.mm_message.mm_fields, MAILIMF_FIELD_FROM );
511 if ( ffrom && (ffrom->fld_type == MAILIMF_FIELD_FROM)
512 && ffrom->fld_data.fld_from->frm_mb_list && ffrom->fld_data.fld_from->frm_mb_list->mb_list ) {
513 clist *cl = ffrom->fld_data.fld_from->frm_mb_list->mb_list;
514 clistiter *it;
515 for ( it = clist_begin( cl ); it; it = it->next ) {
516 mailimf_mailbox *mb = (mailimf_mailbox *) it->data;
517 from = strdup( mb->mb_addr_spec );
518 }
519 }
520
521 return from;
522}
523
524SMTPaccount *MailWrapper::getAccount( QString from )
525{
526 SMTPaccount *smtp;
527
528 QList<Account> list = settings->getAccounts();
529 Account *it;
530 for ( it = list.first(); it; it = list.next() ) {
531 if ( it->getType().compare( "SMTP" ) == 0 ) {
532 smtp = static_cast<SMTPaccount *>(it);
533 if ( smtp->getMail().compare( from ) == 0 ) {
534 qDebug( "SMTPaccount found for" );
535 qDebug( from );
536 return smtp;
537 }
538 }
539 }
540
541 return NULL;
542}
543
544QString MailWrapper::getTmpFile() {
545 int num = 0;
546 QString unique;
547
548 QDir dir( "/tmp" );
549 QStringList::Iterator it;
550
551 QStringList list = dir.entryList( "opiemail-tmp-*" );
552 do {
553 unique.setNum( num++ );
554 } while ( list.contains( "opiemail-tmp-" + unique ) > 0 );
555
556 return "/tmp/opiemail-tmp-" + unique;
557}
558
559void MailWrapper::writeToFile( QString file, mailmime *mail )
560{
561 FILE *f;
562 int err, col = 0;
563
564 f = fopen( file.latin1(), "w" );
565 if ( f == NULL ) {
566 qDebug( "writeToFile: error opening file" );
567 return;
568 }
569
570 err = mailmime_write( f, &col, mail );
571 if ( err != MAILIMF_NO_ERROR ) {
572 fclose( f );
573 qDebug( "writeToFile: error writing mailmime" );
574 return;
575 }
576
577 fclose( f );
578}
579
580void MailWrapper::readFromFile( QString file, char **data, size_t *size )
581{
582 char *buf;
583 struct stat st;
584 int fd, count = 0, total = 0;
585
586 fd = open( file.latin1(), O_RDONLY, 0 );
587 if ( fd == -1 ) return;
588
589 if ( fstat( fd, &st ) != 0 ) goto err_close;
590 if ( !st.st_size ) goto err_close;
591
592 buf = (char *) malloc( st.st_size );
593 if ( !buf ) goto err_close;
594
595 while ( ( total < st.st_size ) && ( count >= 0 ) ) {
596 count = read( fd, buf + total, st.st_size - total );
597 total += count;
598 }
599 if ( count < 0 ) goto err_free;
600
601 *data = buf;
602 *size = st.st_size;
603
604 close( fd );
605
606 return; // Success :)
607
608err_free:
609 free( buf );
610err_close:
611 close( fd );
612}
613
614void progress( size_t current, size_t maximum )
615{
616 qDebug( "Current: %i of %i", current, maximum );
617}
618
619void MailWrapper::smtpSend( mailmime *mail )
620{
621 mailsmtp *session;
622 clist *rcpts;
623 char *from, *data, *server, *user = NULL, *pass = NULL;
624 size_t size;
625 int err;
626 bool ssl;
627 uint16_t port;
628
629
630 from = getFrom( mail );
631 SMTPaccount *smtp = getAccount( from );
632 if ( smtp == NULL ) {
633 free(from);
634 return;
635 }
636 server = strdup( smtp->getServer().latin1() );
637 ssl = smtp->getSSL();
638 port = smtp->getPort().toUInt();
639 rcpts = createRcptList( mail->mm_data.mm_message.mm_fields );
640
641 QString file = getTmpFile();
642 writeToFile( file, mail );
643 readFromFile( file, &data, &size );
644 QFile f( file );
645 f.remove();
646
647 session = mailsmtp_new( 20, &progress );
648 if ( session == NULL ) goto free_mem;
649
650 qDebug( "Servername %s at port %i", server, port );
651 if ( ssl ) {
652 qDebug( "SSL session" );
653 err = mailsmtp_ssl_connect( session, server, port );
654 } else {
655 qDebug( "No SSL session" );
656 err = mailsmtp_socket_connect( session, server, port );
657 }
658 if ( err != MAILSMTP_NO_ERROR ) goto free_mem_session;
659
660 err = mailsmtp_init( session );
661 if ( err != MAILSMTP_NO_ERROR ) goto free_con_session;
662
663 qDebug( "INIT OK" );
664
665 if ( smtp->getLogin() ) {
666 if ( smtp->getUser().isEmpty() || smtp->getPassword().isEmpty() ) {
667 // get'em
668 LoginDialog login( smtp->getUser(), smtp->getPassword(), NULL, 0, true );
669 login.show();
670 if ( QDialog::Accepted == login.exec() ) {
671 // ok
672 user = strdup( login.getUser().latin1() );
673 pass = strdup( login.getPassword().latin1() );
674 } else {
675 goto free_con_session;
676 }
677 } else {
678 user = strdup( smtp->getUser().latin1() );
679 pass = strdup( smtp->getPassword().latin1() );
680 }
681 qDebug( "session->auth: %i", session->auth);
682 err = mailsmtp_auth( session, user, pass );
683 if ( err == MAILSMTP_NO_ERROR ) qDebug("auth ok");
684 qDebug( "Done auth!" );
685 }
686
687 err = mailsmtp_send( session, from, rcpts, data, size );
688 if ( err != MAILSMTP_NO_ERROR ) goto free_con_session;
689
690 qDebug( "Mail sent." );
691
692free_con_session:
693 mailsmtp_quit( session );
694free_mem_session:
695 mailsmtp_free( session );
696free_mem:
697 smtp_address_list_free( rcpts );
698 free( data );
699 free( server );
700 if ( smtp->getLogin() ) {
701 free( user );
702 free( pass );
703 }
704 free( from );
705}
706
707void MailWrapper::sendMail( Mail mail )
708{
709 mailmime *mimeMail;
710
711 mimeMail = createMimeMail( &mail );
712 if ( mimeMail == NULL ) {
713 qDebug( "sendMail: error creating mime mail" );
714 } else {
715 smtpSend( mimeMail );
716 mailmime_free( mimeMail );
717 }
718}
719
720Mail::Mail() 135Mail::Mail()
721 :name(""), mail(""), to(""), cc(""), bcc(""), reply(""), subject(""), message("") 136 :name(""), mail(""), to(""), cc(""), bcc(""), reply(""), subject(""), message("")
722{ 137{
723} 138}
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 @@
1#ifndef MAILWRAPPER_H 1#ifndef MAILWRAPPER_H
2#define MAILWRAPPER_H 2#define MAILWRAPPER_H
3 3
4#include <qpe/applnk.h> 4#include <qpe/applnk.h>
5 5
6#include <libetpan/mailmime.h>
7#include <libetpan/mailimf.h>
8#include <libetpan/mailsmtp.h>
9#include <libetpan/mailstorage.h>
10#include <libetpan/maildriver.h>
11#include <qbitarray.h> 6#include <qbitarray.h>
12#include <qdatetime.h> 7#include <qdatetime.h>
13 8
14#include "settings.h" 9#include "settings.h"
15 10
16class Attachment 11class Attachment
17{ 12{
18public: 13public:
19 Attachment( DocLnk lnk ); 14 Attachment( DocLnk lnk );
20 virtual ~Attachment(){} 15 virtual ~Attachment(){}
21 const QString getFileName()const{ return doc.file(); } 16 const QString getFileName()const{ return doc.file(); }
22 const QString getName()const{ return doc.name(); } 17 const QString getName()const{ return doc.name(); }
23 const QString getMimeType()const{ return doc.type(); } 18 const QString getMimeType()const{ return doc.type(); }
24 const QPixmap getPixmap()const{ return doc.pixmap(); } 19 const QPixmap getPixmap()const{ return doc.pixmap(); }
25 const int getSize()const { return size; } 20 const int getSize()const { return size; }
26 DocLnk getDocLnk() { return doc; } 21 DocLnk getDocLnk() { return doc; }
27 22
28protected: 23protected:
29 DocLnk doc; 24 DocLnk doc;
30 int size; 25 int size;
31 26
32}; 27};
33 28
34class Mail 29class Mail
35{ 30{
36public: 31public:
37 Mail(); 32 Mail();
38 /* Possible that this destructor must not be declared virtual 33 /* Possible that this destructor must not be declared virtual
39 * 'cause it seems that it will never have some child classes. 34 * 'cause it seems that it will never have some child classes.
40 * in this case this object will not get a virtual table -> memory and 35 * in this case this object will not get a virtual table -> memory and
41 * speed will be a little bit better? 36 * speed will be a little bit better?
42 */ 37 */
43 virtual ~Mail(){} 38 virtual ~Mail(){}
44 void addAttachment( Attachment *att ) { attList.append( att ); } 39 void addAttachment( Attachment *att ) { attList.append( att ); }
45 const QList<Attachment>& getAttachments()const { return attList; } 40 const QList<Attachment>& getAttachments()const { return attList; }
46 void removeAttachment( Attachment *att ) { attList.remove( att ); } 41 void removeAttachment( Attachment *att ) { attList.remove( att ); }
47 const QString&getName()const { return name; } 42 const QString&getName()const { return name; }
48 void setName( QString s ) { name = s; } 43 void setName( QString s ) { name = s; }
49 const QString&getMail()const{ return mail; } 44 const QString&getMail()const{ return mail; }
50 void setMail( const QString&s ) { mail = s; } 45 void setMail( const QString&s ) { mail = s; }
51 const QString&getTo()const{ return to; } 46 const QString&getTo()const{ return to; }
52 void setTo( const QString&s ) { to = s; } 47 void setTo( const QString&s ) { to = s; }
53 const QString&getCC()const{ return cc; } 48 const QString&getCC()const{ return cc; }
54 void setCC( const QString&s ) { cc = s; } 49 void setCC( const QString&s ) { cc = s; }
55 const QString&getBCC()const { return bcc; } 50 const QString&getBCC()const { return bcc; }
56 void setBCC( const QString&s ) { bcc = s; } 51 void setBCC( const QString&s ) { bcc = s; }
57 const QString&getMessage()const { return message; } 52 const QString&getMessage()const { return message; }
58 void setMessage( const QString&s ) { message = s; } 53 void setMessage( const QString&s ) { message = s; }
59 const QString&getSubject()const { return subject; } 54 const QString&getSubject()const { return subject; }
60 void setSubject( const QString&s ) { subject = s; } 55 void setSubject( const QString&s ) { subject = s; }
61 const QString&getReply()const{ return reply; } 56 const QString&getReply()const{ return reply; }
62 void setReply( const QString&a ) { reply = a; } 57 void setReply( const QString&a ) { reply = a; }
63 58
64private: 59private:
65 QList<Attachment> attList; 60 QList<Attachment> attList;
66 QString name, mail, to, cc, bcc, reply, subject, message; 61 QString name, mail, to, cc, bcc, reply, subject, message;
67}; 62};
68 63
69class Folder : public QObject 64class Folder : public QObject
70{ 65{
71 Q_OBJECT 66 Q_OBJECT
72 67
73public: 68public:
74 Folder( const QString&init_name,const QString&sep ); 69 Folder( const QString&init_name,const QString&sep );
75 const QString&getDisplayName()const { return nameDisplay; } 70 const QString&getDisplayName()const { return nameDisplay; }
76 const QString&getName()const { return name; } 71 const QString&getName()const { return name; }
77 virtual bool may_select()const{return true;}; 72 virtual bool may_select()const{return true;};
78 const QString&Separator()const; 73 const QString&Separator()const;
79 74
80protected: 75protected:
81 QString nameDisplay, name, separator; 76 QString nameDisplay, name, separator;
82 77
83}; 78};
84 79
85class IMAPFolder : public Folder 80class IMAPFolder : public Folder
86{ 81{
87 public: 82 public:
88 IMAPFolder(const QString&name, const QString&sep, bool select=true,const QString&prefix="" ); 83 IMAPFolder(const QString&name, const QString&sep, bool select=true,const QString&prefix="" );
89 virtual bool may_select()const{return m_MaySelect;} 84 virtual bool may_select()const{return m_MaySelect;}
90 private: 85 private:
91 static QString decodeFolderName( const QString &name ); 86 static QString decodeFolderName( const QString &name );
92 bool m_MaySelect; 87 bool m_MaySelect;
93 88
94}; 89};
95 90
96class MailWrapper : public QObject
97{
98 Q_OBJECT
99
100public:
101 MailWrapper( Settings *s );
102 void sendMail( Mail mail );
103
104private:
105 mailimf_mailbox *newMailbox(const QString&name,const QString&mail );
106 mailimf_address_list *parseAddresses(const QString&addr );
107 mailimf_fields *createImfFields( Mail *mail );
108 mailmime *buildTxtPart( QString str );
109 mailmime *buildFilePart( QString filename, QString mimetype );
110 void addFileParts( mailmime *message, QList<Attachment> files );
111 mailmime *createMimeMail( Mail *mail );
112 void smtpSend( mailmime *mail );
113 mailimf_field *getField( mailimf_fields *fields, int type );
114 clist *createRcptList( mailimf_fields *fields );
115 char *getFrom( mailmime *mail );
116 SMTPaccount *getAccount( QString from );
117 void writeToFile( QString file, mailmime *mail );
118 void readFromFile( QString file, char **data, size_t *size );
119 static QString mailsmtpError( int err );
120 static QString getTmpFile();
121
122 Settings *settings;
123
124};
125
126#endif 91#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 @@
1#ifndef __POP3WRAPPER 1#ifndef __POP3WRAPPER
2#define __POP3WRAPPER 2#define __POP3WRAPPER
3 3
4#include <libetpan/clist.h>
4#include "mailwrapper.h" 5#include "mailwrapper.h"
5#include "abstractmail.h" 6#include "abstractmail.h"
6#include <qmap.h> 7#include <qmap.h>
7#include <qstring.h> 8#include <qstring.h>
8 9
9class RecMail; 10class RecMail;
10class RecBody; 11class RecBody;
11class encodedString; 12class encodedString;
12struct mailpop3; 13struct mailpop3;
13struct mailmessage; 14struct mailmessage;
14struct mailmime; 15struct mailmime;
15struct mailmime_mechanism; 16struct mailmime_mechanism;
17struct mailimf_mailbox_list;
18struct mailimf_mailbox;
19struct mailimf_date_time;
20struct mailimf_group;
21struct mailimf_address_list;
16 22
17class POP3wrapper : public AbstractMail 23class POP3wrapper : public AbstractMail
18{ 24{
19 Q_OBJECT 25 Q_OBJECT
20 26
21public: 27public:
22 POP3wrapper( POP3account *a ); 28 POP3wrapper( POP3account *a );
23 virtual ~POP3wrapper(); 29 virtual ~POP3wrapper();
24 /* mailbox will be ignored */ 30 /* mailbox will be ignored */
25 virtual void listMessages(const QString & mailbox, QList<RecMail> &target ); 31 virtual void listMessages(const QString & mailbox, QList<RecMail> &target );
26 virtual QList<Folder>* listFolders(); 32 virtual QList<Folder>* listFolders();
27 virtual QString fetchTextPart(const RecMail&mail,const RecPart&part); 33 virtual QString fetchTextPart(const RecMail&mail,const RecPart&part);
28 virtual encodedString* fetchDecodedPart(const RecMail&mail,const RecPart&part); 34 virtual encodedString* fetchDecodedPart(const RecMail&mail,const RecPart&part);
29 virtual encodedString* fetchRawPart(const RecMail&mail,const RecPart&part); 35 virtual encodedString* fetchRawPart(const RecMail&mail,const RecPart&part);
30 36
31 virtual void deleteMail(const RecMail&mail); 37 virtual void deleteMail(const RecMail&mail);
32 virtual void answeredMail(const RecMail&mail); 38 virtual void answeredMail(const RecMail&mail);
33 39
34 RecBody fetchBody( const RecMail &mail ); 40 RecBody fetchBody( const RecMail &mail );
35 static void pop3_progress( size_t current, size_t maximum ); 41 static void pop3_progress( size_t current, size_t maximum );
36 42
37protected: 43protected:
38 void login(); 44 void login();
39 void logout(); 45 void logout();
40 46
41 RecMail *parseHeader( const char *header ); 47 RecMail *parseHeader( const char *header );
42 RecBody parseMail( char *message ); 48 RecBody parseMail( char *message );
43 QString parseMailboxList( mailimf_mailbox_list *list ); 49 QString parseMailboxList( mailimf_mailbox_list *list );
44 QString parseMailbox( mailimf_mailbox *box ); 50 QString parseMailbox( mailimf_mailbox *box );
45 QString parseGroup( mailimf_group *group ); 51 QString parseGroup( mailimf_group *group );
46 QString parseAddressList( mailimf_address_list *list ); 52 QString parseAddressList( mailimf_address_list *list );
47 QString parseDateTime( mailimf_date_time *date ); 53 QString parseDateTime( mailimf_date_time *date );
48 54
49 void cleanUpCache(); 55 void cleanUpCache();
50 56
51 void traverseBody(RecBody&target,mailmessage*message,mailmime*mime,unsigned int current_rek=0); 57 void traverseBody(RecBody&target,mailmessage*message,mailmime*mime,unsigned int current_rek=0);
52 static void fillSingleBody(RecPart&target,mailmessage*message,mailmime*mime); 58 static void fillSingleBody(RecPart&target,mailmessage*message,mailmime*mime);
53 static void fillParameters(RecPart&target,clist*parameters); 59 static void fillParameters(RecPart&target,clist*parameters);
54 static QString POP3wrapper::getencoding(mailmime_mechanism*aEnc); 60 static QString POP3wrapper::getencoding(mailmime_mechanism*aEnc);
55 61
56 POP3account *account; 62 POP3account *account;
57 mailpop3 *m_pop3; 63 mailpop3 *m_pop3;
58 QString msgTempName; 64 QString msgTempName;
59 unsigned int last_msg_id; 65 unsigned int last_msg_id;
60 QMap<QString,encodedString*> bodyCache; 66 QMap<QString,encodedString*> bodyCache;
61}; 67};
62 68
63#endif 69#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 @@
1#include <stdlib.h>
2#include <sys/stat.h>
3#include <sys/types.h>
4#include <unistd.h>
5#include <fcntl.h>
6#include <string.h>
7#include <qdir.h>
8
9#include <libetpan/mailmime.h>
10#include <libetpan/mailimf.h>
11#include <libetpan/mailsmtp.h>
12#include <libetpan/mailstorage.h>
13#include <libetpan/maildriver.h>
14
15#include "smtpwrapper.h"
16#include "mailwrapper.h"
17#include "logindialog.h"
18#include "defines.h"
19
20SMTPwrapper::SMTPwrapper( Settings *s )
21 : QObject()
22{
23 settings = s;
24}
25
26QString SMTPwrapper::mailsmtpError( int errnum )
27{
28 switch ( errnum ) {
29 case MAILSMTP_NO_ERROR:
30 return tr( "No error" );
31 case MAILSMTP_ERROR_UNEXPECTED_CODE:
32 return tr( "Unexpected error code" );
33 case MAILSMTP_ERROR_SERVICE_NOT_AVAILABLE:
34 return tr( "Service not available" );
35 case MAILSMTP_ERROR_STREAM:
36 return tr( "Stream error" );
37 case MAILSMTP_ERROR_HOSTNAME:
38 return tr( "gethostname() failed" );
39 case MAILSMTP_ERROR_NOT_IMPLEMENTED:
40 return tr( "Not implemented" );
41 case MAILSMTP_ERROR_ACTION_NOT_TAKEN:
42 return tr( "Error, action not taken" );
43 case MAILSMTP_ERROR_EXCEED_STORAGE_ALLOCATION:
44 return tr( "Data exceeds storage allocation" );
45 case MAILSMTP_ERROR_IN_PROCESSING:
46 return tr( "Error in processing" );
47 // case MAILSMTP_ERROR_INSUFFISANT_SYSTEM_STORAGE:
48 // return tr( "Insufficient system storage" );
49 case MAILSMTP_ERROR_MAILBOX_UNAVAILABLE:
50 return tr( "Mailbox unavailable" );
51 case MAILSMTP_ERROR_MAILBOX_NAME_NOT_ALLOWED:
52 return tr( "Mailbox name not allowed" );
53 case MAILSMTP_ERROR_BAD_SEQUENCE_OF_COMMAND:
54 return tr( "Bad command sequence" );
55 case MAILSMTP_ERROR_USER_NOT_LOCAL:
56 return tr( "User not local" );
57 case MAILSMTP_ERROR_TRANSACTION_FAILED:
58 return tr( "Transaction failed" );
59 case MAILSMTP_ERROR_MEMORY:
60 return tr( "Memory error" );
61 case MAILSMTP_ERROR_CONNECTION_REFUSED:
62 return tr( "Connection refused" );
63 default:
64 return tr( "Unknown error code" );
65 }
66}
67
68mailimf_mailbox *SMTPwrapper::newMailbox(const QString&name, const QString&mail )
69{
70 return mailimf_mailbox_new( strdup( name.latin1() ),
71 strdup( mail.latin1() ) );
72}
73
74mailimf_address_list *SMTPwrapper::parseAddresses(const QString&addr )
75{
76 mailimf_address_list *addresses;
77
78 if ( addr.isEmpty() ) return NULL;
79
80 addresses = mailimf_address_list_new_empty();
81
82 QStringList list = QStringList::split( ',', addr );
83 QStringList::Iterator it;
84 for ( it = list.begin(); it != list.end(); it++ ) {
85 char *str = strdup( (*it).latin1() );
86 int err = mailimf_address_list_add_parse( addresses, str );
87 if ( err != MAILIMF_NO_ERROR ) {
88 qDebug( "Error parsing" );
89 qDebug( *it );
90 free( str );
91 } else {
92 qDebug( "Parse success! :)" );
93 }
94 }
95
96 return addresses;
97}
98
99mailimf_fields *SMTPwrapper::createImfFields(const Mail&mail )
100{
101 mailimf_fields *fields;
102 mailimf_field *xmailer;
103 mailimf_mailbox *sender, *fromBox;
104 mailimf_mailbox_list *from;
105 mailimf_address_list *to, *cc, *bcc, *reply;
106 char *subject = strdup( mail.getSubject().latin1() );
107 int err;
108
109 sender = newMailbox( mail.getName(), mail.getMail() );
110 if ( sender == NULL ) goto err_free;
111
112 fromBox = newMailbox( mail.getName(), mail.getMail() );
113 if ( fromBox == NULL ) goto err_free_sender;
114
115 from = mailimf_mailbox_list_new_empty();
116 if ( from == NULL ) goto err_free_fromBox;
117
118 err = mailimf_mailbox_list_add( from, fromBox );
119 if ( err != MAILIMF_NO_ERROR ) goto err_free_from;
120
121 to = parseAddresses( mail.getTo() );
122 if ( to == NULL ) goto err_free_from;
123
124 cc = parseAddresses( mail.getCC() );
125 bcc = parseAddresses( mail.getBCC() );
126 reply = parseAddresses( mail.getReply() );
127
128 fields = mailimf_fields_new_with_data( from, sender, reply, to, cc, bcc,
129 NULL, NULL, subject );
130 if ( fields == NULL ) goto err_free_reply;
131
132 xmailer = mailimf_field_new_custom( strdup( "User-Agent" ),
133 strdup( USER_AGENT ) );
134 if ( xmailer == NULL ) goto err_free_fields;
135
136 err = mailimf_fields_add( fields, xmailer );
137 if ( err != MAILIMF_NO_ERROR ) goto err_free_xmailer;
138
139 return fields; // Success :)
140
141err_free_xmailer:
142 mailimf_field_free( xmailer );
143err_free_fields:
144 mailimf_fields_free( fields );
145err_free_reply:
146 mailimf_address_list_free( reply );
147 mailimf_address_list_free( bcc );
148 mailimf_address_list_free( cc );
149 mailimf_address_list_free( to );
150err_free_from:
151 mailimf_mailbox_list_free( from );
152err_free_fromBox:
153 mailimf_mailbox_free( fromBox );
154err_free_sender:
155 mailimf_mailbox_free( sender );
156err_free:
157 free( subject );
158 qDebug( "createImfFields - error" );
159
160 return NULL; // Error :(
161}
162
163mailmime *SMTPwrapper::buildTxtPart(const QString&str )
164{
165 mailmime *txtPart;
166 mailmime_fields *fields;
167 mailmime_content *content;
168 mailmime_parameter *param;
169 char *txt = strdup( str.latin1() );
170 int err;
171
172 param = mailmime_parameter_new( strdup( "charset" ),
173 strdup( "iso-8859-1" ) );
174 if ( param == NULL ) goto err_free;
175
176 content = mailmime_content_new_with_str( "text/plain" );
177 if ( content == NULL ) goto err_free_param;
178
179 err = clist_append( content->ct_parameters, param );
180 if ( err != MAILIMF_NO_ERROR ) goto err_free_content;
181
182 fields = mailmime_fields_new_encoding( MAILMIME_MECHANISM_8BIT );
183 if ( fields == NULL ) goto err_free_content;
184
185 txtPart = mailmime_new_empty( content, fields );
186 if ( txtPart == NULL ) goto err_free_fields;
187
188 err = mailmime_set_body_text( txtPart, txt, strlen( txt ) );
189 if ( err != MAILIMF_NO_ERROR ) goto err_free_txtPart;
190
191 return txtPart; // Success :)
192
193err_free_txtPart:
194 mailmime_free( txtPart );
195err_free_fields:
196 mailmime_fields_free( fields );
197err_free_content:
198 mailmime_content_free( content );
199err_free_param:
200 mailmime_parameter_free( param );
201err_free:
202 free( txt );
203 qDebug( "buildTxtPart - error" );
204
205 return NULL; // Error :(
206}
207
208mailmime *SMTPwrapper::buildFilePart(const QString&filename,const QString&mimetype )
209{
210 mailmime * filePart;
211 mailmime_fields * fields;
212 mailmime_content * content;
213 mailmime_parameter * param = NULL;
214 int err;
215
216 int pos = filename.findRev( '/' );
217 QString tmp = filename.right( filename.length() - ( pos + 1 ) );
218 char *name = strdup( tmp.latin1() ); // just filename
219 char *file = strdup( filename.latin1() ); // full name with path
220 char *mime = strdup( mimetype.latin1() ); // mimetype -e.g. text/plain
221
222 fields = mailmime_fields_new_filename(
223 MAILMIME_DISPOSITION_TYPE_ATTACHMENT, name,
224 MAILMIME_MECHANISM_BASE64 );
225 if ( fields == NULL ) goto err_free;
226
227 content = mailmime_content_new_with_str( mime );
228 if ( content == NULL ) goto err_free_fields;
229
230 if ( mimetype.compare( "text/plain" ) == 0 ) {
231 param = mailmime_parameter_new( strdup( "charset" ),
232 strdup( "iso-8859-1" ) );
233 if ( param == NULL ) goto err_free_content;
234
235 err = clist_append( content->ct_parameters, param );
236 if ( err != MAILIMF_NO_ERROR ) goto err_free_param;
237 }
238
239 filePart = mailmime_new_empty( content, fields );
240 if ( filePart == NULL ) goto err_free_param;
241
242 err = mailmime_set_body_file( filePart, file );
243 if ( err != MAILIMF_NO_ERROR ) goto err_free_filePart;
244
245 return filePart; // Success :)
246
247err_free_filePart:
248 mailmime_free( filePart );
249err_free_param:
250 if ( param != NULL ) mailmime_parameter_free( param );
251err_free_content:
252 mailmime_content_free( content );
253err_free_fields:
254 mailmime_fields_free( fields );
255err_free:
256 free( name );
257 free( mime );
258 free( file );
259 qDebug( "buildFilePart - error" );
260
261 return NULL; // Error :(
262}
263
264void SMTPwrapper::addFileParts( mailmime *message,const QList<Attachment>&files )
265{
266 const Attachment *it;
267 /* work around for the brainfucked qlist which can not act with const values */
268 for ( it = ((QList<Attachment>)files).first(); it; it = ((QList<Attachment>)files).next() ) {
269 qDebug( "Adding file" );
270 mailmime *filePart;
271 int err;
272
273 filePart = buildFilePart( it->getFileName(), it->getMimeType() );
274 if ( filePart == NULL ) goto err_free;
275
276 err = mailmime_smart_add_part( message, filePart );
277 if ( err != MAILIMF_NO_ERROR ) goto err_free_filePart;
278
279 continue; // Success :)
280
281 err_free_filePart:
282 mailmime_free( filePart );
283 err_free:
284 qDebug( "addFileParts: error adding file:" );
285 qDebug( it->getFileName() );
286 }
287}
288
289mailmime *SMTPwrapper::createMimeMail(const Mail &mail )
290{
291 mailmime *message, *txtPart;
292 mailimf_fields *fields;
293 int err;
294
295 fields = createImfFields( mail );
296 if ( fields == NULL ) goto err_free;
297
298 message = mailmime_new_message_data( NULL );
299 if ( message == NULL ) goto err_free_fields;
300
301 mailmime_set_imf_fields( message, fields );
302
303 txtPart = buildTxtPart( mail.getMessage() );
304 if ( txtPart == NULL ) goto err_free_message;
305
306 err = mailmime_smart_add_part( message, txtPart );
307 if ( err != MAILIMF_NO_ERROR ) goto err_free_txtPart;
308
309 addFileParts( message, mail.getAttachments() );
310
311 return message; // Success :)
312
313err_free_txtPart:
314 mailmime_free( txtPart );
315err_free_message:
316 mailmime_free( message );
317err_free_fields:
318 mailimf_fields_free( fields );
319err_free:
320 qDebug( "createMimeMail: error" );
321
322 return NULL; // Error :(
323}
324
325mailimf_field *SMTPwrapper::getField( mailimf_fields *fields, int type )
326{
327 mailimf_field *field;
328 clistiter *it;
329
330 it = clist_begin( fields->fld_list );
331 while ( it ) {
332 field = (mailimf_field *) it->data;
333 if ( field->fld_type == type ) {
334 return field;
335 }
336 it = it->next;
337 }
338
339 return NULL;
340}
341
342void SMTPwrapper::addRcpts( clist *list, mailimf_address_list *addr_list )
343{
344 clistiter *it, *it2;
345
346 for ( it = clist_begin( addr_list->ad_list ); it; it = it->next ) {
347 mailimf_address *addr;
348 addr = (mailimf_address *) it->data;
349
350 if ( addr->ad_type == MAILIMF_ADDRESS_MAILBOX ) {
351 esmtp_address_list_add( list, addr->ad_data.ad_mailbox->mb_addr_spec, 0, NULL );
352 } else if ( addr->ad_type == MAILIMF_ADDRESS_GROUP ) {
353 clist *l = addr->ad_data.ad_group->grp_mb_list->mb_list;
354 for ( it2 = clist_begin( l ); it2; it2 = it2->next ) {
355 mailimf_mailbox *mbox;
356 mbox = (mailimf_mailbox *) it2->data;
357 esmtp_address_list_add( list, mbox->mb_addr_spec, 0, NULL );
358 }
359 }
360 }
361}
362
363clist *SMTPwrapper::createRcptList( mailimf_fields *fields )
364{
365 clist *rcptList;
366 mailimf_field *field;
367
368 rcptList = esmtp_address_list_new();
369
370 field = getField( fields, MAILIMF_FIELD_TO );
371 if ( field && (field->fld_type == MAILIMF_FIELD_TO)
372 && field->fld_data.fld_to->to_addr_list ) {
373 addRcpts( rcptList, field->fld_data.fld_to->to_addr_list );
374 }
375
376 field = getField( fields, MAILIMF_FIELD_CC );
377 if ( field && (field->fld_type == MAILIMF_FIELD_CC)
378 && field->fld_data.fld_cc->cc_addr_list ) {
379 addRcpts( rcptList, field->fld_data.fld_cc->cc_addr_list );
380 }
381
382 field = getField( fields, MAILIMF_FIELD_BCC );
383 if ( field && (field->fld_type == MAILIMF_FIELD_BCC)
384 && field->fld_data.fld_bcc->bcc_addr_list ) {
385 addRcpts( rcptList, field->fld_data.fld_bcc->bcc_addr_list );
386 }
387
388 return rcptList;
389}
390
391char *SMTPwrapper::getFrom( mailmime *mail )
392{
393 char *from = NULL;
394
395 mailimf_field *ffrom;
396 ffrom = getField( mail->mm_data.mm_message.mm_fields, MAILIMF_FIELD_FROM );
397 if ( ffrom && (ffrom->fld_type == MAILIMF_FIELD_FROM)
398 && ffrom->fld_data.fld_from->frm_mb_list && ffrom->fld_data.fld_from->frm_mb_list->mb_list ) {
399 clist *cl = ffrom->fld_data.fld_from->frm_mb_list->mb_list;
400 clistiter *it;
401 for ( it = clist_begin( cl ); it; it = it->next ) {
402 mailimf_mailbox *mb = (mailimf_mailbox *) it->data;
403 from = strdup( mb->mb_addr_spec );
404 }
405 }
406
407 return from;
408}
409
410SMTPaccount *SMTPwrapper::getAccount(const QString&from )
411{
412 SMTPaccount *smtp;
413
414 QList<Account> list = settings->getAccounts();
415 Account *it;
416 for ( it = list.first(); it; it = list.next() ) {
417 if ( it->getType().compare( "SMTP" ) == 0 ) {
418 smtp = static_cast<SMTPaccount *>(it);
419 if ( smtp->getMail().compare( from ) == 0 ) {
420 qDebug( "SMTPaccount found for" );
421 qDebug( from );
422 return smtp;
423 }
424 }
425 }
426
427 return NULL;
428}
429
430QString SMTPwrapper::getTmpFile() {
431 int num = 0;
432 QString unique;
433
434 QDir dir( "/tmp" );
435 QStringList::Iterator it;
436
437 QStringList list = dir.entryList( "opiemail-tmp-*" );
438 do {
439 unique.setNum( num++ );
440 } while ( list.contains( "opiemail-tmp-" + unique ) > 0 );
441
442 return "/tmp/opiemail-tmp-" + unique;
443}
444
445void SMTPwrapper::writeToFile(const QString&file, mailmime *mail )
446{
447 FILE *f;
448 int err, col = 0;
449
450 f = fopen( file.latin1(), "w" );
451 if ( f == NULL ) {
452 qDebug( "writeToFile: error opening file" );
453 return;
454 }
455
456 err = mailmime_write( f, &col, mail );
457 if ( err != MAILIMF_NO_ERROR ) {
458 fclose( f );
459 qDebug( "writeToFile: error writing mailmime" );
460 return;
461 }
462
463 fclose( f );
464}
465
466void SMTPwrapper::readFromFile(const QString&file, char **data, size_t *size )
467{
468 char *buf;
469 struct stat st;
470 int fd, count = 0, total = 0;
471
472 fd = open( file.latin1(), O_RDONLY, 0 );
473 if ( fd == -1 ) return;
474
475 if ( fstat( fd, &st ) != 0 ) goto err_close;
476 if ( !st.st_size ) goto err_close;
477
478 buf = (char *) malloc( st.st_size );
479 if ( !buf ) goto err_close;
480
481 while ( ( total < st.st_size ) && ( count >= 0 ) ) {
482 count = read( fd, buf + total, st.st_size - total );
483 total += count;
484 }
485 if ( count < 0 ) goto err_free;
486
487 *data = buf;
488 *size = st.st_size;
489
490 close( fd );
491
492 return; // Success :)
493
494err_free:
495 free( buf );
496err_close:
497 close( fd );
498}
499
500void SMTPwrapper::progress( size_t current, size_t maximum )
501{
502 qDebug( "Current: %i of %i", current, maximum );
503}
504
505void SMTPwrapper::smtpSend( mailmime *mail )
506{
507 mailsmtp *session;
508 clist *rcpts;
509 char *from, *data, *server, *user = NULL, *pass = NULL;
510 size_t size;
511 int err;
512 bool ssl;
513 uint16_t port;
514
515
516 from = getFrom( mail );
517 SMTPaccount *smtp = getAccount( from );
518 if ( smtp == NULL ) {
519 free(from);
520 return;
521 }
522 server = strdup( smtp->getServer().latin1() );
523 ssl = smtp->getSSL();
524 port = smtp->getPort().toUInt();
525 rcpts = createRcptList( mail->mm_data.mm_message.mm_fields );
526
527 QString file = getTmpFile();
528 writeToFile( file, mail );
529 readFromFile( file, &data, &size );
530 QFile f( file );
531 f.remove();
532
533 session = mailsmtp_new( 20, &progress );
534 if ( session == NULL ) goto free_mem;
535
536 qDebug( "Servername %s at port %i", server, port );
537 if ( ssl ) {
538 qDebug( "SSL session" );
539 err = mailsmtp_ssl_connect( session, server, port );
540 } else {
541 qDebug( "No SSL session" );
542 err = mailsmtp_socket_connect( session, server, port );
543 }
544 if ( err != MAILSMTP_NO_ERROR ) goto free_mem_session;
545
546 err = mailsmtp_init( session );
547 if ( err != MAILSMTP_NO_ERROR ) goto free_con_session;
548
549 qDebug( "INIT OK" );
550
551 if ( smtp->getLogin() ) {
552 if ( smtp->getUser().isEmpty() || smtp->getPassword().isEmpty() ) {
553 // get'em
554 LoginDialog login( smtp->getUser(), smtp->getPassword(), NULL, 0, true );
555 login.show();
556 if ( QDialog::Accepted == login.exec() ) {
557 // ok
558 user = strdup( login.getUser().latin1() );
559 pass = strdup( login.getPassword().latin1() );
560 } else {
561 goto free_con_session;
562 }
563 } else {
564 user = strdup( smtp->getUser().latin1() );
565 pass = strdup( smtp->getPassword().latin1() );
566 }
567 qDebug( "session->auth: %i", session->auth);
568 err = mailsmtp_auth( session, user, pass );
569 if ( err == MAILSMTP_NO_ERROR ) qDebug("auth ok");
570 qDebug( "Done auth!" );
571 }
572
573 err = mailsmtp_send( session, from, rcpts, data, size );
574 if ( err != MAILSMTP_NO_ERROR ) goto free_con_session;
575
576 qDebug( "Mail sent." );
577
578free_con_session:
579 mailsmtp_quit( session );
580free_mem_session:
581 mailsmtp_free( session );
582free_mem:
583 smtp_address_list_free( rcpts );
584 free( data );
585 free( server );
586 if ( smtp->getLogin() ) {
587 free( user );
588 free( pass );
589 }
590 free( from );
591}
592
593void SMTPwrapper::sendMail(const Mail&mail )
594{
595 mailmime *mimeMail;
596
597 mimeMail = createMimeMail(mail );
598 if ( mimeMail == NULL ) {
599 qDebug( "sendMail: error creating mime mail" );
600 } else {
601 smtpSend( mimeMail );
602 mailmime_free( mimeMail );
603 }
604}
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 @@
1#ifndef SMTPwrapper_H
2#define SMTPwrapper_H
3
4#include <qpe/applnk.h>
5
6#include <qbitarray.h>
7#include <qdatetime.h>
8#include <libetpan/clist.h>
9
10#include "settings.h"
11
12class Mail;
13class Attachment;
14struct mailimf_fields;
15struct mailimf_field;
16struct mailimf_mailbox;
17struct mailmime;
18struct mailimf_address_list;
19
20class SMTPwrapper : public QObject
21{
22 Q_OBJECT
23
24public:
25 SMTPwrapper( Settings *s );
26 virtual ~SMTPwrapper(){}
27 void sendMail(const Mail& mail );
28
29protected:
30 mailimf_mailbox *newMailbox(const QString&name,const QString&mail );
31 mailimf_fields *createImfFields(const Mail &mail );
32 mailmime *createMimeMail(const Mail&mail );
33
34 mailimf_address_list *parseAddresses(const QString&addr );
35 void addFileParts( mailmime *message,const QList<Attachment>&files );
36 mailmime *buildTxtPart(const QString&str );
37 mailmime *buildFilePart(const QString&filename,const QString&mimetype );
38 void smtpSend( mailmime *mail );
39 mailimf_field *getField( mailimf_fields *fields, int type );
40 clist *createRcptList( mailimf_fields *fields );
41 char *getFrom( mailmime *mail );
42 SMTPaccount *getAccount(const QString&from );
43 void writeToFile(const QString&file, mailmime *mail );
44 void readFromFile(const QString&file, char **data, size_t *size );
45
46 static QString mailsmtpError( int err );
47 static QString getTmpFile();
48 static void progress( size_t current, size_t maximum );
49 static void addRcpts( clist *list, mailimf_address_list *addr_list );
50 Settings *settings;
51};
52
53#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 @@
1 CONFIG += qt warn_on debug quick-app 1 CONFIG += qt warn_on debug quick-app
2 2
3 HEADERS = defines.h \ 3 HEADERS = defines.h \
4 logindialog.h \ 4 logindialog.h \
5 settings.h \ 5 settings.h \
6 editaccounts.h \ 6 editaccounts.h \
7 mailwrapper.h \ 7 mailwrapper.h \
8 composemail.h \ 8 composemail.h \
9 accountview.h \ 9 accountview.h \
10 mainwindow.h \ 10 mainwindow.h \
11 viewmail.h \ 11 viewmail.h \
12 viewmailbase.h \ 12 viewmailbase.h \
13 opiemail.h \ 13 opiemail.h \
14 imapwrapper.h \ 14 imapwrapper.h \
15 mailtypes.h \ 15 mailtypes.h \
16 mailistviewitem.h \ 16 mailistviewitem.h \
17 pop3wrapper.h \ 17 pop3wrapper.h \
18 abstractmail.h \ 18 abstractmail.h \
19 settingsdialog.h \ 19 settingsdialog.h \
20 statuswidget.h 20 statuswidget.h \
21 smtpwrapper.h
21 22
22 SOURCES = main.cpp \ 23 SOURCES = main.cpp \
23 opiemail.cpp \ 24 opiemail.cpp \
24 mainwindow.cpp \ 25 mainwindow.cpp \
25 accountview.cpp \ 26 accountview.cpp \
26 composemail.cpp \ 27 composemail.cpp \
27 mailwrapper.cpp \ 28 mailwrapper.cpp \
28 imapwrapper.cpp \ 29 imapwrapper.cpp \
29 addresspicker.cpp \ 30 addresspicker.cpp \
30 editaccounts.cpp \ 31 editaccounts.cpp \
31 logindialog.cpp \ 32 logindialog.cpp \
32 viewmail.cpp \ 33 viewmail.cpp \
33 viewmailbase.cpp \ 34 viewmailbase.cpp \
34 settings.cpp \ 35 settings.cpp \
35 mailtypes.cpp \ 36 mailtypes.cpp \
36 pop3wrapper.cpp \ 37 pop3wrapper.cpp \
37 abstractmail.cpp \ 38 abstractmail.cpp \
38 settingsdialog.cpp \ 39 settingsdialog.cpp \
39 statuswidget.cpp 40 statuswidget.cpp \
41 smtpwrapper.cpp
40 42
41 INTERFACES = editaccountsui.ui \ 43 INTERFACES = editaccountsui.ui \
42 selectmailtypeui.ui \ 44 selectmailtypeui.ui \
43 imapconfigui.ui \ 45 imapconfigui.ui \
44 pop3configui.ui \ 46 pop3configui.ui \
45 nntpconfigui.ui \ 47 nntpconfigui.ui \
46 smtpconfigui.ui \ 48 smtpconfigui.ui \
47 addresspickerui.ui \ 49 addresspickerui.ui \
48 logindialogui.ui \ 50 logindialogui.ui \
49 composemailui.ui \ 51 composemailui.ui \
50 settingsdialogui.ui \ 52 settingsdialogui.ui \
51 statuswidgetui.ui 53 statuswidgetui.ui
52 54
53INCLUDEPATH += $(OPIEDIR)/include 55INCLUDEPATH += $(OPIEDIR)/include
54 56
55CONFTEST = $$system( echo $CONFIG_TARGET_MACOSX ) 57CONFTEST = $$system( echo $CONFIG_TARGET_MACOSX )
56contains( CONFTEST, y ){ 58contains( CONFTEST, y ){
57 LIBS += -lqpe -letpan -lssl -lcrypto -lopie -liconv 59 LIBS += -lqpe -letpan -lssl -lcrypto -lopie -liconv
58}else{ 60}else{
59 LIBS += -lqpe -letpan -lssl -lcrypto -lopie 61 LIBS += -lqpe -letpan -lssl -lcrypto -lopie
60} 62}
61 63
62TARGET = opiemail 64TARGET = opiemail
63 65
64include ( $(OPIEDIR)/include.pro ) 66include ( $(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 @@
1#include <stdlib.h> 1#include <stdlib.h>
2#include <sys/stat.h> 2#include <sys/stat.h>
3#include <sys/types.h> 3#include <sys/types.h>
4#include <unistd.h> 4#include <unistd.h>
5#include <fcntl.h> 5#include <fcntl.h>
6#include <string.h> 6#include <string.h>
7#include <qdir.h> 7#include <qdir.h>
8 8
9#include "mailwrapper.h" 9#include "mailwrapper.h"
10#include "logindialog.h" 10#include "logindialog.h"
11//#include "mail.h" 11//#include "mail.h"
12#include "defines.h" 12#include "defines.h"
13 13
14Attachment::Attachment( DocLnk lnk ) 14Attachment::Attachment( DocLnk lnk )
15{ 15{
16 doc = lnk; 16 doc = lnk;
17 size = QFileInfo( doc.file() ).size(); 17 size = QFileInfo( doc.file() ).size();
18} 18}
19 19
20Folder::Folder(const QString&tmp_name, const QString&sep ) 20Folder::Folder(const QString&tmp_name, const QString&sep )
21{ 21{
22 name = tmp_name; 22 name = tmp_name;
23 nameDisplay = name; 23 nameDisplay = name;
24 separator = sep; 24 separator = sep;
25} 25}
26 26
27const QString& Folder::Separator()const 27const QString& Folder::Separator()const
28{ 28{
29 return separator; 29 return separator;
30} 30}
31 31
32IMAPFolder::IMAPFolder(const QString&name,const QString&sep, bool select,const QString&prefix ) 32IMAPFolder::IMAPFolder(const QString&name,const QString&sep, bool select,const QString&prefix )
33 : Folder( name,sep ),m_MaySelect(select) 33 : Folder( name,sep ),m_MaySelect(select)
34{ 34{
35 // Decode IMAP foldername 35 // Decode IMAP foldername
36 nameDisplay = IMAPFolder::decodeFolderName( name ); 36 nameDisplay = IMAPFolder::decodeFolderName( name );
37 qDebug( "folder " + name + " - displayed as " + nameDisplay ); 37 qDebug( "folder " + name + " - displayed as " + nameDisplay );
38 38
39 if (prefix.length()>0) { 39 if (prefix.length()>0) {
40 if (nameDisplay.startsWith(prefix) && nameDisplay.length()>prefix.length()) { 40 if (nameDisplay.startsWith(prefix) && nameDisplay.length()>prefix.length()) {
41 nameDisplay=nameDisplay.right(nameDisplay.length()-prefix.length()); 41 nameDisplay=nameDisplay.right(nameDisplay.length()-prefix.length());
42 } 42 }
43 } 43 }
44} 44}
45 45
46static unsigned char base64chars[] = 46static unsigned char base64chars[] =
47 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+,"; 47 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+,";
48 48
49/** 49/**
50 * Decodes base64 encoded parts of the imapfolder name 50 * Decodes base64 encoded parts of the imapfolder name
51 * Code taken from kde cvs: kdebase/kioslave/imap4/rfcdecoder.cc 51 * Code taken from kde cvs: kdebase/kioslave/imap4/rfcdecoder.cc
52 */ 52 */
53QString IMAPFolder::decodeFolderName( const QString &name ) 53QString IMAPFolder::decodeFolderName( const QString &name )
54{ 54{
55 unsigned char c, i, bitcount; 55 unsigned char c, i, bitcount;
56 unsigned long ucs4, utf16, bitbuf; 56 unsigned long ucs4, utf16, bitbuf;
57 unsigned char base64[256], utf8[6]; 57 unsigned char base64[256], utf8[6];
58 unsigned long srcPtr = 0; 58 unsigned long srcPtr = 0;
59 QCString dst; 59 QCString dst;
60 QCString src = name.ascii(); 60 QCString src = name.ascii();
61 61
62 /* initialize modified base64 decoding table */ 62 /* initialize modified base64 decoding table */
63 memset(base64, UNDEFINED, sizeof(base64)); 63 memset(base64, UNDEFINED, sizeof(base64));
64 for (i = 0; i < sizeof(base64chars); ++i) { 64 for (i = 0; i < sizeof(base64chars); ++i) {
65 base64[(int)base64chars[i]] = i; 65 base64[(int)base64chars[i]] = i;
66 } 66 }
67 67
68 /* loop until end of string */ 68 /* loop until end of string */
69 while (srcPtr < src.length ()) { 69 while (srcPtr < src.length ()) {
70 c = src[srcPtr++]; 70 c = src[srcPtr++];
71 /* deal with literal characters and &- */ 71 /* deal with literal characters and &- */
72 if (c != '&' || src[srcPtr] == '-') { 72 if (c != '&' || src[srcPtr] == '-') {
73 /* encode literally */ 73 /* encode literally */
74 dst += c; 74 dst += c;
75 /* skip over the '-' if this is an &- sequence */ 75 /* skip over the '-' if this is an &- sequence */
76 if (c == '&') 76 if (c == '&')
77 srcPtr++; 77 srcPtr++;
78 } else { 78 } else {
79 /* convert modified UTF-7 -> UTF-16 -> UCS-4 -> UTF-8 -> HEX */ 79 /* convert modified UTF-7 -> UTF-16 -> UCS-4 -> UTF-8 -> HEX */
80 bitbuf = 0; 80 bitbuf = 0;
81 bitcount = 0; 81 bitcount = 0;
82 ucs4 = 0; 82 ucs4 = 0;
83 while ((c = base64[(unsigned char) src[srcPtr]]) != UNDEFINED) { 83 while ((c = base64[(unsigned char) src[srcPtr]]) != UNDEFINED) {
84 ++srcPtr; 84 ++srcPtr;
85 bitbuf = (bitbuf << 6) | c; 85 bitbuf = (bitbuf << 6) | c;
86 bitcount += 6; 86 bitcount += 6;
87 /* enough bits for a UTF-16 character? */ 87 /* enough bits for a UTF-16 character? */
88 if (bitcount >= 16) { 88 if (bitcount >= 16) {
89 bitcount -= 16; 89 bitcount -= 16;
90 utf16 = (bitcount ? bitbuf >> bitcount : bitbuf) & 0xffff; 90 utf16 = (bitcount ? bitbuf >> bitcount : bitbuf) & 0xffff;
91 /* convert UTF16 to UCS4 */ 91 /* convert UTF16 to UCS4 */
92 if (utf16 >= UTF16HIGHSTART && utf16 <= UTF16HIGHEND) { 92 if (utf16 >= UTF16HIGHSTART && utf16 <= UTF16HIGHEND) {
93 ucs4 = (utf16 - UTF16HIGHSTART) << UTF16SHIFT; 93 ucs4 = (utf16 - UTF16HIGHSTART) << UTF16SHIFT;
94 continue; 94 continue;
95 } else if (utf16 >= UTF16LOSTART && utf16 <= UTF16LOEND) { 95 } else if (utf16 >= UTF16LOSTART && utf16 <= UTF16LOEND) {
96 ucs4 += utf16 - UTF16LOSTART + UTF16BASE; 96 ucs4 += utf16 - UTF16LOSTART + UTF16BASE;
97 } else { 97 } else {
98 ucs4 = utf16; 98 ucs4 = utf16;
99 } 99 }
100 /* convert UTF-16 range of UCS4 to UTF-8 */ 100 /* convert UTF-16 range of UCS4 to UTF-8 */
101 if (ucs4 <= 0x7fUL) { 101 if (ucs4 <= 0x7fUL) {
102 utf8[0] = ucs4; 102 utf8[0] = ucs4;
103 i = 1; 103 i = 1;
104 } else if (ucs4 <= 0x7ffUL) { 104 } else if (ucs4 <= 0x7ffUL) {
105 utf8[0] = 0xc0 | (ucs4 >> 6); 105 utf8[0] = 0xc0 | (ucs4 >> 6);
106 utf8[1] = 0x80 | (ucs4 & 0x3f); 106 utf8[1] = 0x80 | (ucs4 & 0x3f);
107 i = 2; 107 i = 2;
108 } else if (ucs4 <= 0xffffUL) { 108 } else if (ucs4 <= 0xffffUL) {
109 utf8[0] = 0xe0 | (ucs4 >> 12); 109 utf8[0] = 0xe0 | (ucs4 >> 12);
110 utf8[1] = 0x80 | ((ucs4 >> 6) & 0x3f); 110 utf8[1] = 0x80 | ((ucs4 >> 6) & 0x3f);
111 utf8[2] = 0x80 | (ucs4 & 0x3f); 111 utf8[2] = 0x80 | (ucs4 & 0x3f);
112 i = 3; 112 i = 3;
113 } else { 113 } else {
114 utf8[0] = 0xf0 | (ucs4 >> 18); 114 utf8[0] = 0xf0 | (ucs4 >> 18);
115 utf8[1] = 0x80 | ((ucs4 >> 12) & 0x3f); 115 utf8[1] = 0x80 | ((ucs4 >> 12) & 0x3f);
116 utf8[2] = 0x80 | ((ucs4 >> 6) & 0x3f); 116 utf8[2] = 0x80 | ((ucs4 >> 6) & 0x3f);
117 utf8[3] = 0x80 | (ucs4 & 0x3f); 117 utf8[3] = 0x80 | (ucs4 & 0x3f);
118 i = 4; 118 i = 4;
119 } 119 }
120 /* copy it */ 120 /* copy it */
121 for (c = 0; c < i; ++c) { 121 for (c = 0; c < i; ++c) {
122 dst += utf8[c]; 122 dst += utf8[c];
123 } 123 }
124 } 124 }
125 } 125 }
126 /* skip over trailing '-' in modified UTF-7 encoding */ 126 /* skip over trailing '-' in modified UTF-7 encoding */
127 if (src[srcPtr] == '-') 127 if (src[srcPtr] == '-')
128 ++srcPtr; 128 ++srcPtr;
129 } 129 }
130 } 130 }
131 131
132 return QString::fromUtf8( dst.data() ); 132 return QString::fromUtf8( dst.data() );
133} 133}
134 134
135MailWrapper::MailWrapper( Settings *s )
136 : QObject()
137{
138 settings = s;
139}
140
141QString MailWrapper::mailsmtpError( int errnum )
142{
143 switch ( errnum ) {
144 case MAILSMTP_NO_ERROR:
145 return tr( "No error" );
146 case MAILSMTP_ERROR_UNEXPECTED_CODE:
147 return tr( "Unexpected error code" );
148 case MAILSMTP_ERROR_SERVICE_NOT_AVAILABLE:
149 return tr( "Service not available" );
150 case MAILSMTP_ERROR_STREAM:
151 return tr( "Stream error" );
152 case MAILSMTP_ERROR_HOSTNAME:
153 return tr( "gethostname() failed" );
154 case MAILSMTP_ERROR_NOT_IMPLEMENTED:
155 return tr( "Not implemented" );
156 case MAILSMTP_ERROR_ACTION_NOT_TAKEN:
157 return tr( "Error, action not taken" );
158 case MAILSMTP_ERROR_EXCEED_STORAGE_ALLOCATION:
159 return tr( "Data exceeds storage allocation" );
160 case MAILSMTP_ERROR_IN_PROCESSING:
161 return tr( "Error in processing" );
162 // case MAILSMTP_ERROR_INSUFFISANT_SYSTEM_STORAGE:
163 // return tr( "Insufficient system storage" );
164 case MAILSMTP_ERROR_MAILBOX_UNAVAILABLE:
165 return tr( "Mailbox unavailable" );
166 case MAILSMTP_ERROR_MAILBOX_NAME_NOT_ALLOWED:
167 return tr( "Mailbox name not allowed" );
168 case MAILSMTP_ERROR_BAD_SEQUENCE_OF_COMMAND:
169 return tr( "Bad command sequence" );
170 case MAILSMTP_ERROR_USER_NOT_LOCAL:
171 return tr( "User not local" );
172 case MAILSMTP_ERROR_TRANSACTION_FAILED:
173 return tr( "Transaction failed" );
174 case MAILSMTP_ERROR_MEMORY:
175 return tr( "Memory error" );
176 case MAILSMTP_ERROR_CONNECTION_REFUSED:
177 return tr( "Connection refused" );
178 default:
179 return tr( "Unknown error code" );
180 }
181}
182
183mailimf_mailbox *MailWrapper::newMailbox(const QString&name, const QString&mail )
184{
185 return mailimf_mailbox_new( strdup( name.latin1() ),
186 strdup( mail.latin1() ) );
187}
188
189mailimf_address_list *MailWrapper::parseAddresses(const QString&addr )
190{
191 mailimf_address_list *addresses;
192
193 if ( addr.isEmpty() ) return NULL;
194
195 addresses = mailimf_address_list_new_empty();
196
197 QStringList list = QStringList::split( ',', addr );
198 QStringList::Iterator it;
199 for ( it = list.begin(); it != list.end(); it++ ) {
200 char *str = strdup( (*it).latin1() );
201 int err = mailimf_address_list_add_parse( addresses, str );
202 if ( err != MAILIMF_NO_ERROR ) {
203 qDebug( "Error parsing" );
204 qDebug( *it );
205 free( str );
206 } else {
207 qDebug( "Parse success! :)" );
208 }
209 }
210
211 return addresses;
212}
213
214mailimf_fields *MailWrapper::createImfFields( Mail *mail )
215{
216 mailimf_fields *fields;
217 mailimf_field *xmailer;
218 mailimf_mailbox *sender, *fromBox;
219 mailimf_mailbox_list *from;
220 mailimf_address_list *to, *cc, *bcc, *reply;
221 char *subject = strdup( mail->getSubject().latin1() );
222 int err;
223
224 sender = newMailbox( mail->getName(), mail->getMail() );
225 if ( sender == NULL ) goto err_free;
226
227 fromBox = newMailbox( mail->getName(), mail->getMail() );
228 if ( fromBox == NULL ) goto err_free_sender;
229
230 from = mailimf_mailbox_list_new_empty();
231 if ( from == NULL ) goto err_free_fromBox;
232
233 err = mailimf_mailbox_list_add( from, fromBox );
234 if ( err != MAILIMF_NO_ERROR ) goto err_free_from;
235
236 to = parseAddresses( mail->getTo() );
237 if ( to == NULL ) goto err_free_from;
238
239 cc = parseAddresses( mail->getCC() );
240 bcc = parseAddresses( mail->getBCC() );
241 reply = parseAddresses( mail->getReply() );
242
243 fields = mailimf_fields_new_with_data( from, sender, reply, to, cc, bcc,
244 NULL, NULL, subject );
245 if ( fields == NULL ) goto err_free_reply;
246
247 xmailer = mailimf_field_new_custom( strdup( "User-Agent" ),
248 strdup( USER_AGENT ) );
249 if ( xmailer == NULL ) goto err_free_fields;
250
251 err = mailimf_fields_add( fields, xmailer );
252 if ( err != MAILIMF_NO_ERROR ) goto err_free_xmailer;
253
254 return fields; // Success :)
255
256err_free_xmailer:
257 mailimf_field_free( xmailer );
258err_free_fields:
259 mailimf_fields_free( fields );
260err_free_reply:
261 mailimf_address_list_free( reply );
262 mailimf_address_list_free( bcc );
263 mailimf_address_list_free( cc );
264 mailimf_address_list_free( to );
265err_free_from:
266 mailimf_mailbox_list_free( from );
267err_free_fromBox:
268 mailimf_mailbox_free( fromBox );
269err_free_sender:
270 mailimf_mailbox_free( sender );
271err_free:
272 free( subject );
273 qDebug( "createImfFields - error" );
274
275 return NULL; // Error :(
276}
277
278mailmime *MailWrapper::buildTxtPart( QString str )
279{
280 mailmime *txtPart;
281 mailmime_fields *fields;
282 mailmime_content *content;
283 mailmime_parameter *param;
284 char *txt = strdup( str.latin1() );
285 int err;
286
287 param = mailmime_parameter_new( strdup( "charset" ),
288 strdup( "iso-8859-1" ) );
289 if ( param == NULL ) goto err_free;
290
291 content = mailmime_content_new_with_str( "text/plain" );
292 if ( content == NULL ) goto err_free_param;
293
294 err = clist_append( content->ct_parameters, param );
295 if ( err != MAILIMF_NO_ERROR ) goto err_free_content;
296
297 fields = mailmime_fields_new_encoding( MAILMIME_MECHANISM_8BIT );
298 if ( fields == NULL ) goto err_free_content;
299
300 txtPart = mailmime_new_empty( content, fields );
301 if ( txtPart == NULL ) goto err_free_fields;
302
303 err = mailmime_set_body_text( txtPart, txt, strlen( txt ) );
304 if ( err != MAILIMF_NO_ERROR ) goto err_free_txtPart;
305
306 return txtPart; // Success :)
307
308err_free_txtPart:
309 mailmime_free( txtPart );
310err_free_fields:
311 mailmime_fields_free( fields );
312err_free_content:
313 mailmime_content_free( content );
314err_free_param:
315 mailmime_parameter_free( param );
316err_free:
317 free( txt );
318 qDebug( "buildTxtPart - error" );
319
320 return NULL; // Error :(
321}
322
323mailmime *MailWrapper::buildFilePart( QString filename, QString mimetype )
324{
325 mailmime * filePart;
326 mailmime_fields * fields;
327 mailmime_content * content;
328 mailmime_parameter * param = NULL;
329 int err;
330
331 int pos = filename.findRev( '/' );
332 QString tmp = filename.right( filename.length() - ( pos + 1 ) );
333 char *name = strdup( tmp.latin1() ); // just filename
334 char *file = strdup( filename.latin1() ); // full name with path
335 char *mime = strdup( mimetype.latin1() ); // mimetype -e.g. text/plain
336
337 fields = mailmime_fields_new_filename(
338 MAILMIME_DISPOSITION_TYPE_ATTACHMENT, name,
339 MAILMIME_MECHANISM_BASE64 );
340 if ( fields == NULL ) goto err_free;
341
342 content = mailmime_content_new_with_str( mime );
343 if ( content == NULL ) goto err_free_fields;
344
345 if ( mimetype.compare( "text/plain" ) == 0 ) {
346 param = mailmime_parameter_new( strdup( "charset" ),
347 strdup( "iso-8859-1" ) );
348 if ( param == NULL ) goto err_free_content;
349
350 err = clist_append( content->ct_parameters, param );
351 if ( err != MAILIMF_NO_ERROR ) goto err_free_param;
352 }
353
354 filePart = mailmime_new_empty( content, fields );
355 if ( filePart == NULL ) goto err_free_param;
356
357 err = mailmime_set_body_file( filePart, file );
358 if ( err != MAILIMF_NO_ERROR ) goto err_free_filePart;
359
360 return filePart; // Success :)
361
362err_free_filePart:
363 mailmime_free( filePart );
364err_free_param:
365 if ( param != NULL ) mailmime_parameter_free( param );
366err_free_content:
367 mailmime_content_free( content );
368err_free_fields:
369 mailmime_fields_free( fields );
370err_free:
371 free( name );
372 free( mime );
373 free( file );
374 qDebug( "buildFilePart - error" );
375
376 return NULL; // Error :(
377}
378
379void MailWrapper::addFileParts( mailmime *message, QList<Attachment> files )
380{
381 Attachment *it;
382 for ( it = files.first(); it; it = files.next() ) {
383 qDebug( "Adding file" );
384 mailmime *filePart;
385 int err;
386
387 filePart = buildFilePart( it->getFileName(), it->getMimeType() );
388 if ( filePart == NULL ) goto err_free;
389
390 err = mailmime_smart_add_part( message, filePart );
391 if ( err != MAILIMF_NO_ERROR ) goto err_free_filePart;
392
393 continue; // Success :)
394
395 err_free_filePart:
396 mailmime_free( filePart );
397 err_free:
398 qDebug( "addFileParts: error adding file:" );
399 qDebug( it->getFileName() );
400 }
401}
402
403mailmime *MailWrapper::createMimeMail( Mail *mail )
404{
405 mailmime *message, *txtPart;
406 mailimf_fields *fields;
407 int err;
408
409 fields = createImfFields( mail );
410 if ( fields == NULL ) goto err_free;
411
412 message = mailmime_new_message_data( NULL );
413 if ( message == NULL ) goto err_free_fields;
414
415 mailmime_set_imf_fields( message, fields );
416
417 txtPart = buildTxtPart( mail->getMessage() );
418 if ( txtPart == NULL ) goto err_free_message;
419
420 err = mailmime_smart_add_part( message, txtPart );
421 if ( err != MAILIMF_NO_ERROR ) goto err_free_txtPart;
422
423 addFileParts( message, mail->getAttachments() );
424
425 return message; // Success :)
426
427err_free_txtPart:
428 mailmime_free( txtPart );
429err_free_message:
430 mailmime_free( message );
431err_free_fields:
432 mailimf_fields_free( fields );
433err_free:
434 qDebug( "createMimeMail: error" );
435
436 return NULL; // Error :(
437}
438
439mailimf_field *MailWrapper::getField( mailimf_fields *fields, int type )
440{
441 mailimf_field *field;
442 clistiter *it;
443
444 it = clist_begin( fields->fld_list );
445 while ( it ) {
446 field = (mailimf_field *) it->data;
447 if ( field->fld_type == type ) {
448 return field;
449 }
450 it = it->next;
451 }
452
453 return NULL;
454}
455
456static void addRcpts( clist *list, mailimf_address_list *addr_list )
457{
458 clistiter *it, *it2;
459
460 for ( it = clist_begin( addr_list->ad_list ); it; it = it->next ) {
461 mailimf_address *addr;
462 addr = (mailimf_address *) it->data;
463
464 if ( addr->ad_type == MAILIMF_ADDRESS_MAILBOX ) {
465 esmtp_address_list_add( list, addr->ad_data.ad_mailbox->mb_addr_spec, 0, NULL );
466 } else if ( addr->ad_type == MAILIMF_ADDRESS_GROUP ) {
467 clist *l = addr->ad_data.ad_group->grp_mb_list->mb_list;
468 for ( it2 = clist_begin( l ); it2; it2 = it2->next ) {
469 mailimf_mailbox *mbox;
470 mbox = (mailimf_mailbox *) it2->data;
471 esmtp_address_list_add( list, mbox->mb_addr_spec, 0, NULL );
472 }
473 }
474 }
475}
476
477clist *MailWrapper::createRcptList( mailimf_fields *fields )
478{
479 clist *rcptList;
480 mailimf_field *field;
481
482 rcptList = esmtp_address_list_new();
483
484 field = getField( fields, MAILIMF_FIELD_TO );
485 if ( field && (field->fld_type == MAILIMF_FIELD_TO)
486 && field->fld_data.fld_to->to_addr_list ) {
487 addRcpts( rcptList, field->fld_data.fld_to->to_addr_list );
488 }
489
490 field = getField( fields, MAILIMF_FIELD_CC );
491 if ( field && (field->fld_type == MAILIMF_FIELD_CC)
492 && field->fld_data.fld_cc->cc_addr_list ) {
493 addRcpts( rcptList, field->fld_data.fld_cc->cc_addr_list );
494 }
495
496 field = getField( fields, MAILIMF_FIELD_BCC );
497 if ( field && (field->fld_type == MAILIMF_FIELD_BCC)
498 && field->fld_data.fld_bcc->bcc_addr_list ) {
499 addRcpts( rcptList, field->fld_data.fld_bcc->bcc_addr_list );
500 }
501
502 return rcptList;
503}
504
505char *MailWrapper::getFrom( mailmime *mail )
506{
507 char *from = NULL;
508
509 mailimf_field *ffrom;
510 ffrom = getField( mail->mm_data.mm_message.mm_fields, MAILIMF_FIELD_FROM );
511 if ( ffrom && (ffrom->fld_type == MAILIMF_FIELD_FROM)
512 && ffrom->fld_data.fld_from->frm_mb_list && ffrom->fld_data.fld_from->frm_mb_list->mb_list ) {
513 clist *cl = ffrom->fld_data.fld_from->frm_mb_list->mb_list;
514 clistiter *it;
515 for ( it = clist_begin( cl ); it; it = it->next ) {
516 mailimf_mailbox *mb = (mailimf_mailbox *) it->data;
517 from = strdup( mb->mb_addr_spec );
518 }
519 }
520
521 return from;
522}
523
524SMTPaccount *MailWrapper::getAccount( QString from )
525{
526 SMTPaccount *smtp;
527
528 QList<Account> list = settings->getAccounts();
529 Account *it;
530 for ( it = list.first(); it; it = list.next() ) {
531 if ( it->getType().compare( "SMTP" ) == 0 ) {
532 smtp = static_cast<SMTPaccount *>(it);
533 if ( smtp->getMail().compare( from ) == 0 ) {
534 qDebug( "SMTPaccount found for" );
535 qDebug( from );
536 return smtp;
537 }
538 }
539 }
540
541 return NULL;
542}
543
544QString MailWrapper::getTmpFile() {
545 int num = 0;
546 QString unique;
547
548 QDir dir( "/tmp" );
549 QStringList::Iterator it;
550
551 QStringList list = dir.entryList( "opiemail-tmp-*" );
552 do {
553 unique.setNum( num++ );
554 } while ( list.contains( "opiemail-tmp-" + unique ) > 0 );
555
556 return "/tmp/opiemail-tmp-" + unique;
557}
558
559void MailWrapper::writeToFile( QString file, mailmime *mail )
560{
561 FILE *f;
562 int err, col = 0;
563
564 f = fopen( file.latin1(), "w" );
565 if ( f == NULL ) {
566 qDebug( "writeToFile: error opening file" );
567 return;
568 }
569
570 err = mailmime_write( f, &col, mail );
571 if ( err != MAILIMF_NO_ERROR ) {
572 fclose( f );
573 qDebug( "writeToFile: error writing mailmime" );
574 return;
575 }
576
577 fclose( f );
578}
579
580void MailWrapper::readFromFile( QString file, char **data, size_t *size )
581{
582 char *buf;
583 struct stat st;
584 int fd, count = 0, total = 0;
585
586 fd = open( file.latin1(), O_RDONLY, 0 );
587 if ( fd == -1 ) return;
588
589 if ( fstat( fd, &st ) != 0 ) goto err_close;
590 if ( !st.st_size ) goto err_close;
591
592 buf = (char *) malloc( st.st_size );
593 if ( !buf ) goto err_close;
594
595 while ( ( total < st.st_size ) && ( count >= 0 ) ) {
596 count = read( fd, buf + total, st.st_size - total );
597 total += count;
598 }
599 if ( count < 0 ) goto err_free;
600
601 *data = buf;
602 *size = st.st_size;
603
604 close( fd );
605
606 return; // Success :)
607
608err_free:
609 free( buf );
610err_close:
611 close( fd );
612}
613
614void progress( size_t current, size_t maximum )
615{
616 qDebug( "Current: %i of %i", current, maximum );
617}
618
619void MailWrapper::smtpSend( mailmime *mail )
620{
621 mailsmtp *session;
622 clist *rcpts;
623 char *from, *data, *server, *user = NULL, *pass = NULL;
624 size_t size;
625 int err;
626 bool ssl;
627 uint16_t port;
628
629
630 from = getFrom( mail );
631 SMTPaccount *smtp = getAccount( from );
632 if ( smtp == NULL ) {
633 free(from);
634 return;
635 }
636 server = strdup( smtp->getServer().latin1() );
637 ssl = smtp->getSSL();
638 port = smtp->getPort().toUInt();
639 rcpts = createRcptList( mail->mm_data.mm_message.mm_fields );
640
641 QString file = getTmpFile();
642 writeToFile( file, mail );
643 readFromFile( file, &data, &size );
644 QFile f( file );
645 f.remove();
646
647 session = mailsmtp_new( 20, &progress );
648 if ( session == NULL ) goto free_mem;
649
650 qDebug( "Servername %s at port %i", server, port );
651 if ( ssl ) {
652 qDebug( "SSL session" );
653 err = mailsmtp_ssl_connect( session, server, port );
654 } else {
655 qDebug( "No SSL session" );
656 err = mailsmtp_socket_connect( session, server, port );
657 }
658 if ( err != MAILSMTP_NO_ERROR ) goto free_mem_session;
659
660 err = mailsmtp_init( session );
661 if ( err != MAILSMTP_NO_ERROR ) goto free_con_session;
662
663 qDebug( "INIT OK" );
664
665 if ( smtp->getLogin() ) {
666 if ( smtp->getUser().isEmpty() || smtp->getPassword().isEmpty() ) {
667 // get'em
668 LoginDialog login( smtp->getUser(), smtp->getPassword(), NULL, 0, true );
669 login.show();
670 if ( QDialog::Accepted == login.exec() ) {
671 // ok
672 user = strdup( login.getUser().latin1() );
673 pass = strdup( login.getPassword().latin1() );
674 } else {
675 goto free_con_session;
676 }
677 } else {
678 user = strdup( smtp->getUser().latin1() );
679 pass = strdup( smtp->getPassword().latin1() );
680 }
681 qDebug( "session->auth: %i", session->auth);
682 err = mailsmtp_auth( session, user, pass );
683 if ( err == MAILSMTP_NO_ERROR ) qDebug("auth ok");
684 qDebug( "Done auth!" );
685 }
686
687 err = mailsmtp_send( session, from, rcpts, data, size );
688 if ( err != MAILSMTP_NO_ERROR ) goto free_con_session;
689
690 qDebug( "Mail sent." );
691
692free_con_session:
693 mailsmtp_quit( session );
694free_mem_session:
695 mailsmtp_free( session );
696free_mem:
697 smtp_address_list_free( rcpts );
698 free( data );
699 free( server );
700 if ( smtp->getLogin() ) {
701 free( user );
702 free( pass );
703 }
704 free( from );
705}
706
707void MailWrapper::sendMail( Mail mail )
708{
709 mailmime *mimeMail;
710
711 mimeMail = createMimeMail( &mail );
712 if ( mimeMail == NULL ) {
713 qDebug( "sendMail: error creating mime mail" );
714 } else {
715 smtpSend( mimeMail );
716 mailmime_free( mimeMail );
717 }
718}
719
720Mail::Mail() 135Mail::Mail()
721 :name(""), mail(""), to(""), cc(""), bcc(""), reply(""), subject(""), message("") 136 :name(""), mail(""), to(""), cc(""), bcc(""), reply(""), subject(""), message("")
722{ 137{
723} 138}
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 @@
1#ifndef MAILWRAPPER_H 1#ifndef MAILWRAPPER_H
2#define MAILWRAPPER_H 2#define MAILWRAPPER_H
3 3
4#include <qpe/applnk.h> 4#include <qpe/applnk.h>
5 5
6#include <libetpan/mailmime.h>
7#include <libetpan/mailimf.h>
8#include <libetpan/mailsmtp.h>
9#include <libetpan/mailstorage.h>
10#include <libetpan/maildriver.h>
11#include <qbitarray.h> 6#include <qbitarray.h>
12#include <qdatetime.h> 7#include <qdatetime.h>
13 8
14#include "settings.h" 9#include "settings.h"
15 10
16class Attachment 11class Attachment
17{ 12{
18public: 13public:
19 Attachment( DocLnk lnk ); 14 Attachment( DocLnk lnk );
20 virtual ~Attachment(){} 15 virtual ~Attachment(){}
21 const QString getFileName()const{ return doc.file(); } 16 const QString getFileName()const{ return doc.file(); }
22 const QString getName()const{ return doc.name(); } 17 const QString getName()const{ return doc.name(); }
23 const QString getMimeType()const{ return doc.type(); } 18 const QString getMimeType()const{ return doc.type(); }
24 const QPixmap getPixmap()const{ return doc.pixmap(); } 19 const QPixmap getPixmap()const{ return doc.pixmap(); }
25 const int getSize()const { return size; } 20 const int getSize()const { return size; }
26 DocLnk getDocLnk() { return doc; } 21 DocLnk getDocLnk() { return doc; }
27 22
28protected: 23protected:
29 DocLnk doc; 24 DocLnk doc;
30 int size; 25 int size;
31 26
32}; 27};
33 28
34class Mail 29class Mail
35{ 30{
36public: 31public:
37 Mail(); 32 Mail();
38 /* Possible that this destructor must not be declared virtual 33 /* Possible that this destructor must not be declared virtual
39 * 'cause it seems that it will never have some child classes. 34 * 'cause it seems that it will never have some child classes.
40 * in this case this object will not get a virtual table -> memory and 35 * in this case this object will not get a virtual table -> memory and
41 * speed will be a little bit better? 36 * speed will be a little bit better?
42 */ 37 */
43 virtual ~Mail(){} 38 virtual ~Mail(){}
44 void addAttachment( Attachment *att ) { attList.append( att ); } 39 void addAttachment( Attachment *att ) { attList.append( att ); }
45 const QList<Attachment>& getAttachments()const { return attList; } 40 const QList<Attachment>& getAttachments()const { return attList; }
46 void removeAttachment( Attachment *att ) { attList.remove( att ); } 41 void removeAttachment( Attachment *att ) { attList.remove( att ); }
47 const QString&getName()const { return name; } 42 const QString&getName()const { return name; }
48 void setName( QString s ) { name = s; } 43 void setName( QString s ) { name = s; }
49 const QString&getMail()const{ return mail; } 44 const QString&getMail()const{ return mail; }
50 void setMail( const QString&s ) { mail = s; } 45 void setMail( const QString&s ) { mail = s; }
51 const QString&getTo()const{ return to; } 46 const QString&getTo()const{ return to; }
52 void setTo( const QString&s ) { to = s; } 47 void setTo( const QString&s ) { to = s; }
53 const QString&getCC()const{ return cc; } 48 const QString&getCC()const{ return cc; }
54 void setCC( const QString&s ) { cc = s; } 49 void setCC( const QString&s ) { cc = s; }
55 const QString&getBCC()const { return bcc; } 50 const QString&getBCC()const { return bcc; }
56 void setBCC( const QString&s ) { bcc = s; } 51 void setBCC( const QString&s ) { bcc = s; }
57 const QString&getMessage()const { return message; } 52 const QString&getMessage()const { return message; }
58 void setMessage( const QString&s ) { message = s; } 53 void setMessage( const QString&s ) { message = s; }
59 const QString&getSubject()const { return subject; } 54 const QString&getSubject()const { return subject; }
60 void setSubject( const QString&s ) { subject = s; } 55 void setSubject( const QString&s ) { subject = s; }
61 const QString&getReply()const{ return reply; } 56 const QString&getReply()const{ return reply; }
62 void setReply( const QString&a ) { reply = a; } 57 void setReply( const QString&a ) { reply = a; }
63 58
64private: 59private:
65 QList<Attachment> attList; 60 QList<Attachment> attList;
66 QString name, mail, to, cc, bcc, reply, subject, message; 61 QString name, mail, to, cc, bcc, reply, subject, message;
67}; 62};
68 63
69class Folder : public QObject 64class Folder : public QObject
70{ 65{
71 Q_OBJECT 66 Q_OBJECT
72 67
73public: 68public:
74 Folder( const QString&init_name,const QString&sep ); 69 Folder( const QString&init_name,const QString&sep );
75 const QString&getDisplayName()const { return nameDisplay; } 70 const QString&getDisplayName()const { return nameDisplay; }
76 const QString&getName()const { return name; } 71 const QString&getName()const { return name; }
77 virtual bool may_select()const{return true;}; 72 virtual bool may_select()const{return true;};
78 const QString&Separator()const; 73 const QString&Separator()const;
79 74
80protected: 75protected:
81 QString nameDisplay, name, separator; 76 QString nameDisplay, name, separator;
82 77
83}; 78};
84 79
85class IMAPFolder : public Folder 80class IMAPFolder : public Folder
86{ 81{
87 public: 82 public:
88 IMAPFolder(const QString&name, const QString&sep, bool select=true,const QString&prefix="" ); 83 IMAPFolder(const QString&name, const QString&sep, bool select=true,const QString&prefix="" );
89 virtual bool may_select()const{return m_MaySelect;} 84 virtual bool may_select()const{return m_MaySelect;}
90 private: 85 private:
91 static QString decodeFolderName( const QString &name ); 86 static QString decodeFolderName( const QString &name );
92 bool m_MaySelect; 87 bool m_MaySelect;
93 88
94}; 89};
95 90
96class MailWrapper : public QObject
97{
98 Q_OBJECT
99
100public:
101 MailWrapper( Settings *s );
102 void sendMail( Mail mail );
103
104private:
105 mailimf_mailbox *newMailbox(const QString&name,const QString&mail );
106 mailimf_address_list *parseAddresses(const QString&addr );
107 mailimf_fields *createImfFields( Mail *mail );
108 mailmime *buildTxtPart( QString str );
109 mailmime *buildFilePart( QString filename, QString mimetype );
110 void addFileParts( mailmime *message, QList<Attachment> files );
111 mailmime *createMimeMail( Mail *mail );
112 void smtpSend( mailmime *mail );
113 mailimf_field *getField( mailimf_fields *fields, int type );
114 clist *createRcptList( mailimf_fields *fields );
115 char *getFrom( mailmime *mail );
116 SMTPaccount *getAccount( QString from );
117 void writeToFile( QString file, mailmime *mail );
118 void readFromFile( QString file, char **data, size_t *size );
119 static QString mailsmtpError( int err );
120 static QString getTmpFile();
121
122 Settings *settings;
123
124};
125
126#endif 91#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 @@
1#ifndef __POP3WRAPPER 1#ifndef __POP3WRAPPER
2#define __POP3WRAPPER 2#define __POP3WRAPPER
3 3
4#include <libetpan/clist.h>
4#include "mailwrapper.h" 5#include "mailwrapper.h"
5#include "abstractmail.h" 6#include "abstractmail.h"
6#include <qmap.h> 7#include <qmap.h>
7#include <qstring.h> 8#include <qstring.h>
8 9
9class RecMail; 10class RecMail;
10class RecBody; 11class RecBody;
11class encodedString; 12class encodedString;
12struct mailpop3; 13struct mailpop3;
13struct mailmessage; 14struct mailmessage;
14struct mailmime; 15struct mailmime;
15struct mailmime_mechanism; 16struct mailmime_mechanism;
17struct mailimf_mailbox_list;
18struct mailimf_mailbox;
19struct mailimf_date_time;
20struct mailimf_group;
21struct mailimf_address_list;
16 22
17class POP3wrapper : public AbstractMail 23class POP3wrapper : public AbstractMail
18{ 24{
19 Q_OBJECT 25 Q_OBJECT
20 26
21public: 27public:
22 POP3wrapper( POP3account *a ); 28 POP3wrapper( POP3account *a );
23 virtual ~POP3wrapper(); 29 virtual ~POP3wrapper();
24 /* mailbox will be ignored */ 30 /* mailbox will be ignored */
25 virtual void listMessages(const QString & mailbox, QList<RecMail> &target ); 31 virtual void listMessages(const QString & mailbox, QList<RecMail> &target );
26 virtual QList<Folder>* listFolders(); 32 virtual QList<Folder>* listFolders();
27 virtual QString fetchTextPart(const RecMail&mail,const RecPart&part); 33 virtual QString fetchTextPart(const RecMail&mail,const RecPart&part);
28 virtual encodedString* fetchDecodedPart(const RecMail&mail,const RecPart&part); 34 virtual encodedString* fetchDecodedPart(const RecMail&mail,const RecPart&part);
29 virtual encodedString* fetchRawPart(const RecMail&mail,const RecPart&part); 35 virtual encodedString* fetchRawPart(const RecMail&mail,const RecPart&part);
30 36
31 virtual void deleteMail(const RecMail&mail); 37 virtual void deleteMail(const RecMail&mail);
32 virtual void answeredMail(const RecMail&mail); 38 virtual void answeredMail(const RecMail&mail);
33 39
34 RecBody fetchBody( const RecMail &mail ); 40 RecBody fetchBody( const RecMail &mail );
35 static void pop3_progress( size_t current, size_t maximum ); 41 static void pop3_progress( size_t current, size_t maximum );
36 42
37protected: 43protected:
38 void login(); 44 void login();
39 void logout(); 45 void logout();
40 46
41 RecMail *parseHeader( const char *header ); 47 RecMail *parseHeader( const char *header );
42 RecBody parseMail( char *message ); 48 RecBody parseMail( char *message );
43 QString parseMailboxList( mailimf_mailbox_list *list ); 49 QString parseMailboxList( mailimf_mailbox_list *list );
44 QString parseMailbox( mailimf_mailbox *box ); 50 QString parseMailbox( mailimf_mailbox *box );
45 QString parseGroup( mailimf_group *group ); 51 QString parseGroup( mailimf_group *group );
46 QString parseAddressList( mailimf_address_list *list ); 52 QString parseAddressList( mailimf_address_list *list );
47 QString parseDateTime( mailimf_date_time *date ); 53 QString parseDateTime( mailimf_date_time *date );
48 54
49 void cleanUpCache(); 55 void cleanUpCache();
50 56
51 void traverseBody(RecBody&target,mailmessage*message,mailmime*mime,unsigned int current_rek=0); 57 void traverseBody(RecBody&target,mailmessage*message,mailmime*mime,unsigned int current_rek=0);
52 static void fillSingleBody(RecPart&target,mailmessage*message,mailmime*mime); 58 static void fillSingleBody(RecPart&target,mailmessage*message,mailmime*mime);
53 static void fillParameters(RecPart&target,clist*parameters); 59 static void fillParameters(RecPart&target,clist*parameters);
54 static QString POP3wrapper::getencoding(mailmime_mechanism*aEnc); 60 static QString POP3wrapper::getencoding(mailmime_mechanism*aEnc);
55 61
56 POP3account *account; 62 POP3account *account;
57 mailpop3 *m_pop3; 63 mailpop3 *m_pop3;
58 QString msgTempName; 64 QString msgTempName;
59 unsigned int last_msg_id; 65 unsigned int last_msg_id;
60 QMap<QString,encodedString*> bodyCache; 66 QMap<QString,encodedString*> bodyCache;
61}; 67};
62 68
63#endif 69#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 @@
1#include <stdlib.h>
2#include <sys/stat.h>
3#include <sys/types.h>
4#include <unistd.h>
5#include <fcntl.h>
6#include <string.h>
7#include <qdir.h>
8
9#include <libetpan/mailmime.h>
10#include <libetpan/mailimf.h>
11#include <libetpan/mailsmtp.h>
12#include <libetpan/mailstorage.h>
13#include <libetpan/maildriver.h>
14
15#include "smtpwrapper.h"
16#include "mailwrapper.h"
17#include "logindialog.h"
18#include "defines.h"
19
20SMTPwrapper::SMTPwrapper( Settings *s )
21 : QObject()
22{
23 settings = s;
24}
25
26QString SMTPwrapper::mailsmtpError( int errnum )
27{
28 switch ( errnum ) {
29 case MAILSMTP_NO_ERROR:
30 return tr( "No error" );
31 case MAILSMTP_ERROR_UNEXPECTED_CODE:
32 return tr( "Unexpected error code" );
33 case MAILSMTP_ERROR_SERVICE_NOT_AVAILABLE:
34 return tr( "Service not available" );
35 case MAILSMTP_ERROR_STREAM:
36 return tr( "Stream error" );
37 case MAILSMTP_ERROR_HOSTNAME:
38 return tr( "gethostname() failed" );
39 case MAILSMTP_ERROR_NOT_IMPLEMENTED:
40 return tr( "Not implemented" );
41 case MAILSMTP_ERROR_ACTION_NOT_TAKEN:
42 return tr( "Error, action not taken" );
43 case MAILSMTP_ERROR_EXCEED_STORAGE_ALLOCATION:
44 return tr( "Data exceeds storage allocation" );
45 case MAILSMTP_ERROR_IN_PROCESSING:
46 return tr( "Error in processing" );
47 // case MAILSMTP_ERROR_INSUFFISANT_SYSTEM_STORAGE:
48 // return tr( "Insufficient system storage" );
49 case MAILSMTP_ERROR_MAILBOX_UNAVAILABLE:
50 return tr( "Mailbox unavailable" );
51 case MAILSMTP_ERROR_MAILBOX_NAME_NOT_ALLOWED:
52 return tr( "Mailbox name not allowed" );
53 case MAILSMTP_ERROR_BAD_SEQUENCE_OF_COMMAND:
54 return tr( "Bad command sequence" );
55 case MAILSMTP_ERROR_USER_NOT_LOCAL:
56 return tr( "User not local" );
57 case MAILSMTP_ERROR_TRANSACTION_FAILED:
58 return tr( "Transaction failed" );
59 case MAILSMTP_ERROR_MEMORY:
60 return tr( "Memory error" );
61 case MAILSMTP_ERROR_CONNECTION_REFUSED:
62 return tr( "Connection refused" );
63 default:
64 return tr( "Unknown error code" );
65 }
66}
67
68mailimf_mailbox *SMTPwrapper::newMailbox(const QString&name, const QString&mail )
69{
70 return mailimf_mailbox_new( strdup( name.latin1() ),
71 strdup( mail.latin1() ) );
72}
73
74mailimf_address_list *SMTPwrapper::parseAddresses(const QString&addr )
75{
76 mailimf_address_list *addresses;
77
78 if ( addr.isEmpty() ) return NULL;
79
80 addresses = mailimf_address_list_new_empty();
81
82 QStringList list = QStringList::split( ',', addr );
83 QStringList::Iterator it;
84 for ( it = list.begin(); it != list.end(); it++ ) {
85 char *str = strdup( (*it).latin1() );
86 int err = mailimf_address_list_add_parse( addresses, str );
87 if ( err != MAILIMF_NO_ERROR ) {
88 qDebug( "Error parsing" );
89 qDebug( *it );
90 free( str );
91 } else {
92 qDebug( "Parse success! :)" );
93 }
94 }
95
96 return addresses;
97}
98
99mailimf_fields *SMTPwrapper::createImfFields(const Mail&mail )
100{
101 mailimf_fields *fields;
102 mailimf_field *xmailer;
103 mailimf_mailbox *sender, *fromBox;
104 mailimf_mailbox_list *from;
105 mailimf_address_list *to, *cc, *bcc, *reply;
106 char *subject = strdup( mail.getSubject().latin1() );
107 int err;
108
109 sender = newMailbox( mail.getName(), mail.getMail() );
110 if ( sender == NULL ) goto err_free;
111
112 fromBox = newMailbox( mail.getName(), mail.getMail() );
113 if ( fromBox == NULL ) goto err_free_sender;
114
115 from = mailimf_mailbox_list_new_empty();
116 if ( from == NULL ) goto err_free_fromBox;
117
118 err = mailimf_mailbox_list_add( from, fromBox );
119 if ( err != MAILIMF_NO_ERROR ) goto err_free_from;
120
121 to = parseAddresses( mail.getTo() );
122 if ( to == NULL ) goto err_free_from;
123
124 cc = parseAddresses( mail.getCC() );
125 bcc = parseAddresses( mail.getBCC() );
126 reply = parseAddresses( mail.getReply() );
127
128 fields = mailimf_fields_new_with_data( from, sender, reply, to, cc, bcc,
129 NULL, NULL, subject );
130 if ( fields == NULL ) goto err_free_reply;
131
132 xmailer = mailimf_field_new_custom( strdup( "User-Agent" ),
133 strdup( USER_AGENT ) );
134 if ( xmailer == NULL ) goto err_free_fields;
135
136 err = mailimf_fields_add( fields, xmailer );
137 if ( err != MAILIMF_NO_ERROR ) goto err_free_xmailer;
138
139 return fields; // Success :)
140
141err_free_xmailer:
142 mailimf_field_free( xmailer );
143err_free_fields:
144 mailimf_fields_free( fields );
145err_free_reply:
146 mailimf_address_list_free( reply );
147 mailimf_address_list_free( bcc );
148 mailimf_address_list_free( cc );
149 mailimf_address_list_free( to );
150err_free_from:
151 mailimf_mailbox_list_free( from );
152err_free_fromBox:
153 mailimf_mailbox_free( fromBox );
154err_free_sender:
155 mailimf_mailbox_free( sender );
156err_free:
157 free( subject );
158 qDebug( "createImfFields - error" );
159
160 return NULL; // Error :(
161}
162
163mailmime *SMTPwrapper::buildTxtPart(const QString&str )
164{
165 mailmime *txtPart;
166 mailmime_fields *fields;
167 mailmime_content *content;
168 mailmime_parameter *param;
169 char *txt = strdup( str.latin1() );
170 int err;
171
172 param = mailmime_parameter_new( strdup( "charset" ),
173 strdup( "iso-8859-1" ) );
174 if ( param == NULL ) goto err_free;
175
176 content = mailmime_content_new_with_str( "text/plain" );
177 if ( content == NULL ) goto err_free_param;
178
179 err = clist_append( content->ct_parameters, param );
180 if ( err != MAILIMF_NO_ERROR ) goto err_free_content;
181
182 fields = mailmime_fields_new_encoding( MAILMIME_MECHANISM_8BIT );
183 if ( fields == NULL ) goto err_free_content;
184
185 txtPart = mailmime_new_empty( content, fields );
186 if ( txtPart == NULL ) goto err_free_fields;
187
188 err = mailmime_set_body_text( txtPart, txt, strlen( txt ) );
189 if ( err != MAILIMF_NO_ERROR ) goto err_free_txtPart;
190
191 return txtPart; // Success :)
192
193err_free_txtPart:
194 mailmime_free( txtPart );
195err_free_fields:
196 mailmime_fields_free( fields );
197err_free_content:
198 mailmime_content_free( content );
199err_free_param:
200 mailmime_parameter_free( param );
201err_free:
202 free( txt );
203 qDebug( "buildTxtPart - error" );
204
205 return NULL; // Error :(
206}
207
208mailmime *SMTPwrapper::buildFilePart(const QString&filename,const QString&mimetype )
209{
210 mailmime * filePart;
211 mailmime_fields * fields;
212 mailmime_content * content;
213 mailmime_parameter * param = NULL;
214 int err;
215
216 int pos = filename.findRev( '/' );
217 QString tmp = filename.right( filename.length() - ( pos + 1 ) );
218 char *name = strdup( tmp.latin1() ); // just filename
219 char *file = strdup( filename.latin1() ); // full name with path
220 char *mime = strdup( mimetype.latin1() ); // mimetype -e.g. text/plain
221
222 fields = mailmime_fields_new_filename(
223 MAILMIME_DISPOSITION_TYPE_ATTACHMENT, name,
224 MAILMIME_MECHANISM_BASE64 );
225 if ( fields == NULL ) goto err_free;
226
227 content = mailmime_content_new_with_str( mime );
228 if ( content == NULL ) goto err_free_fields;
229
230 if ( mimetype.compare( "text/plain" ) == 0 ) {
231 param = mailmime_parameter_new( strdup( "charset" ),
232 strdup( "iso-8859-1" ) );
233 if ( param == NULL ) goto err_free_content;
234
235 err = clist_append( content->ct_parameters, param );
236 if ( err != MAILIMF_NO_ERROR ) goto err_free_param;
237 }
238
239 filePart = mailmime_new_empty( content, fields );
240 if ( filePart == NULL ) goto err_free_param;
241
242 err = mailmime_set_body_file( filePart, file );
243 if ( err != MAILIMF_NO_ERROR ) goto err_free_filePart;
244
245 return filePart; // Success :)
246
247err_free_filePart:
248 mailmime_free( filePart );
249err_free_param:
250 if ( param != NULL ) mailmime_parameter_free( param );
251err_free_content:
252 mailmime_content_free( content );
253err_free_fields:
254 mailmime_fields_free( fields );
255err_free:
256 free( name );
257 free( mime );
258 free( file );
259 qDebug( "buildFilePart - error" );
260
261 return NULL; // Error :(
262}
263
264void SMTPwrapper::addFileParts( mailmime *message,const QList<Attachment>&files )
265{
266 const Attachment *it;
267 /* work around for the brainfucked qlist which can not act with const values */
268 for ( it = ((QList<Attachment>)files).first(); it; it = ((QList<Attachment>)files).next() ) {
269 qDebug( "Adding file" );
270 mailmime *filePart;
271 int err;
272
273 filePart = buildFilePart( it->getFileName(), it->getMimeType() );
274 if ( filePart == NULL ) goto err_free;
275
276 err = mailmime_smart_add_part( message, filePart );
277 if ( err != MAILIMF_NO_ERROR ) goto err_free_filePart;
278
279 continue; // Success :)
280
281 err_free_filePart:
282 mailmime_free( filePart );
283 err_free:
284 qDebug( "addFileParts: error adding file:" );
285 qDebug( it->getFileName() );
286 }
287}
288
289mailmime *SMTPwrapper::createMimeMail(const Mail &mail )
290{
291 mailmime *message, *txtPart;
292 mailimf_fields *fields;
293 int err;
294
295 fields = createImfFields( mail );
296 if ( fields == NULL ) goto err_free;
297
298 message = mailmime_new_message_data( NULL );
299 if ( message == NULL ) goto err_free_fields;
300
301 mailmime_set_imf_fields( message, fields );
302
303 txtPart = buildTxtPart( mail.getMessage() );
304 if ( txtPart == NULL ) goto err_free_message;
305
306 err = mailmime_smart_add_part( message, txtPart );
307 if ( err != MAILIMF_NO_ERROR ) goto err_free_txtPart;
308
309 addFileParts( message, mail.getAttachments() );
310
311 return message; // Success :)
312
313err_free_txtPart:
314 mailmime_free( txtPart );
315err_free_message:
316 mailmime_free( message );
317err_free_fields:
318 mailimf_fields_free( fields );
319err_free:
320 qDebug( "createMimeMail: error" );
321
322 return NULL; // Error :(
323}
324
325mailimf_field *SMTPwrapper::getField( mailimf_fields *fields, int type )
326{
327 mailimf_field *field;
328 clistiter *it;
329
330 it = clist_begin( fields->fld_list );
331 while ( it ) {
332 field = (mailimf_field *) it->data;
333 if ( field->fld_type == type ) {
334 return field;
335 }
336 it = it->next;
337 }
338
339 return NULL;
340}
341
342void SMTPwrapper::addRcpts( clist *list, mailimf_address_list *addr_list )
343{
344 clistiter *it, *it2;
345
346 for ( it = clist_begin( addr_list->ad_list ); it; it = it->next ) {
347 mailimf_address *addr;
348 addr = (mailimf_address *) it->data;
349
350 if ( addr->ad_type == MAILIMF_ADDRESS_MAILBOX ) {
351 esmtp_address_list_add( list, addr->ad_data.ad_mailbox->mb_addr_spec, 0, NULL );
352 } else if ( addr->ad_type == MAILIMF_ADDRESS_GROUP ) {
353 clist *l = addr->ad_data.ad_group->grp_mb_list->mb_list;
354 for ( it2 = clist_begin( l ); it2; it2 = it2->next ) {
355 mailimf_mailbox *mbox;
356 mbox = (mailimf_mailbox *) it2->data;
357 esmtp_address_list_add( list, mbox->mb_addr_spec, 0, NULL );
358 }
359 }
360 }
361}
362
363clist *SMTPwrapper::createRcptList( mailimf_fields *fields )
364{
365 clist *rcptList;
366 mailimf_field *field;
367
368 rcptList = esmtp_address_list_new();
369
370 field = getField( fields, MAILIMF_FIELD_TO );
371 if ( field && (field->fld_type == MAILIMF_FIELD_TO)
372 && field->fld_data.fld_to->to_addr_list ) {
373 addRcpts( rcptList, field->fld_data.fld_to->to_addr_list );
374 }
375
376 field = getField( fields, MAILIMF_FIELD_CC );
377 if ( field && (field->fld_type == MAILIMF_FIELD_CC)
378 && field->fld_data.fld_cc->cc_addr_list ) {
379 addRcpts( rcptList, field->fld_data.fld_cc->cc_addr_list );
380 }
381
382 field = getField( fields, MAILIMF_FIELD_BCC );
383 if ( field && (field->fld_type == MAILIMF_FIELD_BCC)
384 && field->fld_data.fld_bcc->bcc_addr_list ) {
385 addRcpts( rcptList, field->fld_data.fld_bcc->bcc_addr_list );
386 }
387
388 return rcptList;
389}
390
391char *SMTPwrapper::getFrom( mailmime *mail )
392{
393 char *from = NULL;
394
395 mailimf_field *ffrom;
396 ffrom = getField( mail->mm_data.mm_message.mm_fields, MAILIMF_FIELD_FROM );
397 if ( ffrom && (ffrom->fld_type == MAILIMF_FIELD_FROM)
398 && ffrom->fld_data.fld_from->frm_mb_list && ffrom->fld_data.fld_from->frm_mb_list->mb_list ) {
399 clist *cl = ffrom->fld_data.fld_from->frm_mb_list->mb_list;
400 clistiter *it;
401 for ( it = clist_begin( cl ); it; it = it->next ) {
402 mailimf_mailbox *mb = (mailimf_mailbox *) it->data;
403 from = strdup( mb->mb_addr_spec );
404 }
405 }
406
407 return from;
408}
409
410SMTPaccount *SMTPwrapper::getAccount(const QString&from )
411{
412 SMTPaccount *smtp;
413
414 QList<Account> list = settings->getAccounts();
415 Account *it;
416 for ( it = list.first(); it; it = list.next() ) {
417 if ( it->getType().compare( "SMTP" ) == 0 ) {
418 smtp = static_cast<SMTPaccount *>(it);
419 if ( smtp->getMail().compare( from ) == 0 ) {
420 qDebug( "SMTPaccount found for" );
421 qDebug( from );
422 return smtp;
423 }
424 }
425 }
426
427 return NULL;
428}
429
430QString SMTPwrapper::getTmpFile() {
431 int num = 0;
432 QString unique;
433
434 QDir dir( "/tmp" );
435 QStringList::Iterator it;
436
437 QStringList list = dir.entryList( "opiemail-tmp-*" );
438 do {
439 unique.setNum( num++ );
440 } while ( list.contains( "opiemail-tmp-" + unique ) > 0 );
441
442 return "/tmp/opiemail-tmp-" + unique;
443}
444
445void SMTPwrapper::writeToFile(const QString&file, mailmime *mail )
446{
447 FILE *f;
448 int err, col = 0;
449
450 f = fopen( file.latin1(), "w" );
451 if ( f == NULL ) {
452 qDebug( "writeToFile: error opening file" );
453 return;
454 }
455
456 err = mailmime_write( f, &col, mail );
457 if ( err != MAILIMF_NO_ERROR ) {
458 fclose( f );
459 qDebug( "writeToFile: error writing mailmime" );
460 return;
461 }
462
463 fclose( f );
464}
465
466void SMTPwrapper::readFromFile(const QString&file, char **data, size_t *size )
467{
468 char *buf;
469 struct stat st;
470 int fd, count = 0, total = 0;
471
472 fd = open( file.latin1(), O_RDONLY, 0 );
473 if ( fd == -1 ) return;
474
475 if ( fstat( fd, &st ) != 0 ) goto err_close;
476 if ( !st.st_size ) goto err_close;
477
478 buf = (char *) malloc( st.st_size );
479 if ( !buf ) goto err_close;
480
481 while ( ( total < st.st_size ) && ( count >= 0 ) ) {
482 count = read( fd, buf + total, st.st_size - total );
483 total += count;
484 }
485 if ( count < 0 ) goto err_free;
486
487 *data = buf;
488 *size = st.st_size;
489
490 close( fd );
491
492 return; // Success :)
493
494err_free:
495 free( buf );
496err_close:
497 close( fd );
498}
499
500void SMTPwrapper::progress( size_t current, size_t maximum )
501{
502 qDebug( "Current: %i of %i", current, maximum );
503}
504
505void SMTPwrapper::smtpSend( mailmime *mail )
506{
507 mailsmtp *session;
508 clist *rcpts;
509 char *from, *data, *server, *user = NULL, *pass = NULL;
510 size_t size;
511 int err;
512 bool ssl;
513 uint16_t port;
514
515
516 from = getFrom( mail );
517 SMTPaccount *smtp = getAccount( from );
518 if ( smtp == NULL ) {
519 free(from);
520 return;
521 }
522 server = strdup( smtp->getServer().latin1() );
523 ssl = smtp->getSSL();
524 port = smtp->getPort().toUInt();
525 rcpts = createRcptList( mail->mm_data.mm_message.mm_fields );
526
527 QString file = getTmpFile();
528 writeToFile( file, mail );
529 readFromFile( file, &data, &size );
530 QFile f( file );
531 f.remove();
532
533 session = mailsmtp_new( 20, &progress );
534 if ( session == NULL ) goto free_mem;
535
536 qDebug( "Servername %s at port %i", server, port );
537 if ( ssl ) {
538 qDebug( "SSL session" );
539 err = mailsmtp_ssl_connect( session, server, port );
540 } else {
541 qDebug( "No SSL session" );
542 err = mailsmtp_socket_connect( session, server, port );
543 }
544 if ( err != MAILSMTP_NO_ERROR ) goto free_mem_session;
545
546 err = mailsmtp_init( session );
547 if ( err != MAILSMTP_NO_ERROR ) goto free_con_session;
548
549 qDebug( "INIT OK" );
550
551 if ( smtp->getLogin() ) {
552 if ( smtp->getUser().isEmpty() || smtp->getPassword().isEmpty() ) {
553 // get'em
554 LoginDialog login( smtp->getUser(), smtp->getPassword(), NULL, 0, true );
555 login.show();
556 if ( QDialog::Accepted == login.exec() ) {
557 // ok
558 user = strdup( login.getUser().latin1() );
559 pass = strdup( login.getPassword().latin1() );
560 } else {
561 goto free_con_session;
562 }
563 } else {
564 user = strdup( smtp->getUser().latin1() );
565 pass = strdup( smtp->getPassword().latin1() );
566 }
567 qDebug( "session->auth: %i", session->auth);
568 err = mailsmtp_auth( session, user, pass );
569 if ( err == MAILSMTP_NO_ERROR ) qDebug("auth ok");
570 qDebug( "Done auth!" );
571 }
572
573 err = mailsmtp_send( session, from, rcpts, data, size );
574 if ( err != MAILSMTP_NO_ERROR ) goto free_con_session;
575
576 qDebug( "Mail sent." );
577
578free_con_session:
579 mailsmtp_quit( session );
580free_mem_session:
581 mailsmtp_free( session );
582free_mem:
583 smtp_address_list_free( rcpts );
584 free( data );
585 free( server );
586 if ( smtp->getLogin() ) {
587 free( user );
588 free( pass );
589 }
590 free( from );
591}
592
593void SMTPwrapper::sendMail(const Mail&mail )
594{
595 mailmime *mimeMail;
596
597 mimeMail = createMimeMail(mail );
598 if ( mimeMail == NULL ) {
599 qDebug( "sendMail: error creating mime mail" );
600 } else {
601 smtpSend( mimeMail );
602 mailmime_free( mimeMail );
603 }
604}
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 @@
1#ifndef SMTPwrapper_H
2#define SMTPwrapper_H
3
4#include <qpe/applnk.h>
5
6#include <qbitarray.h>
7#include <qdatetime.h>
8#include <libetpan/clist.h>
9
10#include "settings.h"
11
12class Mail;
13class Attachment;
14struct mailimf_fields;
15struct mailimf_field;
16struct mailimf_mailbox;
17struct mailmime;
18struct mailimf_address_list;
19
20class SMTPwrapper : public QObject
21{
22 Q_OBJECT
23
24public:
25 SMTPwrapper( Settings *s );
26 virtual ~SMTPwrapper(){}
27 void sendMail(const Mail& mail );
28
29protected:
30 mailimf_mailbox *newMailbox(const QString&name,const QString&mail );
31 mailimf_fields *createImfFields(const Mail &mail );
32 mailmime *createMimeMail(const Mail&mail );
33
34 mailimf_address_list *parseAddresses(const QString&addr );
35 void addFileParts( mailmime *message,const QList<Attachment>&files );
36 mailmime *buildTxtPart(const QString&str );
37 mailmime *buildFilePart(const QString&filename,const QString&mimetype );
38 void smtpSend( mailmime *mail );
39 mailimf_field *getField( mailimf_fields *fields, int type );
40 clist *createRcptList( mailimf_fields *fields );
41 char *getFrom( mailmime *mail );
42 SMTPaccount *getAccount(const QString&from );
43 void writeToFile(const QString&file, mailmime *mail );
44 void readFromFile(const QString&file, char **data, size_t *size );
45
46 static QString mailsmtpError( int err );
47 static QString getTmpFile();
48 static void progress( size_t current, size_t maximum );
49 static void addRcpts( clist *list, mailimf_address_list *addr_list );
50 Settings *settings;
51};
52
53#endif