1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* This Source Code Form is subject to the terms of the Mozilla Public
3  * License, v. 2.0. If a copy of the MPL was not distributed with this
4  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
5 
6 #ifndef _nsIMAPServerResponseParser_H_
7 #define _nsIMAPServerResponseParser_H_
8 
9 #include "mozilla/Attributes.h"
10 #include "nsIImapHostSessionList.h"
11 #include "nsImapSearchResults.h"
12 #include "nsString.h"
13 #include "MailNewsTypes.h"
14 #include "nsTArray.h"
15 #include "nsImapUtils.h"
16 
17 class nsImapBodyShell;
18 class nsIMAPBodypart;
19 class nsImapSearchResultIterator;
20 class nsIImapFlagAndUidState;
21 
22 #include "nsImapGenericParser.h"
23 
24 class nsImapServerResponseParser : public nsImapGenericParser {
25  public:
26   explicit nsImapServerResponseParser(nsImapProtocol& imapConnection);
27   virtual ~nsImapServerResponseParser();
28 
29   // Overridden from the base parser class
30   virtual bool LastCommandSuccessful() override;
31   virtual void HandleMemoryFailure() override;
32 
33   // aignoreBadAndNOResponses --> don't throw a error dialog if this command
34   // results in a NO or Bad response from the server..in other words the command
35   // is "exploratory" and we don't really care if it succeeds or fails. This
36   // value is typically FALSE for almost all cases.
37   virtual void ParseIMAPServerResponse(const char* aCurrentCommand,
38                                        bool aIgnoreBadAndNOResponses,
39                                        char* aGreetingWithCapability = NULL);
40   virtual void InitializeState();
41   bool CommandFailed();
42   void SetCommandFailed(bool failed);
43 
44   enum eIMAPstate { kNonAuthenticated, kAuthenticated, kFolderSelected };
45 
46   virtual eIMAPstate GetIMAPstate();
WaitingForMoreClientInput()47   virtual bool WaitingForMoreClientInput() {
48     return fWaitingForMoreClientInput;
49   }
50   const char* GetSelectedMailboxName();  // can be NULL
IsStdJunkNotJunkUseOk()51   bool IsStdJunkNotJunkUseOk() { return fStdJunkNotJunkUseOk; }
52 
53   // if we get a PREAUTH greeting from the server, initialize the parser to
54   // begin in the kAuthenticated state
55   void PreauthSetAuthenticatedState();
56 
57   // these functions represent the state of the currently selected
58   // folder
59   bool CurrentFolderReadOnly();
60   int32_t NumberOfMessages();
61   int32_t NumberOfRecentMessages();
62   int32_t NumberOfUnseenMessages();
63   int32_t FolderUID();
64   uint32_t CurrentResponseUID();
65   uint32_t HighestRecordedUID();
66   void ResetHighestRecordedUID();
67   void SetCurrentResponseUID(uint32_t uid);
68   bool IsNumericString(const char* string);
69   uint32_t SizeOfMostRecentMessage();
SetTotalDownloadSize(int32_t newSize)70   void SetTotalDownloadSize(int32_t newSize) { fTotalDownloadSize = newSize; }
71 
72   nsImapSearchResultIterator* CreateSearchResultIterator();
ResetSearchResultSequence()73   void ResetSearchResultSequence() { fSearchResults->ResetSequence(); }
74 
75   // create a struct mailbox_spec from our info, used in
76   // libmsg c interface
77   already_AddRefed<nsImapMailboxSpec> CreateCurrentMailboxSpec(
78       const char* mailboxName = nullptr);
79 
80   // Resets the flags state.
81   void ResetFlagInfo();
82 
83   // set this to false if you don't want to alert the user to server
84   // error messages
SetReportingErrors(bool reportThem)85   void SetReportingErrors(bool reportThem) { fReportingErrors = reportThem; }
GetReportingErrors()86   bool GetReportingErrors() { return fReportingErrors; }
87 
GetCapabilityFlag()88   eIMAPCapabilityFlags GetCapabilityFlag() { return fCapabilityFlag; }
SetCapabilityFlag(eIMAPCapabilityFlags capability)89   void SetCapabilityFlag(eIMAPCapabilityFlags capability) {
90     fCapabilityFlag = capability;
91   }
ServerHasIMAP4Rev1Capability()92   bool ServerHasIMAP4Rev1Capability() {
93     return ((fCapabilityFlag & kIMAP4rev1Capability) != 0);
94   }
ServerHasACLCapability()95   bool ServerHasACLCapability() {
96     return ((fCapabilityFlag & kACLCapability) != 0);
97   }
ServerHasNamespaceCapability()98   bool ServerHasNamespaceCapability() {
99     return ((fCapabilityFlag & kNamespaceCapability) != 0);
100   }
ServerIsNetscape3xServer()101   bool ServerIsNetscape3xServer() { return fServerIsNetscape3xServer; }
ServerHasServerInfo()102   bool ServerHasServerInfo() {
103     return ((fCapabilityFlag & kXServerInfoCapability) != 0);
104   }
ServerIsAOLServer()105   bool ServerIsAOLServer() {
106     return ((fCapabilityFlag & kAOLImapCapability) != 0);
107   }
SetFetchingFlags(bool aFetchFlags)108   void SetFetchingFlags(bool aFetchFlags) { fFetchingAllFlags = aFetchFlags; }
109   void ResetCapabilityFlag();
110 
GetMailAccountUrl()111   nsCString& GetMailAccountUrl() { return fMailAccountUrl; }
GetXSenderInfo()112   const char* GetXSenderInfo() { return fXSenderInfo; }
FreeXSenderInfo()113   void FreeXSenderInfo() { PR_FREEIF(fXSenderInfo); }
GetManageListsUrl()114   nsCString& GetManageListsUrl() { return fManageListsUrl; }
GetManageFiltersUrl()115   nsCString& GetManageFiltersUrl() { return fManageFiltersUrl; }
GetManageFolderUrl()116   const char* GetManageFolderUrl() { return fFolderAdminUrl; }
GetServerID()117   nsCString& GetServerID() { return fServerIdResponse; }
118 
119   // Call this when adding a pipelined command to the session
120   void IncrementNumberOfTaggedResponsesExpected(const char* newExpectedTag);
121 
122   // Interrupt a Fetch, without really Interrupting (through netlib)
123   bool GetLastFetchChunkReceived();
124   void ClearLastFetchChunkReceived();
SupportsUserFlags()125   virtual uint16_t SupportsUserFlags() { return fSupportsUserDefinedFlags; }
SettablePermanentFlags()126   virtual uint16_t SettablePermanentFlags() { return fSettablePermanentFlags; }
127   void SetFlagState(nsIImapFlagAndUidState* state);
128   bool GetDownloadingHeaders();
129   bool GetFillingInShell();
130   void UseCachedShell(nsImapBodyShell* cachedShell);
131   void SetHostSessionList(nsIImapHostSessionList* aHostSession);
132   char* fAuthChallenge;    // the challenge returned by the server in
133                            // response to authenticate using CRAM-MD5 or NTLM
134   bool fCondStoreEnabled;  // Not used it seems
135   bool fUtf8AcceptEnabled;
136   bool fUseModSeq;  // can use mod seq for currently selected folder
137   uint64_t fHighestModSeq;
138 
139  protected:
140   virtual void flags();
141   virtual void envelope_data();
142   virtual void xaolenvelope_data();
143   virtual void parse_address(nsAutoCString& addressLine);
144   virtual void internal_date();
145   virtual nsresult BeginMessageDownload(const char* content_type);
146 
147   virtual void response_data();
148   virtual void resp_text();
149   virtual void resp_cond_state(bool isTagged);
150   virtual void text_mime2();
151   virtual void text();
152   virtual void parse_folder_flags(bool calledForFlags);
153   virtual void enable_data();
154   virtual void language_data();
155   virtual void authChallengeResponse_data();
156   virtual void resp_text_code();
157   virtual void response_done();
158   virtual void response_tagged();
159   virtual void response_fatal();
160   virtual void resp_cond_bye();
161   virtual void id_data();
162   virtual void mailbox_data();
163   virtual void numeric_mailbox_data();
164   virtual void capability_data();
165   virtual void xserverinfo_data();
166   virtual void xmailboxinfo_data();
167   virtual void namespace_data();
168   virtual void myrights_data(bool unsolicited);
169   virtual void acl_data();
170   virtual void bodystructure_data();
171   nsIMAPBodypart* bodystructure_part(char* partNum, nsIMAPBodypart* parentPart);
172   nsIMAPBodypart* bodystructure_leaf(char* partNum, nsIMAPBodypart* parentPart);
173   nsIMAPBodypart* bodystructure_multipart(char* partNum,
174                                           nsIMAPBodypart* parentPart);
175   virtual void mime_data();
176   virtual void mime_part_data();
177   virtual void mime_header_data();
178   virtual void quota_data();
179   virtual void msg_fetch();
180   virtual void msg_obsolete();
181   virtual void msg_fetch_headers(const char* partNum);
182   virtual void msg_fetch_content(bool chunk, int32_t origin,
183                                  const char* content_type);
184   virtual bool msg_fetch_quoted();
185   virtual bool msg_fetch_literal(bool chunk, int32_t origin);
186   virtual void mailbox_list(bool discoveredFromLsub);
187   virtual void mailbox(nsImapMailboxSpec* boxSpec);
188 
189   virtual void ProcessOkCommand(const char* commandToken);
190   virtual void ProcessBadCommand(const char* commandToken);
191   virtual void PreProcessCommandToken(const char* commandToken,
192                                       const char* currentCommand);
193   virtual void PostProcessEndOfLine();
194 
195   // Overridden from the nsImapGenericParser, to retrieve the next line
196   // from the open socket.
197   virtual bool GetNextLineForParser(char** nextLine) override;
198   // overridden to do logging
199   virtual void SetSyntaxError(bool error, const char* msg = nullptr) override;
200 
201  private:
202   bool fCurrentCommandFailed;
203   bool fReportingErrors;
204 
205   bool fCurrentFolderReadOnly;
206   bool fCurrentLineContainedFlagInfo;
207   bool fFetchingAllFlags;
208   bool fWaitingForMoreClientInput;
209   // Is the server a Netscape 3.x Messaging Server?
210   bool fServerIsNetscape3xServer;
211   bool fDownloadingHeaders;
212   bool fCurrentCommandIsSingleMessageFetch;
213   bool fGotPermanentFlags;
214   bool fStdJunkNotJunkUseOk;
215   imapMessageFlagsType fSavedFlagInfo;
216   nsTArray<nsCString> fCustomFlags;
217 
218   uint16_t fSupportsUserDefinedFlags;
219   uint16_t fSettablePermanentFlags;
220 
221   int32_t fFolderUIDValidity;
222   int32_t fNumberOfUnseenMessages;
223   int32_t fNumberOfExistingMessages;
224   int32_t fNumberOfRecentMessages;
225   uint32_t fCurrentResponseUID;
226   uint32_t fHighestRecordedUID;
227   // used to handle server that sends msg size after headers
228   uint32_t fReceivedHeaderOrSizeForUID;
229   int32_t fSizeOfMostRecentMessage;
230   int32_t fTotalDownloadSize;
231 
232   int32_t fStatusUnseenMessages;
233   int32_t fStatusRecentMessages;
234   uint32_t fStatusNextUID;
235   uint32_t fStatusExistingMessages;
236 
237   int fNumberOfTaggedResponsesExpected;
238 
239   char* fCurrentCommandTag;
240 
241   nsCString fZeroLengthMessageUidString;
242 
243   char* fSelectedMailboxName;
244 
245   nsImapSearchResultSequence* fSearchResults;
246 
247   nsCOMPtr<nsIImapFlagAndUidState>
248       fFlagState;  // NOT owned by us, it's a copy, do not destroy
249 
250   eIMAPstate fIMAPstate;
251 
252   eIMAPCapabilityFlags fCapabilityFlag;
253   nsCString fMailAccountUrl;
254   char* fNetscapeServerVersionString;
255   char* fXSenderInfo; /* changed per message download */
256   char* fLastAlert; /* used to avoid displaying the same alert over and over */
257   char* fMsgID;     /* MessageID for Gmail only (X-GM-MSGID) */
258   char* fThreadID;  /* ThreadID for Gmail only (X-GM-THRID) */
259   char* fLabels;    /* Labels for Gmail only (X-GM-LABELS) [will include parens,
260                        removed while passing to hashTable ]*/
261   nsCString fManageListsUrl;
262   nsCString fManageFiltersUrl;
263   char* fFolderAdminUrl;
264   nsCString fServerIdResponse;  // RFC
265 
266   int32_t fFetchResponseIndex;
267 
268   // used for aborting a fetch stream when we're pseudo-Interrupted
269   int32_t numberOfCharsInThisChunk;
270   int32_t charsReadSoFar;
271   bool fLastChunk;
272 
273   // Flags split of \r and \n between chunks in msg_fetch_literal().
274   bool fNextChunkStartsWithNewline;
275 
276   // points to the current body shell, if any
277   RefPtr<nsImapBodyShell> m_shell;
278 
279   // The connection object
280   nsImapProtocol& fServerConnection;
281 
282   RefPtr<nsIImapHostSessionList> fHostSessionList;
283   nsTArray<nsMsgKey> fCopyResponseKeyArray;
284 };
285 
286 #endif
287