📄 imapprotocol.cpp
字号:
/******************************************************************************** Copyright (C) 2000-2006 TROLLTECH ASA. All rights reserved.**** This file is part of the Phone Edition of the Qtopia Toolkit.**** Licensees holding a valid license agreement from Trolltech or any of its** authorized distributors may use this file in accordance with** the License Agreement provided with the Licensed Software.**** See http://www.trolltech.com/pricing.html or email sales@trolltech.com for** information about Trolltech's Commercial License Agreements.**** Contact info@trolltech.com if any conditions of this licensing are** not clear to you.********** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.******************************************************************************/#include <qapplication.h>#include "imapprotocol.h"/* Helper class to reduce memory usage while downloading large mails */class ImapPrivate {public: ImapPrivate() { pos = -1; len = 0; } void reset() { data = ""; pos = -1; len = 0; oldPos = -1; } QString first() { pos = data.indexOf('\n', 0); if ( pos == -1 ) return QString::null; pos++; oldPos = -1; return data.mid(0, pos); } QString next() { oldPos = pos; if ( pos >= len ) return QString::null; int start = pos; pos = data.indexOf('\n', start); if ( pos == -1 ) pos = data.length()-1; pos++; return data.mid(start, pos - start); } QString current() { if ( oldPos == -1 ) return first(); pos = oldPos; return next(); } void append(QString str) { data += str; len += str.length(); }private: int len; int pos; int oldPos; QString data; // Tried QCString, but the process of converting QCStrings to QStrings are too slow.};ImapProtocol::ImapProtocol(){ _connected = false; read = 0; firstParseFetch = true; d = new ImapPrivate(); socket = 0;#ifdef SMTPAUTH secureSocket = 0;#endif}ImapProtocol::~ImapProtocol(){ delete socket; delete stream; delete d;}bool ImapProtocol::open(QString url, int port){ if ( _connected ) { qWarning("socket in use, connection refused"); return false; }#ifdef SMTPAUTH if(secureSocket) { secureSocket->deleteLater(); delete stream; secureSocket = 0; socket = 0; }#endif if(!socket) { socket = new QTcpSocket(this); socket->setObjectName("imapProtocol"); connect(socket, SIGNAL(error(QAbstractSocket::SocketError)),SLOT(socketError(QAbstractSocket::SocketError))); connect(socket, SIGNAL(connected()), this, SLOT(connectionEstablished())); connect(socket, SIGNAL(readyRead()), this, SLOT(incomingData())); connect(&incomingDataTimer, SIGNAL(timeout()), this, SLOT(incomingData())); connect(&parseFetchTimer, SIGNAL(timeout()), this, SLOT(parseFetch())); stream = new QTextStream(socket); } status = IMAP_Init; errorList.clear(); _connected = true; requestCount = 0; requests.clear(); d->reset(); socket->connectToHost(url, port); return true;}#ifdef SMTPAUTHbool ImapProtocol::openSecure(QString url, int port, bool useTLS){ if ( _connected ) { qWarning("socket in use, connection refused"); return false; } if(socket && !secureSocket) { socket->deleteLater(); delete stream; socket = 0; } //if useTLS is enabled then enable starttls for the connection if(!secureSocket) { if(!useTLS) //SSL connection { secureSocket = new QtSslSocket(QtSslSocket::Client,this); secureSocket->setObjectName("imapProtocol-secure"); secureSocket->setPathToCACertDir(QtMail::sslCertsPath()); connect(secureSocket,SIGNAL(connectionVerificationDone(QtSslSocket::VerifyResult,bool, const QString&)),SLOT(certCheckDone(QtSslSocket::VerifyResult,bool,const QString&))); socket = secureSocket; connect(socket, SIGNAL(error(QAbstractSocket::SocketError)),SLOT(socketError(QAbstractSocket::SocketError))); connect(socket, SIGNAL(connected()), this, SLOT(connectionEstablished())); connect(socket, SIGNAL(readyRead()), this, SLOT(incomingData())); connect(&incomingDataTimer, SIGNAL(timeout()), this, SLOT(incomingData())); connect(&parseFetchTimer, SIGNAL(timeout()), this, SLOT(parseFetch())); stream = new QTextStream(socket); } else { //TODO add support for starttls command } } status = IMAP_Init; errorList.clear(); _connected = true; requestCount = 0; requests.clear(); d->reset(); secureSocket->connectToHost(url, port); return true;}void ImapProtocol::certCheckDone(QtSslSocket::VerifyResult result ,bool hostMatched,const QString& msg){ Q_UNUSED(hostMatched) if(result == QtSslSocket::VerifyOk) return; qWarning(("SSL cert check failed: " + msg).toAscii()); socket->close(); _connected = false; emit connectionError(static_cast<int>(result));}#endifvoid ImapProtocol::close(){ _connected = false; _name = ""; socket->close();}int ImapProtocol::exists(){ return _exists;}int ImapProtocol::recent(){ return _recent;}QString ImapProtocol:: mailboxUid(){ return _mailboxUid;}QString ImapProtocol::flags(){ return _flags;}QStringList ImapProtocol::mailboxUidList(){ return uidList;}QString ImapProtocol::selected(){ return _name;}/* Type ignored for now */void ImapProtocol::login(QString user, QString password){ QString cmd = "LOGIN " + user + " " + password + "\r\n"; status = IMAP_Login; sendCommand(cmd);}void ImapProtocol::logout(){ QString cmd = "LOGOUT\r\n"; status = IMAP_Logout; sendCommand(cmd);}void ImapProtocol::list(QString reference, QString mailbox){ QString cmd = "LIST \"" + reference + "\" " + mailbox + "\r\n"; status = IMAP_List; sendCommand(cmd);}void ImapProtocol::select(QString mailbox){ QString cmd = "SELECT " + quoteString(mailbox) + "\r\n"; status = IMAP_Select; _name = mailbox; sendCommand(cmd);}void ImapProtocol::uidSearch(uint from, uint to, MessageFlags flags){ QString str = ""; if ( flags & MFlag_Recent ) str += " RECENT"; if (flags & MFlag_Deleted) str += " DELETED"; if (flags & MFlag_Answered) str += " ANSWERED"; if (flags & MFlag_Flagged) str += " FLAGGED"; if (flags & MFlag_Seen) str += " SEEN"; if (flags & MFlag_Unseen) str += " UNSEEN"; if (flags & MFlag_Draft) str += " DRAFT"; QString cmd = QString("UID SEARCH %1:%2%3\r\n").arg(from).arg(to).arg(str); status = IMAP_UIDSearch; sendCommand(cmd);}void ImapProtocol::uidSearch(MessageFlags flags){ QString str = ""; if ( flags & MFlag_Recent ) str += " RECENT"; if (flags & MFlag_Deleted) str += " DELETED"; if (flags & MFlag_Answered) str += " ANSWERED"; if (flags & MFlag_Flagged) str += " FLAGGED"; if (flags & MFlag_Seen) str += " SEEN"; if (flags & MFlag_Unseen) str += " UNSEEN"; if (flags & MFlag_Draft) str += " DRAFT"; QString cmd = QString("UID SEARCH%1\r\n").arg(str); status = IMAP_UIDSearch; sendCommand(cmd);}void ImapProtocol::uidFetch(QString from, QString to, FetchItemFlags items){ dataItems = items; QString flags = "(FLAGS"; if (dataItems & F_UID) flags += " UID"; if (dataItems & F_RFC822_SIZE) flags += " RFC822.SIZE"; if (dataItems & F_RFC822_HEADER) flags += " RFC822.HEADER"; if (dataItems & F_RFC822) flags += " RFC822"; flags += ")"; QString cmd = QString("UID FETCH %1:%2 %3\r\n").arg(from).arg(to).arg(flags); status = IMAP_UIDFetch; sendCommand(cmd);}/* Note that \Recent flag is ignored as only the server is allowed to set/unset that flag */void ImapProtocol::uidStore(QString uid, MessageFlags flags){ QString str = "FLAGS ("; if (flags & MFlag_Deleted) { str += "\\Deleted "; // No tr uidList.removeAll(uid); } if (flags & MFlag_Answered) str += "\\Answered "; // No tr if (flags & MFlag_Flagged) str += "\\Flagged "; // No tr if (flags & MFlag_Seen) str += "\\Seen "; // No tr if (flags & MFlag_Draft) str += "\\Draft "; // No tr str = str.trimmed() + ")"; QString cmd = QString("UID STORE %1 %2\r\n").arg(uid).arg(str); status = IMAP_UIDStore; sendCommand(cmd);}void ImapProtocol::expunge(){ QString cmd = "EXPUNGE\r\n"; status = IMAP_Expunge; sendCommand(cmd);}void ImapProtocol::connectionEstablished(){ // qWarning( "Connection established");#ifdef SMTPAUTH if(secureSocket) qDebug("Secure connection established");#endif mailDropSize = 0;}void ImapProtocol::socketError(QAbstractSocket::SocketError status){ _connected = false; socket->close(); if(this->status != IMAP_Logout) emit connectionError(static_cast<int>(status));}void ImapProtocol::sendCommand(QString cmd){ QString command = newCommandId() + " " + cmd; requests.append(command); d->reset();// qWarning("sending command: " + command); *stream << command << flush;}void ImapProtocol::incomingData(){ int readLines = 0; while ( socket->canReadLine() ) { response = socket->readLine(); readLines++; read += response.length(); if (status != IMAP_Init) { d->append( response ); } if ( (status == IMAP_UIDFetch) && (dataItems & F_RFC822) ) { mailDropSize += response.length(); } if(readLines > 30){ incomingDataTimer.start(0); return; }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -