mailnews/imap/src/nsImapServerResponseParser.h
author Rob Lemley <rob@thunderbird.net>
Mon, 27 Apr 2020 19:51:09 -0400
changeset 38064 39e1d01fb0c37b7f70bc92d58a9a06f8148e6981
parent 37108 61106214bab978442d9db6b0d4d3a3e8969bf387
child 38590 9c08c80ec341936cd58f8a8fbdf01a59bec5fd17
permissions -rw-r--r--
Bug 1577518 - Update libgcrypt to version 1.8.5. r=kaie

/* -*- 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 "nsIIMAPHostSessionList.h"
#include "nsImapSearchResults.h"
#include "nsString.h"
#include "MailNewsTypes.h"
#include "nsTArray.h"
#include "nsImapUtils.h"

class nsIMAPBodyShell;
class nsIMAPBodypart;
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);

  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 NumberOfUnseenMessages();
  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();
  virtual uint16_t SupportsUserFlags() { return fSupportsUserDefinedFlags; }
  virtual uint16_t SettablePermanentFlags() { return fSettablePermanentFlags; }
  void SetFlagState(nsIImapFlagAndUidState *state);
  bool GetDownloadingHeaders();
  bool GetFillingInShell();
  void UseCachedShell(nsIMAPBodyShell *cachedShell);
  void SetHostSessionList(nsIImapHostSessionList *aHostSession);
  char *fAuthChallenge;  // the challenge returned by the server in
                         // response to authenticate using CRAM-MD5 or NTLM
  bool fCondStoreEnabled;
  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 bodystructure_data();
  nsIMAPBodypart *bodystructure_part(char *partNum, nsIMAPBodypart *parentPart);
  nsIMAPBodypart *bodystructure_leaf(char *partNum, nsIMAPBodypart *parentPart);
  nsIMAPBodypart *bodystructure_multipart(char *partNum,
                                          nsIMAPBodypart *parentPart);
  virtual void mime_data();
  virtual void mime_part_data();
  virtual void mime_header_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 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 fNumberOfUnseenMessages;
  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;
  uint32_t fStatusExistingMessages;

  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;

  // points to the current body shell, if any
  RefPtr<nsIMAPBodyShell> m_shell;

  // The connection object
  nsImapProtocol &fServerConnection;

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

#endif