summaryrefslogtreecommitdiff
authorjgf <jgf>2003-12-18 02:43:07 (UTC)
committer jgf <jgf>2003-12-18 02:43:07 (UTC)
commitd7fed5a555f51008db8b96e8b978c3830c59be77 (patch) (side-by-side diff)
tree9f3a8aa82909ef80cf1c42431abc20d3ac585436
parent77e353da0c33bbfabf1b919e25008d62581bf164 (diff)
downloadopie-d7fed5a555f51008db8b96e8b978c3830c59be77.zip
opie-d7fed5a555f51008db8b96e8b978c3830c59be77.tar.gz
opie-d7fed5a555f51008db8b96e8b978c3830c59be77.tar.bz2
decoding of imap folder names
Diffstat (more/less context) (show whitespace changes)
-rw-r--r--noncore/net/mail/defines.h11
-rw-r--r--noncore/net/mail/libmailwrapper/mailwrapper.cpp107
-rw-r--r--noncore/net/mail/libmailwrapper/mailwrapper.h2
-rw-r--r--noncore/net/mail/mailwrapper.cpp107
-rw-r--r--noncore/net/mail/mailwrapper.h2
5 files changed, 201 insertions, 28 deletions
diff --git a/noncore/net/mail/defines.h b/noncore/net/mail/defines.h
index 9036658..d9cdab0 100644
--- a/noncore/net/mail/defines.h
+++ b/noncore/net/mail/defines.h
@@ -8,33 +8,44 @@
#define PIC_COMPOSEMAIL "mail/composemail"
#define PIC_SENDQUEUED "mail/sendqueued"
#define PIC_SHOWFOLDERS "mail/showfolders"
#define PIC_SEARCHMAILS "mail/searchmails"
#define PIC_EDITSETTINGS "mail/editsettings"
#define PIC_EDITACCOUNTS "mail/editaccounts"
#define PIC_SYNC "mail/sync"
#define PIC_IMAPFOLDER "mail/imapfolder"
#define PIC_POP3FOLDER "mail/pop3folder"
#define PIC_INBOXFOLDER "mail/inbox"
#define ICON_COMPOSEMAIL QIconSet( Resource::loadPixmap( PIC_COMPOSEMAIL ) )
#define ICON_SENDQUEUED QIconSet( Resource::loadPixmap( PIC_SENDQUEUED ) )
#define ICON_SHOWFOLDERS QIconSet( Resource::loadPixmap( PIC_SHOWFOLDERS ) )
#define ICON_SEARCHMAILS QIconSet( Resource::loadPixmap( PIC_SEARCHMAILS ) )
#define ICON_EDITSETTINGS QIconSet( Resource::loadPixmap( PIC_EDITSETTINGS ) )
#define ICON_EDITACCOUNTS QIconSet( Resource::loadPixmap( PIC_EDITACCOUNTS ) )
#define ICON_SYNC QIconSet( Resource::loadPixmap( PIC_SYNC ) )
#define PIXMAP_IMAPFOLDER QPixmap( Resource::loadPixmap( PIC_IMAPFOLDER ) )
#define PIXMAP_POP3FOLDER QPixmap( Resource::loadPixmap( PIC_POP3FOLDER ) )
#define PIXMAP_INBOXFOLDER QPixmap( Resource::loadPixmap( PIC_INBOXFOLDER) )
#define IMAP_PORT "143"
#define IMAP_SSL_PORT "993"
#define SMTP_PORT "25"
#define SMTP_SSL_PORT "465"
#define POP3_PORT "110"
#define POP3_SSL_PORT "995"
#define NNTP_PORT "119"
#define NNTP_SSL_PORT "563"
+/* used for decoding imapfoldername */
+#define UNDEFINED 64
+#define MAXLINE 76
+#define UTF16MASK 0x03FFUL
+#define UTF16SHIFT 10
+#define UTF16BASE 0x10000UL
+#define UTF16HIGHSTART 0xD800UL
+#define UTF16HIGHEND 0xDBFFUL
+#define UTF16LOSTART 0xDC00UL
+#define UTF16LOEND 0xDFFFUL
+
#endif
diff --git a/noncore/net/mail/libmailwrapper/mailwrapper.cpp b/noncore/net/mail/libmailwrapper/mailwrapper.cpp
index 858283f..75c06f9 100644
--- a/noncore/net/mail/libmailwrapper/mailwrapper.cpp
+++ b/noncore/net/mail/libmailwrapper/mailwrapper.cpp
@@ -1,87 +1,166 @@
#include <stdlib.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>
#include <fcntl.h>
#include <string.h>
#include <qdir.h>
#include "mailwrapper.h"
#include "logindialog.h"
//#include "mail.h"
#include "defines.h"
Attachment::Attachment( DocLnk lnk )
{
doc = lnk;
size = QFileInfo( doc.file() ).size();
}
Folder::Folder(const QString&tmp_name, const QString&sep )
{
name = tmp_name;
nameDisplay = name;
-
- for ( int pos = nameDisplay.find( '&' ); pos != -1;
- pos = nameDisplay.find( '&' ) ) {
- int end = nameDisplay.find( '-' );
- if ( end == -1 || end <= pos ) break;
- QString str64 = nameDisplay.mid( pos + 1, end - pos - 1 );
- // TODO: do real base64 decoding here !
- if ( str64.compare( "APw" ) == 0 ) {
- nameDisplay = nameDisplay.replace( pos, end - pos + 1, "ue" );
- } else if ( str64.compare( "APY" ) == 0 ) {
- nameDisplay = nameDisplay.replace( pos, end - pos + 1, "oe" );
- }
- }
- qDebug( "folder " + name + " - displayed as " + nameDisplay );
separator = sep;
}
const QString& Folder::Separator()const
{
return separator;
}
IMAPFolder::IMAPFolder(const QString&name,const QString&sep, bool select,const QString&prefix )
: Folder( name,sep ),m_MaySelect(select)
{
+ // Decode IMAP foldername
+ nameDisplay = IMAPFolder::decodeFolderName( name );
+ qDebug( "folder " + name + " - displayed as " + nameDisplay );
+
if (prefix.length()>0) {
if (nameDisplay.startsWith(prefix) && nameDisplay.length()>prefix.length()) {
nameDisplay=nameDisplay.right(nameDisplay.length()-prefix.length());
}
}
}
+static unsigned char base64chars[] =
+ "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+,";
+
+/**
+ * Decodes base64 encoded parts of the imapfolder name
+ * Code taken from kde cvs: kdebase/kioslave/imap4/rfcdecoder.cc
+ */
+QString IMAPFolder::decodeFolderName( const QString &name )
+{
+ unsigned char c, i, bitcount;
+ unsigned long ucs4, utf16, bitbuf;
+ unsigned char base64[256], utf8[6];
+ unsigned long srcPtr = 0;
+ QCString dst;
+ QCString src = name.ascii();
+
+ /* initialize modified base64 decoding table */
+ memset(base64, UNDEFINED, sizeof(base64));
+ for (i = 0; i < sizeof(base64chars); ++i) {
+ base64[(int)base64chars[i]] = i;
+ }
+
+ /* loop until end of string */
+ while (srcPtr < src.length ()) {
+ c = src[srcPtr++];
+ /* deal with literal characters and &- */
+ if (c != '&' || src[srcPtr] == '-') {
+ /* encode literally */
+ dst += c;
+ /* skip over the '-' if this is an &- sequence */
+ if (c == '&')
+ srcPtr++;
+ } else {
+ /* convert modified UTF-7 -> UTF-16 -> UCS-4 -> UTF-8 -> HEX */
+ bitbuf = 0;
+ bitcount = 0;
+ ucs4 = 0;
+ while ((c = base64[(unsigned char) src[srcPtr]]) != UNDEFINED) {
+ ++srcPtr;
+ bitbuf = (bitbuf << 6) | c;
+ bitcount += 6;
+ /* enough bits for a UTF-16 character? */
+ if (bitcount >= 16) {
+ bitcount -= 16;
+ utf16 = (bitcount ? bitbuf >> bitcount : bitbuf) & 0xffff;
+ /* convert UTF16 to UCS4 */
+ if (utf16 >= UTF16HIGHSTART && utf16 <= UTF16HIGHEND) {
+ ucs4 = (utf16 - UTF16HIGHSTART) << UTF16SHIFT;
+ continue;
+ } else if (utf16 >= UTF16LOSTART && utf16 <= UTF16LOEND) {
+ ucs4 += utf16 - UTF16LOSTART + UTF16BASE;
+ } else {
+ ucs4 = utf16;
+ }
+ /* convert UTF-16 range of UCS4 to UTF-8 */
+ if (ucs4 <= 0x7fUL) {
+ utf8[0] = ucs4;
+ i = 1;
+ } else if (ucs4 <= 0x7ffUL) {
+ utf8[0] = 0xc0 | (ucs4 >> 6);
+ utf8[1] = 0x80 | (ucs4 & 0x3f);
+ i = 2;
+ } else if (ucs4 <= 0xffffUL) {
+ utf8[0] = 0xe0 | (ucs4 >> 12);
+ utf8[1] = 0x80 | ((ucs4 >> 6) & 0x3f);
+ utf8[2] = 0x80 | (ucs4 & 0x3f);
+ i = 3;
+ } else {
+ utf8[0] = 0xf0 | (ucs4 >> 18);
+ utf8[1] = 0x80 | ((ucs4 >> 12) & 0x3f);
+ utf8[2] = 0x80 | ((ucs4 >> 6) & 0x3f);
+ utf8[3] = 0x80 | (ucs4 & 0x3f);
+ i = 4;
+ }
+ /* copy it */
+ for (c = 0; c < i; ++c) {
+ dst += utf8[c];
+ }
+ }
+ }
+ /* skip over trailing '-' in modified UTF-7 encoding */
+ if (src[srcPtr] == '-')
+ ++srcPtr;
+ }
+ }
+
+ return QString::fromUtf8( dst.data() );
+}
+
MailWrapper::MailWrapper( Settings *s )
: QObject()
{
settings = s;
}
QString MailWrapper::mailsmtpError( int errnum )
{
switch ( errnum ) {
case MAILSMTP_NO_ERROR:
return tr( "No error" );
case MAILSMTP_ERROR_UNEXPECTED_CODE:
return tr( "Unexpected error code" );
case MAILSMTP_ERROR_SERVICE_NOT_AVAILABLE:
return tr( "Service not available" );
case MAILSMTP_ERROR_STREAM:
return tr( "Stream error" );
case MAILSMTP_ERROR_HOSTNAME:
return tr( "gethostname() failed" );
case MAILSMTP_ERROR_NOT_IMPLEMENTED:
return tr( "Not implemented" );
case MAILSMTP_ERROR_ACTION_NOT_TAKEN:
return tr( "Error, action not taken" );
case MAILSMTP_ERROR_EXCEED_STORAGE_ALLOCATION:
return tr( "Data exceeds storage allocation" );
case MAILSMTP_ERROR_IN_PROCESSING:
return tr( "Error in processing" );
// case MAILSMTP_ERROR_INSUFFISANT_SYSTEM_STORAGE:
// return tr( "Insufficient system storage" );
case MAILSMTP_ERROR_MAILBOX_UNAVAILABLE:
return tr( "Mailbox unavailable" );
case MAILSMTP_ERROR_MAILBOX_NAME_NOT_ALLOWED:
diff --git a/noncore/net/mail/libmailwrapper/mailwrapper.h b/noncore/net/mail/libmailwrapper/mailwrapper.h
index d78f8e9..02fe4b7 100644
--- a/noncore/net/mail/libmailwrapper/mailwrapper.h
+++ b/noncore/net/mail/libmailwrapper/mailwrapper.h
@@ -59,65 +59,67 @@ public:
const QString&getSubject()const { return subject; }
void setSubject( const QString&s ) { subject = s; }
const QString&getReply()const{ return reply; }
void setReply( const QString&a ) { reply = a; }
private:
QList<Attachment> attList;
QString name, mail, to, cc, bcc, reply, subject, message;
};
class Folder : public QObject
{
Q_OBJECT
public:
Folder( const QString&init_name,const QString&sep );
const QString&getDisplayName()const { return nameDisplay; }
const QString&getName()const { return name; }
virtual bool may_select()const{return true;};
const QString&Separator()const;
protected:
QString nameDisplay, name, separator;
};
class IMAPFolder : public Folder
{
public:
IMAPFolder(const QString&name, const QString&sep, bool select=true,const QString&prefix="" );
virtual bool may_select()const{return m_MaySelect;}
private:
+ static QString decodeFolderName( const QString &name );
bool m_MaySelect;
+
};
class MailWrapper : public QObject
{
Q_OBJECT
public:
MailWrapper( Settings *s );
void sendMail( Mail mail );
private:
mailimf_mailbox *newMailbox(const QString&name,const QString&mail );
mailimf_address_list *parseAddresses(const QString&addr );
mailimf_fields *createImfFields( Mail *mail );
mailmime *buildTxtPart( QString str );
mailmime *buildFilePart( QString filename, QString mimetype );
void addFileParts( mailmime *message, QList<Attachment> files );
mailmime *createMimeMail( Mail *mail );
void smtpSend( mailmime *mail );
mailimf_field *getField( mailimf_fields *fields, int type );
clist *createRcptList( mailimf_fields *fields );
char *getFrom( mailmime *mail );
SMTPaccount *getAccount( QString from );
void writeToFile( QString file, mailmime *mail );
void readFromFile( QString file, char **data, size_t *size );
static QString mailsmtpError( int err );
static QString getTmpFile();
Settings *settings;
};
diff --git a/noncore/net/mail/mailwrapper.cpp b/noncore/net/mail/mailwrapper.cpp
index 858283f..75c06f9 100644
--- a/noncore/net/mail/mailwrapper.cpp
+++ b/noncore/net/mail/mailwrapper.cpp
@@ -1,87 +1,166 @@
#include <stdlib.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>
#include <fcntl.h>
#include <string.h>
#include <qdir.h>
#include "mailwrapper.h"
#include "logindialog.h"
//#include "mail.h"
#include "defines.h"
Attachment::Attachment( DocLnk lnk )
{
doc = lnk;
size = QFileInfo( doc.file() ).size();
}
Folder::Folder(const QString&tmp_name, const QString&sep )
{
name = tmp_name;
nameDisplay = name;
-
- for ( int pos = nameDisplay.find( '&' ); pos != -1;
- pos = nameDisplay.find( '&' ) ) {
- int end = nameDisplay.find( '-' );
- if ( end == -1 || end <= pos ) break;
- QString str64 = nameDisplay.mid( pos + 1, end - pos - 1 );
- // TODO: do real base64 decoding here !
- if ( str64.compare( "APw" ) == 0 ) {
- nameDisplay = nameDisplay.replace( pos, end - pos + 1, "ue" );
- } else if ( str64.compare( "APY" ) == 0 ) {
- nameDisplay = nameDisplay.replace( pos, end - pos + 1, "oe" );
- }
- }
- qDebug( "folder " + name + " - displayed as " + nameDisplay );
separator = sep;
}
const QString& Folder::Separator()const
{
return separator;
}
IMAPFolder::IMAPFolder(const QString&name,const QString&sep, bool select,const QString&prefix )
: Folder( name,sep ),m_MaySelect(select)
{
+ // Decode IMAP foldername
+ nameDisplay = IMAPFolder::decodeFolderName( name );
+ qDebug( "folder " + name + " - displayed as " + nameDisplay );
+
if (prefix.length()>0) {
if (nameDisplay.startsWith(prefix) && nameDisplay.length()>prefix.length()) {
nameDisplay=nameDisplay.right(nameDisplay.length()-prefix.length());
}
}
}
+static unsigned char base64chars[] =
+ "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+,";
+
+/**
+ * Decodes base64 encoded parts of the imapfolder name
+ * Code taken from kde cvs: kdebase/kioslave/imap4/rfcdecoder.cc
+ */
+QString IMAPFolder::decodeFolderName( const QString &name )
+{
+ unsigned char c, i, bitcount;
+ unsigned long ucs4, utf16, bitbuf;
+ unsigned char base64[256], utf8[6];
+ unsigned long srcPtr = 0;
+ QCString dst;
+ QCString src = name.ascii();
+
+ /* initialize modified base64 decoding table */
+ memset(base64, UNDEFINED, sizeof(base64));
+ for (i = 0; i < sizeof(base64chars); ++i) {
+ base64[(int)base64chars[i]] = i;
+ }
+
+ /* loop until end of string */
+ while (srcPtr < src.length ()) {
+ c = src[srcPtr++];
+ /* deal with literal characters and &- */
+ if (c != '&' || src[srcPtr] == '-') {
+ /* encode literally */
+ dst += c;
+ /* skip over the '-' if this is an &- sequence */
+ if (c == '&')
+ srcPtr++;
+ } else {
+ /* convert modified UTF-7 -> UTF-16 -> UCS-4 -> UTF-8 -> HEX */
+ bitbuf = 0;
+ bitcount = 0;
+ ucs4 = 0;
+ while ((c = base64[(unsigned char) src[srcPtr]]) != UNDEFINED) {
+ ++srcPtr;
+ bitbuf = (bitbuf << 6) | c;
+ bitcount += 6;
+ /* enough bits for a UTF-16 character? */
+ if (bitcount >= 16) {
+ bitcount -= 16;
+ utf16 = (bitcount ? bitbuf >> bitcount : bitbuf) & 0xffff;
+ /* convert UTF16 to UCS4 */
+ if (utf16 >= UTF16HIGHSTART && utf16 <= UTF16HIGHEND) {
+ ucs4 = (utf16 - UTF16HIGHSTART) << UTF16SHIFT;
+ continue;
+ } else if (utf16 >= UTF16LOSTART && utf16 <= UTF16LOEND) {
+ ucs4 += utf16 - UTF16LOSTART + UTF16BASE;
+ } else {
+ ucs4 = utf16;
+ }
+ /* convert UTF-16 range of UCS4 to UTF-8 */
+ if (ucs4 <= 0x7fUL) {
+ utf8[0] = ucs4;
+ i = 1;
+ } else if (ucs4 <= 0x7ffUL) {
+ utf8[0] = 0xc0 | (ucs4 >> 6);
+ utf8[1] = 0x80 | (ucs4 & 0x3f);
+ i = 2;
+ } else if (ucs4 <= 0xffffUL) {
+ utf8[0] = 0xe0 | (ucs4 >> 12);
+ utf8[1] = 0x80 | ((ucs4 >> 6) & 0x3f);
+ utf8[2] = 0x80 | (ucs4 & 0x3f);
+ i = 3;
+ } else {
+ utf8[0] = 0xf0 | (ucs4 >> 18);
+ utf8[1] = 0x80 | ((ucs4 >> 12) & 0x3f);
+ utf8[2] = 0x80 | ((ucs4 >> 6) & 0x3f);
+ utf8[3] = 0x80 | (ucs4 & 0x3f);
+ i = 4;
+ }
+ /* copy it */
+ for (c = 0; c < i; ++c) {
+ dst += utf8[c];
+ }
+ }
+ }
+ /* skip over trailing '-' in modified UTF-7 encoding */
+ if (src[srcPtr] == '-')
+ ++srcPtr;
+ }
+ }
+
+ return QString::fromUtf8( dst.data() );
+}
+
MailWrapper::MailWrapper( Settings *s )
: QObject()
{
settings = s;
}
QString MailWrapper::mailsmtpError( int errnum )
{
switch ( errnum ) {
case MAILSMTP_NO_ERROR:
return tr( "No error" );
case MAILSMTP_ERROR_UNEXPECTED_CODE:
return tr( "Unexpected error code" );
case MAILSMTP_ERROR_SERVICE_NOT_AVAILABLE:
return tr( "Service not available" );
case MAILSMTP_ERROR_STREAM:
return tr( "Stream error" );
case MAILSMTP_ERROR_HOSTNAME:
return tr( "gethostname() failed" );
case MAILSMTP_ERROR_NOT_IMPLEMENTED:
return tr( "Not implemented" );
case MAILSMTP_ERROR_ACTION_NOT_TAKEN:
return tr( "Error, action not taken" );
case MAILSMTP_ERROR_EXCEED_STORAGE_ALLOCATION:
return tr( "Data exceeds storage allocation" );
case MAILSMTP_ERROR_IN_PROCESSING:
return tr( "Error in processing" );
// case MAILSMTP_ERROR_INSUFFISANT_SYSTEM_STORAGE:
// return tr( "Insufficient system storage" );
case MAILSMTP_ERROR_MAILBOX_UNAVAILABLE:
return tr( "Mailbox unavailable" );
case MAILSMTP_ERROR_MAILBOX_NAME_NOT_ALLOWED:
diff --git a/noncore/net/mail/mailwrapper.h b/noncore/net/mail/mailwrapper.h
index d78f8e9..02fe4b7 100644
--- a/noncore/net/mail/mailwrapper.h
+++ b/noncore/net/mail/mailwrapper.h
@@ -59,65 +59,67 @@ public:
const QString&getSubject()const { return subject; }
void setSubject( const QString&s ) { subject = s; }
const QString&getReply()const{ return reply; }
void setReply( const QString&a ) { reply = a; }
private:
QList<Attachment> attList;
QString name, mail, to, cc, bcc, reply, subject, message;
};
class Folder : public QObject
{
Q_OBJECT
public:
Folder( const QString&init_name,const QString&sep );
const QString&getDisplayName()const { return nameDisplay; }
const QString&getName()const { return name; }
virtual bool may_select()const{return true;};
const QString&Separator()const;
protected:
QString nameDisplay, name, separator;
};
class IMAPFolder : public Folder
{
public:
IMAPFolder(const QString&name, const QString&sep, bool select=true,const QString&prefix="" );
virtual bool may_select()const{return m_MaySelect;}
private:
+ static QString decodeFolderName( const QString &name );
bool m_MaySelect;
+
};
class MailWrapper : public QObject
{
Q_OBJECT
public:
MailWrapper( Settings *s );
void sendMail( Mail mail );
private:
mailimf_mailbox *newMailbox(const QString&name,const QString&mail );
mailimf_address_list *parseAddresses(const QString&addr );
mailimf_fields *createImfFields( Mail *mail );
mailmime *buildTxtPart( QString str );
mailmime *buildFilePart( QString filename, QString mimetype );
void addFileParts( mailmime *message, QList<Attachment> files );
mailmime *createMimeMail( Mail *mail );
void smtpSend( mailmime *mail );
mailimf_field *getField( mailimf_fields *fields, int type );
clist *createRcptList( mailimf_fields *fields );
char *getFrom( mailmime *mail );
SMTPaccount *getAccount( QString from );
void writeToFile( QString file, mailmime *mail );
void readFromFile( QString file, char **data, size_t *size );
static QString mailsmtpError( int err );
static QString getTmpFile();
Settings *settings;
};