summaryrefslogtreecommitdiff
Side-by-side diff
Diffstat (more/less context) (ignore whitespace changes)
-rw-r--r--noncore/unsupported/mail2/libmail/configfile.cpp4
-rw-r--r--noncore/unsupported/mail2/libmail/imapbase.cpp36
-rw-r--r--noncore/unsupported/mail2/libmail/imapbase.h3
-rw-r--r--noncore/unsupported/mail2/libmail/imaphandler.cpp7
-rw-r--r--noncore/unsupported/mail2/libmail/imapresponse.cpp224
-rw-r--r--noncore/unsupported/mail2/libmail/imapresponse.h5
-rw-r--r--noncore/unsupported/mail2/viewmail.cpp4
7 files changed, 194 insertions, 89 deletions
diff --git a/noncore/unsupported/mail2/libmail/configfile.cpp b/noncore/unsupported/mail2/libmail/configfile.cpp
index a5c2b49..082b330 100644
--- a/noncore/unsupported/mail2/libmail/configfile.cpp
+++ b/noncore/unsupported/mail2/libmail/configfile.cpp
@@ -101,12 +101,12 @@ QString ConfigFile::rot13(const QString &input)
int l = i.length();
while(l--) {
if (i[l] >= QChar('A') && i[l] <= QChar('M') ||
i[l] >= QChar('a') && i[l] <= QChar('m'))
- i[l] = (char)((int)QChar(l[i])+13);
+ i[l] = QChar(i[l].unicode()+13);
else if (i[l] >= QChar('N') && i[l] <= QChar('Z') ||
i[l] >= QChar('n') && i[l] <= QChar('z'))
- i[l] = (char)((int)QChar(l[i])-13);
+ i[l] = QChar(i[l].unicode()-13);
}
return i;
}
diff --git a/noncore/unsupported/mail2/libmail/imapbase.cpp b/noncore/unsupported/mail2/libmail/imapbase.cpp
index 9a2ba47..4753f43 100644
--- a/noncore/unsupported/mail2/libmail/imapbase.cpp
+++ b/noncore/unsupported/mail2/libmail/imapbase.cpp
@@ -52,12 +52,16 @@ void IMAPBase::writeCommands()
QStringList::Iterator it;
for (it = _commandQueue.begin(); it != _commandQueue.end(); it++) {
if (!(*it).isEmpty() && _writingAllowed) {
#ifndef QT_NO_DEBUG
- qDebug("IMAP > " + (*it).stripWhiteSpace());
+ qDebug("IMAP > " + (*it).stripWhiteSpace().local8Bit ());
#endif
_socket->writeBlock((*it).latin1(), (*it).length());
_writingAllowed = false;
+ if (( *it ). find ( QRegExp ( "^[a-z][0-9]+ " )) == 0 )
+ _lasttag = (*it).left(2);
+
+ connect(_socket, SIGNAL(readyRead()), SLOT(slotDataAvailiable()));
_commandQueue.remove(it);
break;
}
}
@@ -92,19 +96,37 @@ void IMAPBase::slotDisconnected()
_connected = false;
emit disconnected();
}
+#include <unistd.h>
+
void IMAPBase::slotDataAvailiable()
{
+ static bool firstline = true;
+
while (_socket->canReadLine()) {
- _data += _socket->readLine();
- if (_socket->atEnd()) {
-#ifndef QT_NO_DEBUG
- qDebug("IMAP < " + _data.stripWhiteSpace());
-#endif
+ QString tmp = _socket-> readLine ( );
+
+ _data += tmp;
+ qDebug ( "New Line [%d]: '%s'\n", _connected ? 1 : 0, tmp.latin1( ));
+
+ if ( firstline || tmp. left(2) == _lasttag ) {
+ firstline = false;
+
+// if ( _socket-> atEnd ( ))
+ qDebug ( "at end -> emitting\n" );
+
+ QObject::disconnect(_socket, SIGNAL(readyRead()), this, SLOT(slotDataAvailiable()));
emit dataReceived(_data);
+ _data = QString::null;
_writingAllowed = true;
- _data = QString(0);
}
}
}
+void IMAPBase::tryRead ( QString &data )
+{
+ qDebug ( "Trying to read...\n" );
+
+ while ( _socket-> canReadLine ( ))
+ data += _socket-> readLine ( );
+}
diff --git a/noncore/unsupported/mail2/libmail/imapbase.h b/noncore/unsupported/mail2/libmail/imapbase.h
index e4a0b97..7697ffe 100644
--- a/noncore/unsupported/mail2/libmail/imapbase.h
+++ b/noncore/unsupported/mail2/libmail/imapbase.h
@@ -38,15 +38,16 @@ protected slots:
void slotHostFound();
void slotConnected();
void slotDisconnected();
void slotDataAvailiable();
+ void tryRead ( QString & );
private:
Account _account;
QString _data;
QSocket *_socket;
QStringList _commandQueue;
bool _connected, _writingAllowed;
-
+ QString _lasttag;
};
#endif
diff --git a/noncore/unsupported/mail2/libmail/imaphandler.cpp b/noncore/unsupported/mail2/libmail/imaphandler.cpp
index 7493240..dc97b28 100644
--- a/noncore/unsupported/mail2/libmail/imaphandler.cpp
+++ b/noncore/unsupported/mail2/libmail/imaphandler.cpp
@@ -297,13 +297,16 @@ void IMAPHandler::slotDataReceived(const QString &data)
return;
}
- IMAPResponseParser parser(data);
+ IMAPResponseParser parser;
+// connect ( &parser, SIGNAL( needMoreData ( QString & )), _ibase, SLOT( tryRead ( QString & )));
+ parser. parse ( data );
IMAPResponse response = parser.response();
+// disconnect ( &parser, SIGNAL( needMoreData ( QString & )), _ibase, SLOT( tryRead ( QString & )));
response.setImapHandler(this);
- if (!_loggingin) emit gotResponse(response);
+ if (!_loggingin) { qDebug("Emitting gotResponse!\n" ); emit gotResponse(response); }
else {
if (response.statusResponse().status() == IMAPResponseEnums::OK) {
_loggingin = false;
_loggedin = true;
diff --git a/noncore/unsupported/mail2/libmail/imapresponse.cpp b/noncore/unsupported/mail2/libmail/imapresponse.cpp
index 06dca33..ce5b18b 100644
--- a/noncore/unsupported/mail2/libmail/imapresponse.cpp
+++ b/noncore/unsupported/mail2/libmail/imapresponse.cpp
@@ -1,63 +1,94 @@
#include "imapresponse.h"
-static QString _previousData;
-static unsigned int _neededData;
-IMAPResponseParser::IMAPResponseParser(const QString &data)
+IMAPResponseParser::IMAPResponseParser()
+{
+}
+
+void IMAPResponseParser::parse ( const QString &_data )
{
- QString _data = data, more;
- _data.replace((QString)"\r\n", "\n");
-
- QStringList lines = QStringList::split('\n', _data);
- QStringList::Iterator it;
- for (it = lines.begin(); it != lines.end(); it++) {
- QString tag, lineData;
-
- if (!_previousData.isNull()) {
- qDebug(QString("IMAPResponseParser: got additional data. (%1/%2)").arg(_previousData.length()).arg(_neededData));
- _previousData += *it + "\n";
- if (_previousData.length() >= _neededData) {
- _previousData += ")";
- qDebug("IMAPResponseParser: got ALL additional data.");
- qDebug("Data is: " + _previousData);
- parseResponse(_previousData);
- _previousData = QString(0);
- _neededData = 0;
- }
- } else {
- splitTagData(*it, tag, lineData);
- if (tag == "*") {
- int pos;
- if ((pos = data.find(QRegExp("\\{\\d*\\}"))) != -1) {
- qDebug("IMAPResponseParser: waiting for additional data...");
- _previousData = lineData + "\n";
-
- QString tmp = data.right(data.length() - pos - 1).stripWhiteSpace();
- tmp.truncate(tmp.length() - 1);
-
- _neededData = tmp.toUInt();
- if (_previousData.length() >= _neededData) {
- qDebug("IMAPResponseParser: got ALL additional data. (1st)");
- parseResponse(_previousData);
- _previousData = QString(0);
- _neededData = 0;
- } else {
+ QString data = _data;
+
+ int pos = 0;
+ int len = data. length ( );
+
+
+ while ( pos < len ) {
+ pos = data. find ( QRegExp ( "[^\\s]" ), pos );
+
+ if (( pos < 0 ) || ( pos >= len ))
+ break;
+
+ switch ( data [pos]. latin1 ( )) {
+ case '*': {
+ qDebug ( "* ASTERIX\n" );
+
+ int eol = data. find ( '\n', pos );
+ int bracket = data. findRev ( '{', eol );
+ int rest = data. find ( QRegExp ( "[^\\s]" ), pos + 1 );
+
+ qDebug ( "pos=%d, rest=%d, bracket=%d, eol=%d\n", pos, rest, bracket, eol );
+
+ if ( bracket > pos ) {
+ uint needdata = data. mid ( bracket + 1, data. find ( '}', bracket + 1 ) - bracket - 1 ). toUInt ( );
+
+ if ( needdata ) {
+ qDebug ( "nd=%d - hd=%d\n", needdata, ( len - eol - 1 ));
+
+ while ( needdata > ( len - eol - 1 )) {
+ qDebug ( "emitting need more...\n" );
+ emit needMoreData ( data );
+ len = data. length ( );
+ }
+ qDebug ( "Got all data...\n" );
+
+ QString tmp = data. mid ( rest, eol - rest + 1 + needdata );
+
+ int tail = 0;
+
+ while ( data [eol - rest + 1 + needdata + tail] != ')' )
+ tail++;
+ tmp. append ( data. mid ( eol - rest + 1 + needdata, tail + 1 ));
+
+
+ qDebug ( "Complete parse = |%s|\n", tmp.latin1());
+
+ parseResponse ( tmp );
+
+ pos = rest + needdata + tail + 1;
break;
- }
- } else {
- parseResponse(lineData);
+ }
}
- } else if (tag == "+") {
- emit needMoreData(_data);
- } else {
- _iresponse.setTag(tag);
- parseResponse(_data, true);
+
+ parseResponse ( data. mid ( rest, eol - rest + 1 ). stripWhiteSpace ( ));
+ break;
+ }
+ case '+': {
+ qDebug ( "+ PLUS\n" );
+
+ emit needMoreData ( data );
+ len = data. length ( );
+ break;
+ }
+ default : {
+ qDebug ( "OTHER: '%s...'\n", data. mid ( pos, 20 ). latin1 ( ));
+
+ uint rest = data. find ( ' ', pos + 1 );
+ rest = data. find ( QRegExp ( "[^\\s]" ), rest + 1 );
+ _iresponse. setTag ( data. mid ( pos, rest - pos ). stripWhiteSpace ( ));
+ parseResponse ( data. mid ( rest, data. find ( '\n', rest )). stripWhiteSpace ( ), true );
+ break;
}
}
+
+ // skip to end-of-line
+ while (( pos < len ) && ( data [pos] != '\n' ))
+ pos++;
}
}
+
IMAPResponse IMAPResponseParser::response()
{
return _iresponse;
}
@@ -66,14 +97,18 @@ void IMAPResponseParser::parseResponse(const QString &data, bool tagged)
{
QString response, line;
int pos;
bool isNum = false;
+
+
+// qDebug ( "\n\n#### PRD #### : #%s#\n\n", data.latin1());
+
if ((pos = data.find(' ')) != -1) {
response = data.left(pos).upper();
response.toInt(&isNum);
line = data.right(data.length() - pos - 1);
} else {
- qWarning("IMAPResponseParser: parseResponse: No response found.");
+ qWarning("IMAPResponseParser: parseResponse: No response found.");
return;
}
if (response == "OK" && tagged) {
@@ -144,9 +179,9 @@ void IMAPResponseParser::parseResponse(const QString &data, bool tagged)
else if (*it == "RECENT") status.setRecent(*(++it));
else if (*it == "UIDNEXT") status.setUidnext(*(++it));
else if (*it == "UIDVALIDITY") status.setUidvalidity(*(++it));
else if (*it == "UNSEEN") status.setUnseen(*(++it));
- else qWarning("IMAPResponseParser: parseResponse: Unknown status data: " + *(it++) + "|");
+ else qWarning((QString("IMAPResponseParser: parseResponse: Unknown status data: " )+ *(it++) + "|").latin1());
}
_iresponse.addSTATUS(status);
} else if (response == "SEARCH") {
IMAPResponseSEARCH search(QStringList::split(' ', line));
@@ -171,35 +206,46 @@ void IMAPResponseParser::parseResponse(const QString &data, bool tagged)
} else if (list[0] == "FETCH") {
IMAPResponseFETCH fetch;
QStringList::Iterator it;
+ qDebug ( "Got FETCH\n" );
+
QStringList fetchList = splitData(line, true);
QStringList list;
+
+ qDebug ( "fl [0]=%s, fl [1]=%s, fl[2]=%s\n", fetchList[0].latin1(),fetchList[1].latin1(),fetchList[2].latin1());
+
parseParenthesizedList(fetchList[1], list);
for (it = list.begin(); it != list.end(); it++) {
+ qDebug ( "Checking list[] == %s\n", (*it).latin1());
+
if (*it == "BODY") {
qDebug("IMAPResponseParser: responseParser: got FETCH::BODY");
// XXX
- } else if ((*it).find(QRegExp("BODY\\[\\d+\\]")) != -1) {
- QString bodydata = *(++it);
+ } else if ((*it).find(QRegExp("^BODY\\[\\d+\\]")) != -1) {
qDebug("IMAPResponseParser: responseParser: got FETCH::BODY[x]");
- QStringList blist;
- parseParenthesizedList(bodydata, blist);
+ QString number = ( *it ). mid ( 5, ( *it ). length ( ) - 6 );
+ QString bodydata = *(++it);
+
+// QStringList blist;
+// parseParenthesizedList(bodydata, blist);
IMAPResponseBodyPart bodypart;
- QString tmp;
- for (unsigned int i = 2; i < blist.count(); i++) {
- if (i != 2) tmp += " " + blist[i];
- else tmp += blist[i];
- }
- bodypart.setData(tmp);
+// QString tmp;
+// for (unsigned int i = 2; i < blist.count(); i++) {
+// if (i != 2) tmp += " " + blist[i];
+// else tmp += blist[i];
+// }
+ bodypart.setData(bodydata);
+
+// QString tmp = list[0];
+// tmp.replace(0, 5, "");
+// tmp.truncate(blist[0].length() - 1);
+ bodypart.setPart(number);
- tmp = list[0];
- tmp.replace(0, 5, "");
- tmp.truncate(blist[0].length() - 1);
- bodypart.setPart(tmp);
+ qDebug("added bodypart [%s]: '%s'\n\n", number.latin1(), bodydata.latin1());
fetch.addBodyPart(bodypart);
} else if (*it == "BODYSTRUCTURE") {
qDebug("IMAPResponseParser: responseParser: got FETCH::BODYSTRUCTURE");
@@ -336,9 +382,10 @@ void IMAPResponseParser::parseResponse(const QString &data, bool tagged)
}
}
_iresponse.addFETCH(fetch);
}
- } else qWarning("IMAPResponseParser: parseResponse: Unknown response: " + response + "|");
+ } else qWarning((QString("IMAPResponseParser: parseResponse: Unknown response: ") + response + "|").latin1());
+
}
QStringList IMAPResponseParser::splitData(const QString &data, bool withBrackets)
{
@@ -346,20 +393,50 @@ QStringList IMAPResponseParser::splitData(const QString &data, bool withBrackets
bool a = false, noappend = false, escaped = false;
QString temp;
QStringList list;
+ qDebug ( "sd: '%s'\n", data.latin1());
+
for (unsigned int i = 0; i <= data.length(); i++) {
if (withBrackets && data[i] == '(' && !a) b++;
else if (withBrackets && data[i] == ')' && !a) b--;
- if (data[i] == '"' && !escaped) a = !a;
+ if (data[i] == '{' && !escaped && !a ) {
+ qDebug ( "sd: found a {\n" );
+
+ int p = data. find ( '}', i + 1 );
+ int eol = data. find ( '\n', i + 1 );
+
+ if ( p > int( i )) {
+ int len = data. mid ( i + 1, p - i - 1 ). toInt ( );
+
+ qDebug ( "sd: skipping %d bytes\n", len );
+
+ if ( b == 0 ) {
+ temp = data. mid ( eol + 1, len );
+ noappend = false;
+ i = eol + len;
+ continue;
+ }
+ else {
+ temp. append ( '{' );
+ temp. append ( QString::number ( len ));
+ temp. append ( "}\r\n" );
+ temp. append ( data. mid ( eol + 1, len ));
+ i = eol + len;
+ continue;
+ }
+ }
+ }
+
+ if (data[i] == '\"' && !escaped) a = !a;
else escaped = false;
- if (data[i] == '\\' && data[i + 1] == '"') escaped = true;
+ if (data[i] == '\\' && data[i + 1] == '\"') escaped = true;
if ((data[i] == ' ' || i == data.length()) && b == 0 && !a) {
list.append(temp);
- temp = QString(0);
+ temp = QString::null;
if (data[i] == ' ') noappend = true;
}
if (!noappend) temp += data[i];
@@ -381,24 +458,25 @@ void IMAPResponseParser::splitTagData(const QString &line, QString &tag, QString
int pos;
if ((pos = line.find(' ')) != -1) {
tag = line.left(pos);
data = line.right(line.length() - pos - 1);
- } else qWarning("IMAPResponseParser: splitTagData: tag not found. Line was " + line + "|");
+ } else qWarning((QString("IMAPResponseParser: splitTagData: tag not found. Line was ") + line + "|").latin1());
}
QString IMAPResponseParser::removeLimiters(QString &string, const QChar &sl, const QChar &el)
{
QString tmpString;
+ string = string. stripWhiteSpace ( );
+
if (string[0] == sl && string[string.length() - 1] == el) {
string.truncate(string.length() - 1);
string.replace(0, 1, "");
for (unsigned int i = 1; i <= string.length(); i++) {
- if (string[i - 1] == '\\' && sl == '"') ++i;
+ if (string[i - 1] == '\\' && sl == '\"') ++i;
tmpString += string[i - 1];
}
}
-
return tmpString;
}
IMAPResponseEnums::IMAPResponseCode IMAPResponseParser::getResponseCode(const QString &line)
@@ -416,9 +494,9 @@ IMAPResponseEnums::IMAPResponseCode IMAPResponseParser::getResponseCode(const QS
else if (code.find(QRegExp("[TRYCREATE]")) != -1) return TRYCREATE;
else if (code.find(QRegExp("[UIDVALIDITY \\d*]")) != -1) return UIDVALIDITY; // XXX
else if (code.find(QRegExp("[UNSEEN \\d*]")) != -1) return UNSEEN; // XXX
else {
- qWarning("IMAPResponseParser: getResponseCode: Unknown code: " + code + "|");
+ qWarning((QString("IMAPResponseParser: getResponseCode: Unknown code: ") + code + "|").latin1());
return UnknownCode;
}
}
return NoCode;
@@ -440,9 +518,9 @@ QValueList<IMAPResponseEnums::IMAPResponseFlags> IMAPResponseParser::parseFlagLi
else if (flag == "\\noselect") flags.append(Noselect);
else if (flag == "\\marked") flags.append(Marked);
else if (flag == "\\unmarked") flags.append(Unmarked);
else if (flag.isEmpty()) { }
- else qWarning("IMAPResponseParser: parseFlagList: Unknown flag: " + *it + "|");
+ else qWarning((QString("IMAPResponseParser: parseFlagList: Unknown flag: ") + *it + "|").latin1());
}
return flags;
}
diff --git a/noncore/unsupported/mail2/libmail/imapresponse.h b/noncore/unsupported/mail2/libmail/imapresponse.h
index 73435ee..5a19b96 100644
--- a/noncore/unsupported/mail2/libmail/imapresponse.h
+++ b/noncore/unsupported/mail2/libmail/imapresponse.h
@@ -504,14 +504,15 @@ class IMAPResponseParser : public QObject, public IMAPResponseEnums
{
Q_OBJECT
public:
- IMAPResponseParser(const QString &data);
+ IMAPResponseParser();
+ void parse ( const QString &data);
IMAPResponse response();
signals:
- void needMoreData(const QString &comment);
+ void needMoreData(QString &data);
protected:
void parseResponse(const QString &data, bool tagged = false);
diff --git a/noncore/unsupported/mail2/viewmail.cpp b/noncore/unsupported/mail2/viewmail.cpp
index 3c88d99..da6924d 100644
--- a/noncore/unsupported/mail2/viewmail.cpp
+++ b/noncore/unsupported/mail2/viewmail.cpp
@@ -182,12 +182,12 @@ void ViewMail::slotIMAPUid(IMAPResponse &response)
disconnect(_handler, SIGNAL(gotResponse(IMAPResponse &)), this, SLOT(slotIMAPUid(IMAPResponse &)));
if (response.statusResponse().status() == IMAPResponseEnums::OK) {
QValueList<IMAPResponseBodyPart> bodyParts;
- bodyParts.append(response.FETCH()[0].bodyPart(1));
+ bodyParts.append(response.FETCH()[0].bodyPart(0));
_mail.setBodyParts(bodyParts);
- browser->setText(QString(_mailHtml).arg(deHtml(response.FETCH()[0].bodyPart(1).data())));
+ browser->setText(QString(_mailHtml).arg(deHtml(response.FETCH()[0].bodyPart(0).data())));
// fillList(response.FETCH()[0].bodyStructure());
_gotBody = true;