/**************************************************************************** ** ** Copyright (C) 2015 The Qt Company Ltd. ** Contact: http://www.qt.io/licensing/ ** ** This file is part of the Qt Messaging Framework. ** ** $QT_BEGIN_LICENSE:LGPL21$ ** Commercial License Usage ** Licensees holding valid commercial Qt licenses may use this file in ** accordance with the commercial license agreement provided with the ** Software or, alternatively, in accordance with the terms contained in ** a written agreement between you and The Qt Company. For licensing terms ** and conditions see http://www.qt.io/terms-conditions. For further ** information use the contact form at http://www.qt.io/contact-us. ** ** GNU Lesser General Public License Usage ** Alternatively, this file may be used under the terms of the GNU Lesser ** General Public License version 2.1 or version 3 as published by the Free ** Software Foundation and appearing in the file LICENSE.LGPLv21 and ** LICENSE.LGPLv3 included in the packaging of this file. Please review the ** following information to ensure the GNU Lesser General Public License ** requirements will be met: https://www.gnu.org/licenses/lgpl.html and ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. ** ** As a special exception, The Qt Company gives you certain additional ** rights. These rights are described in The Qt Company LGPL Exception ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. ** ** $QT_END_LICENSE$ ** ****************************************************************************/ #ifndef IMAPPROTOCOL_H #define IMAPPROTOCOL_H #include "imapmailboxproperties.h" #include #include #include #include #include #include #include #include #ifdef Q_OS_WIN // Pipe is not a legal filename char in Windows #define UID_SEPARATOR '#' #else #define UID_SEPARATOR '|' #endif class QMailMessage; enum ImapCommand { IMAP_Unconnected = 0, IMAP_Init, IMAP_Capability, IMAP_Idle_Continuation, IMAP_StartTLS, IMAP_Login, IMAP_Logout, IMAP_List, IMAP_Select, IMAP_Examine, IMAP_Search, IMAP_Search_Message, IMAP_Append, IMAP_UIDSearch, IMAP_UIDFetch, IMAP_UIDStore, IMAP_UIDCopy, IMAP_Expunge, IMAP_GenUrlAuth, IMAP_Close, IMAP_Full, IMAP_Idle, IMAP_Create, IMAP_Delete, IMAP_Rename, IMAP_Enable, IMAP_QResync, IMAP_FetchFlags, IMAP_Noop, IMAP_Compress, IMAP_Move }; enum MessageFlag { MFlag_All = 0, // Not a true flag MFlag_Seen = (1 << 0), MFlag_Answered = (1 << 1), MFlag_Flagged = (1 << 2), MFlag_Deleted = (1 << 3), MFlag_Draft = (1 << 4), MFlag_Recent = (1 << 5), MFlag_Unseen = (1 << 6), MFlag_Forwarded = (1 << 7) }; enum FetchDataItem { F_Rfc822_Size = (1 << 0), F_Rfc822_Header = (1 << 1), F_Rfc822 = (1 << 2), F_Uid = (1 << 3), F_Flags = (1 << 4), F_BodyStructure = (1 << 5), F_SectionHeader = (1 << 6), F_BodySection = (1 << 7), F_Date = (1 << 8) }; typedef uint FetchItemFlags; enum OperationStatus { OpPending = 0, OpFailed, OpOk, OpNo, OpBad, }; class Email; class ImapConfiguration; class ImapTransport; class ImapContextFSM; class QMailAccountConfiguration; class ImapProtocol: public QObject { Q_OBJECT public: ImapProtocol(); ~ImapProtocol(); virtual bool open(const ImapConfiguration& config, qint64 bufferSize = 0); void close(); bool connected() const; bool encrypted() const; bool inUse() const; bool loggingOut() const; bool delimiterUnknown() const; bool flatHierarchy() const; void setFlatHierarchy(bool flat); QChar delimiter() const; void setDelimiter(QChar delimiter); bool compress() const; void setCompress(bool comp); bool authenticated() const; void setAuthenticated(bool auth); bool receivedCapabilities() const; void setReceivedCapabilities(bool received); QString lastError() const { return _lastError; } const QStringList &capabilities() const; void setCapabilities(const QStringList &); bool supportsCapability(const QString& name) const; const ImapMailboxProperties &mailbox() const { return _mailbox; } /* Valid in non-authenticated state only */ void sendCapability(); void sendStartTLS(); void sendLogin(const QMailAccountConfiguration &config, const QMailCredentialsInterface *credentials); /* Valid in authenticated state only */ void sendList(const QMailFolder &reference, const QString &mailbox); void sendDiscoverDelimiter(); void sendGenUrlAuth(const QMailMessagePart::Location &location, bool bodyOnly, const QString &mechanism = QString()); void sendAppend(const QMailFolder &mailbox, const QMailMessageId &message); void sendSelect(const QMailFolder &mailbox); void sendQResync(const QMailFolder &mailbox); void sendExamine(const QMailFolder &mailbox); void sendCreate(const QMailFolderId &parentFolderId, const QString &name); void sendDelete(const QMailFolder &mailbox); void sendRename(const QMailFolder &mailbox, const QString &newname); void sendMove(const QMailFolder &mailbox, const QMailFolderId &newParentId); /* Valid in Selected state only */ void sendSearchMessages(const QMailMessageKey &key, const QString &body, const QMailMessageSortKey &sort, bool count); void sendSearch(MessageFlags flags, const QString &range = QString()); void sendUidSearch(MessageFlags flags, const QString &range = QString()); void sendFetchFlags(const QString &range, const QString &prefix = QString()); void sendUidFetch(FetchItemFlags items, const QString &uidList); void sendUidFetchSection(const QString &uid, const QString §ion, int start, int end); void sendUidFetchSectionHeader(const QString &uid, const QString §ion); void sendUidStore(MessageFlags flags, bool set, const QString &range); void sendUidCopy(const QString &range, const QMailFolder &destination); void sendExpunge(); void sendClose(); void sendEnable(const QString &extensions); void sendNoop(); void sendIdle(); void sendIdleDone(); void sendCompress(); /* Valid in all states */ void sendLogout(); static QString uid(const QString &identifier); static QString url(https://code.qt.io/const%20QMailMessagePart::Location%20&location,%20bool%20absolute,%20bool%20bodyOnly); static QString quoteString(const QString& input); static QString unescapeFolderPath(const QString &path); signals: void mailboxListed(const QString &flags, const QString &name); void messageFetched(QMailMessage& mail, const QString &detachedFilename, bool structureOnly); void dataFetched(const QString &uid, const QString §ion, const QString &fileName, int size); void partHeaderFetched(const QString &uid, const QString §ion, const QString &fileName, int size); void downloadSize(const QString &uid, int); void nonexistentUid(const QString& uid); void messageStored(const QString& uid); void messageCopied(const QString& copiedUid, const QString& createdUid); void messageCreated(const QMailMessageId& id, const QString& uid); void urlAuthorized(const QString& url); void folderCreated(const QString &folder, bool success); void folderDeleted(const QMailFolder &name, bool success); void folderRenamed(const QMailFolder &folder, const QString &newPath, bool success); void folderMoved(const QMailFolder &folder, const QString &newPath, const QMailFolderId &newParentId, bool success); void continuationRequired(ImapCommand, const QString &); void completed(ImapCommand, OperationStatus); void updateStatus(const QString &); void connectionError(int status, const QString &msg); void connectionError(QMailServiceAction::Status::ErrorCode status, const QString &msg); // Possibly unilateral notifications related to currently selected folder void exists(int); void recent(int); void uidValidity(const QString &); void flags(const QString &); void highestModSeq(const QString &); void noModSeq(); protected slots: void connected(QMailTransport::EncryptType encryptType); void errorHandling(int status, QString msg); void incomingData(); private: friend class ImapContext; void clearResponse(); int literalDataRemaining() const; void setLiteralDataRemaining(int literalDataRemaining); QString precedingLiteral() const; void setPrecedingLiteral(const QString &line); void continuation(ImapCommand, const QString &); void operationCompleted(ImapCommand, OperationStatus); bool checkSpace(); void createMail(const QString &uid, const QDateTime &timeStamp, int size, uint flags, const QString &file, const QStringList& structure); void createPart(const QString &uid, const QString §ion, const QString &file, int size); void createPartHeader(const QString &uid, const QString §ion, const QString &file, int size); void processResponse(QString line); void nextAction(const QString &line); void sendData(const QString &cmd, bool maskDebug = false); void sendDataLiteral(const QString &cmd, uint length); QString newCommandId(); QString commandId(QString in); OperationStatus commandResponse(QString in); QString sendCommand(const QString &cmd); QString sendCommandLiteral(const QString &cmd, uint length); void parseChange(); private: ImapContextFSM *_fsm; ImapTransport *_transport; LongStream _stream; QStringList _capabilities; ImapMailboxProperties _mailbox; QStringList _errorList; QString _lastError; int _requestCount; int _literalDataRemaining; QString _precedingLiteral; QString _unprocessedInput; QTimer _incomingDataTimer; bool _flatHierarchy; QChar _delimiter; bool _authenticated; bool _receivedCapabilities; static const int MAX_LINES = 30; QByteArray _lineBuffer; }; #endif