summaryrefslogtreecommitdiffstats
path: root/comm/mailnews/imap/src/nsImapServerResponseParser.h
blob: 43d6a736110ee84252f79b80dc39239247b8196f (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

#ifndef _nsIMAPServerResponseParser_H_
#define _nsIMAPServerResponseParser_H_

#include "mozilla/Attributes.h"
#include "../public/nsIImapHostSessionList.h"
#include "nsImapSearchResults.h"
#include "nsString.h"
#include "MailNewsTypes.h"
#include "nsTArray.h"
#include "nsImapUtils.h"

class nsImapSearchResultIterator;
class nsIImapFlagAndUidState;

#include "nsImapGenericParser.h"

class nsImapServerResponseParser : public nsImapGenericParser {
 public:
  explicit nsImapServerResponseParser(nsImapProtocol& imapConnection);
  virtual ~nsImapServerResponseParser();

  // Overridden from the base parser class
  virtual bool LastCommandSuccessful() override;
  virtual void HandleMemoryFailure() override;

  // aignoreBadAndNOResponses --> don't throw a error dialog if this command
  // results in a NO or Bad response from the server..in other words the command
  // is "exploratory" and we don't really care if it succeeds or fails. This
  // value is typically FALSE for almost all cases.
  virtual void ParseIMAPServerResponse(const char* aCurrentCommand,
                                       bool aIgnoreBadAndNOResponses,
                                       char* aGreetingWithCapability = NULL);
  virtual void InitializeState();
  bool CommandFailed();
  void SetCommandFailed(bool failed);
  bool UntaggedResponse();

  enum eIMAPstate { kNonAuthenticated, kAuthenticated, kFolderSelected };

  virtual eIMAPstate GetIMAPstate();
  virtual bool WaitingForMoreClientInput() {
    return fWaitingForMoreClientInput;
  }
  const char* GetSelectedMailboxName();  // can be NULL
  bool IsStdJunkNotJunkUseOk() { return fStdJunkNotJunkUseOk; }

  // if we get a PREAUTH greeting from the server, initialize the parser to
  // begin in the kAuthenticated state
  void PreauthSetAuthenticatedState();

  // these functions represent the state of the currently selected
  // folder
  bool CurrentFolderReadOnly();
  int32_t NumberOfMessages();
  int32_t NumberOfRecentMessages();
  int32_t FolderUID();
  uint32_t CurrentResponseUID();
  uint32_t HighestRecordedUID();
  void ResetHighestRecordedUID();
  void SetCurrentResponseUID(uint32_t uid);
  bool IsNumericString(const char* string);
  uint32_t SizeOfMostRecentMessage();
  void SetTotalDownloadSize(int32_t newSize) { fTotalDownloadSize = newSize; }

  nsImapSearchResultIterator* CreateSearchResultIterator();
  void ResetSearchResultSequence() { fSearchResults->ResetSequence(); }

  // create a struct mailbox_spec from our info, used in
  // libmsg c interface
  already_AddRefed<nsImapMailboxSpec> CreateCurrentMailboxSpec(
      const char* mailboxName = nullptr);

  // Resets the flags state.
  void ResetFlagInfo();

  // set this to false if you don't want to alert the user to server
  // error messages
  void SetReportingErrors(bool reportThem) { fReportingErrors = reportThem; }
  bool GetReportingErrors() { return fReportingErrors; }

  eIMAPCapabilityFlags GetCapabilityFlag() { return fCapabilityFlag; }
  void SetCapabilityFlag(eIMAPCapabilityFlags capability) {
    fCapabilityFlag = capability;
  }
  bool ServerHasIMAP4Rev1Capability() {
    return ((fCapabilityFlag & kIMAP4rev1Capability) != 0);
  }
  bool ServerHasACLCapability() {
    return ((fCapabilityFlag & kACLCapability) != 0);
  }
  bool ServerHasNamespaceCapability() {
    return ((fCapabilityFlag & kNamespaceCapability) != 0);
  }
  bool ServerIsNetscape3xServer() { return fServerIsNetscape3xServer; }
  bool ServerHasServerInfo() {
    return ((fCapabilityFlag & kXServerInfoCapability) != 0);
  }
  bool ServerIsAOLServer() {
    return ((fCapabilityFlag & kAOLImapCapability) != 0);
  }
  void SetFetchingFlags(bool aFetchFlags) { fFetchingAllFlags = aFetchFlags; }
  void ResetCapabilityFlag();

  nsCString& GetMailAccountUrl() { return fMailAccountUrl; }
  const char* GetXSenderInfo() { return fXSenderInfo; }
  void FreeXSenderInfo() { PR_FREEIF(fXSenderInfo); }
  nsCString& GetManageListsUrl() { return fManageListsUrl; }
  nsCString& GetManageFiltersUrl() { return fManageFiltersUrl; }
  const char* GetManageFolderUrl() { return fFolderAdminUrl; }
  nsCString& GetServerID() { return fServerIdResponse; }

  // Call this when adding a pipelined command to the session
  void IncrementNumberOfTaggedResponsesExpected(const char* newExpectedTag);

  // Interrupt a Fetch, without really Interrupting (through netlib)
  bool GetLastFetchChunkReceived();
  void ClearLastFetchChunkReceived();
  int32_t GetNumBytesFetched();
  void ClearNumBytesFetched();
  virtual uint16_t SupportsUserFlags() { return fSupportsUserDefinedFlags; }
  virtual uint16_t SettablePermanentFlags() { return fSettablePermanentFlags; }
  void SetFlagState(nsIImapFlagAndUidState* state);
  bool GetDownloadingHeaders();
  void SetHostSessionList(nsIImapHostSessionList* aHostSession);
  char* fAuthChallenge;  // the challenge returned by the server in
                         // response to authenticate using CRAM-MD5 or NTLM
  bool fUtf8AcceptEnabled;
  bool fUseModSeq;  // can use mod seq for currently selected folder
  uint64_t fHighestModSeq;

 protected:
  virtual void flags();
  virtual void envelope_data();
  virtual void xaolenvelope_data();
  virtual void parse_address(nsAutoCString& addressLine);
  virtual void internal_date();
  virtual nsresult BeginMessageDownload(const char* content_type);

  virtual void response_data();
  virtual void resp_text();
  virtual void resp_cond_state(bool isTagged);
  virtual void text_mime2();
  virtual void text();
  virtual void parse_folder_flags(bool calledForFlags);
  virtual void enable_data();
  virtual void language_data();
  virtual void authChallengeResponse_data();
  virtual void resp_text_code();
  virtual void response_done();
  virtual void response_tagged();
  virtual void response_fatal();
  virtual void resp_cond_bye();
  virtual void id_data();
  virtual void mailbox_data();
  virtual void numeric_mailbox_data();
  virtual void capability_data();
  virtual void xserverinfo_data();
  virtual void xmailboxinfo_data();
  virtual void namespace_data();
  virtual void myrights_data(bool unsolicited);
  virtual void acl_data();
  virtual void mime_part_data();
  virtual void quota_data();
  virtual void msg_fetch();
  virtual void msg_obsolete();
  virtual void msg_fetch_headers(const char* partNum);
  virtual void msg_fetch_content(bool chunk, int32_t origin,
                                 const char* content_type);
  virtual bool msg_fetch_quoted();
  virtual bool msg_fetch_literal(bool chunk, int32_t origin);
  virtual void mailbox_list(bool discoveredFromLsub);
  virtual void mailbox(nsImapMailboxSpec* boxSpec);

  virtual void ProcessOkCommand(const char* commandToken);
  virtual void ProcessBadCommand(const char* commandToken);
  virtual void PreProcessCommandToken(const char* commandToken,
                                      const char* currentCommand);
  virtual void PostProcessEndOfLine();

  // Overridden from the nsImapGenericParser, to retrieve the next line
  // from the open socket.
  virtual bool GetNextLineForParser(char** nextLine) override;
  // overridden to do logging
  virtual void SetSyntaxError(bool error, const char* msg = nullptr) override;

 private:
  bool fCurrentCommandFailed;
  bool fUntaggedResponse;
  bool fReportingErrors;

  bool fCurrentFolderReadOnly;
  bool fCurrentLineContainedFlagInfo;
  bool fFetchingAllFlags;
  bool fWaitingForMoreClientInput;
  // Is the server a Netscape 3.x Messaging Server?
  bool fServerIsNetscape3xServer;
  bool fDownloadingHeaders;
  bool fCurrentCommandIsSingleMessageFetch;
  bool fGotPermanentFlags;
  bool fStdJunkNotJunkUseOk;
  imapMessageFlagsType fSavedFlagInfo;
  nsTArray<nsCString> fCustomFlags;

  uint16_t fSupportsUserDefinedFlags;
  uint16_t fSettablePermanentFlags;

  int32_t fFolderUIDValidity;
  int32_t fSeqNumOfFirstUnseenMsg;
  int32_t fNumberOfExistingMessages;
  int32_t fNumberOfRecentMessages;
  uint32_t fCurrentResponseUID;
  uint32_t fHighestRecordedUID;
  // used to handle server that sends msg size after headers
  uint32_t fReceivedHeaderOrSizeForUID;
  int32_t fSizeOfMostRecentMessage;
  int32_t fTotalDownloadSize;

  int32_t fStatusUnseenMessages;
  int32_t fStatusRecentMessages;
  uint32_t fStatusNextUID;
  int32_t fStatusExistingMessages;
  uint32_t fNextUID;

  int fNumberOfTaggedResponsesExpected;

  char* fCurrentCommandTag;

  nsCString fZeroLengthMessageUidString;

  char* fSelectedMailboxName;

  nsImapSearchResultSequence* fSearchResults;

  nsCOMPtr<nsIImapFlagAndUidState>
      fFlagState;  // NOT owned by us, it's a copy, do not destroy

  eIMAPstate fIMAPstate;

  eIMAPCapabilityFlags fCapabilityFlag;
  nsCString fMailAccountUrl;
  char* fNetscapeServerVersionString;
  char* fXSenderInfo; /* changed per message download */
  char* fLastAlert; /* used to avoid displaying the same alert over and over */
  char* fMsgID;     /* MessageID for Gmail only (X-GM-MSGID) */
  char* fThreadID;  /* ThreadID for Gmail only (X-GM-THRID) */
  char* fLabels;    /* Labels for Gmail only (X-GM-LABELS) [will include parens,
                       removed while passing to hashTable ]*/
  nsCString fManageListsUrl;
  nsCString fManageFiltersUrl;
  char* fFolderAdminUrl;
  nsCString fServerIdResponse;  // RFC

  int32_t fFetchResponseIndex;

  // used for aborting a fetch stream when we're pseudo-Interrupted
  int32_t numberOfCharsInThisChunk;
  int32_t charsReadSoFar;
  bool fLastChunk;

  // Flags split of \r and \n between chunks in msg_fetch_literal().
  bool fNextChunkStartsWithNewline;

  // The connection object
  nsImapProtocol& fServerConnection;

  RefPtr<nsIImapHostSessionList> fHostSessionList;
  nsTArray<nsMsgKey> fCopyResponseKeyArray;
};

#endif