Back to index

lightning-sunbird  0.9+nobinonly
Public Types | Public Member Functions | Public Attributes | Protected Member Functions | Protected Attributes | Private Attributes
nsImapServerResponseParser Class Reference

#include <nsImapServerResponseParser.h>

Inheritance diagram for nsImapServerResponseParser:
Inheritance graph
[legend]
Collaboration diagram for nsImapServerResponseParser:
Collaboration graph
[legend]

List of all members.

Public Types

enum  eIMAPstate { kNonAuthenticated, kAuthenticated, kFolderSelected }

Public Member Functions

 nsImapServerResponseParser (nsImapProtocol &imapConnection)
virtual ~nsImapServerResponseParser ()
virtual PRBool LastCommandSuccessful ()
virtual void HandleMemoryFailure ()
virtual void ParseIMAPServerResponse (const char *currentCommand, PRBool aIgnoreBadAndNOResponses)
virtual void InitializeState ()
PRBool CommandFailed ()
virtual eIMAPstate GetIMAPstate ()
virtual PRBool WaitingForMoreClientInput ()
const char * GetSelectedMailboxName ()
void PreauthSetAuthenticatedState ()
PRBool CurrentFolderReadOnly ()
PRInt32 NumberOfMessages ()
PRInt32 NumberOfRecentMessages ()
PRInt32 NumberOfUnseenMessages ()
PRInt32 FolderUID ()
PRUint32 CurrentResponseUID ()
PRUint32 HighestRecordedUID ()
void SetCurrentResponseUID (PRUint32 uid)
PRBool IsNumericString (const char *string)
PRInt32 SizeOfMostRecentMessage ()
void SetTotalDownloadSize (PRInt32 newSize)
void SetFetchingEverythingRFC822 (PRBool fetchingEverythingRFC822)
nsImapSearchResultIteratorCreateSearchResultIterator ()
void ResetSearchResultSequence ()
nsImapMailboxSpecCreateCurrentMailboxSpec (const char *mailboxName=nsnull)
void ResetFlagInfo (int numberOfInterestingMessages)
void SetReportingErrors (PRBool reportThem)
PRBool GetReportingErrors ()
PRUint32 GetCapabilityFlag ()
void SetCapabilityFlag (PRUint32 capability)
PRBool ServerHasIMAP4Rev1Capability ()
PRBool ServerHasACLCapability ()
PRBool ServerHasNamespaceCapability ()
PRBool ServerIsNetscape3xServer ()
PRBool ServerHasServerInfo ()
PRBool ServerIsAOLServer ()
void SetFetchingFlags (PRBool aFetchFlags)
void ResetCapabilityFlag ()
const char * GetMailAccountUrl ()
const char * GetXSenderInfo ()
void FreeXSenderInfo ()
const char * GetManageListsUrl ()
const char * GetManageFiltersUrl ()
const char * GetManageFolderUrl ()
void IncrementNumberOfTaggedResponsesExpected (const char *newExpectedTag)
PRBool GetLastFetchChunkReceived ()
void ClearLastFetchChunkReceived ()
virtual PRUint16 SupportsUserFlags ()
virtual PRUint16 SettablePermanentFlags ()
void SetFlagState (nsIImapFlagAndUidState *state)
PRBool GetDownloadingHeaders ()
PRBool GetFillingInShell ()
void UseCachedShell (nsIMAPBodyShell *cachedShell)
void SetHostSessionList (nsIImapHostSessionList *aHostSession)
nsIImapHostSessionListGetHostSessionList ()
PRBool SyntaxError ()
PRBool ContinueParse ()
PRBool Connected ()
void SetConnected (PRBool error)

Public Attributes

char * fAuthChallenge

Protected Member Functions

virtual void flags ()
virtual void envelope_data ()
virtual void xaolenvelope_data ()
virtual void parse_address (nsCAutoString &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 ()
virtual void text_mime2 ()
virtual void text ()
virtual void parse_folder_flags ()
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 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 ()
virtual void acl_data ()
virtual void bodystructure_data ()
nsIMAPBodypartbodystructure_part (char *partNum, nsIMAPBodypart *parentPart)
nsIMAPBodypartbodystructure_leaf (char *partNum, nsIMAPBodypart *parentPart)
nsIMAPBodypartbodystructure_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 (PRBool chunk, PRInt32 origin, const char *content_type)
virtual PRBool msg_fetch_quoted (PRBool chunk, PRInt32 origin)
virtual PRBool msg_fetch_literal (PRBool chunk, PRInt32 origin)
virtual void mailbox_list (PRBool 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 ()
virtual PRBool GetNextLineForParser (char **nextLine)
virtual void SetSyntaxError (PRBool error, const char *msg=nsnull)
void skip_to_CRLF ()
void skip_to_close_paren ()
char * CreateString ()
char * CreateAstring ()
char * CreateNilString ()
char * CreateLiteral ()
char * CreateAtom (PRBool isAstring=PR_FALSE)
char * CreateQuoted (PRBool skipToEnd=PR_TRUE)
char * CreateParenGroup ()
void AdvanceToNextToken ()
void AdvanceToNextLine ()
void AdvanceTokenizerStartingPoint (int32 bytesToAdvance)
void ResetLexAnalyzer ()

Protected Attributes

char * fNextToken
char * fCurrentLine
char * fLineOfTokens
char * fStartOfLineOfTokens
char * fCurrentTokenPlaceHolder
PRBool fAtEndOfLine

Private Attributes

PRPackedBool fProcessingTaggedResponse
PRPackedBool fCurrentCommandFailed
PRPackedBool fReportingErrors
PRPackedBool fCurrentFolderReadOnly
PRPackedBool fCurrentLineContainedFlagInfo
PRPackedBool fFetchingAllFlags
PRPackedBool fWaitingForMoreClientInput
PRPackedBool fFetchEverythingRFC822
PRPackedBool fServerIsNetscape3xServer
PRPackedBool fDownloadingHeaders
PRPackedBool fCurrentCommandIsSingleMessageFetch
PRPackedBool fGotPermanentFlags
imapMessageFlagsType fSavedFlagInfo
nsCStringArray fCustomFlags
PRUint16 fSupportsUserDefinedFlags
PRUint16 fSettablePermanentFlags
PRInt32 fFolderUIDValidity
PRInt32 fNumberOfUnseenMessages
PRInt32 fNumberOfExistingMessages
PRInt32 fNumberOfRecentMessages
PRUint32 fCurrentResponseUID
PRUint32 fHighestRecordedUID
PRUint32 fReceivedHeaderOrSizeForUID
PRInt32 fSizeOfMostRecentMessage
PRInt32 fTotalDownloadSize
PRInt32 fStatusUnseenMessages
PRInt32 fStatusRecentMessages
PRUint32 fStatusNextUID
PRUint32 fStatusExistingMessages
int fNumberOfTaggedResponsesExpected
char * fCurrentCommandTag
nsCString fZeroLengthMessageUidString
char * fSelectedMailboxName
nsImapSearchResultSequencefSearchResults
nsCOMPtr< nsIImapFlagAndUidStatefFlagState
eIMAPstate fIMAPstate
PRUint32 fCapabilityFlag
char * fMailAccountUrl
char * fNetscapeServerVersionString
char * fXSenderInfo
char * fLastAlert
char * fManageListsUrl
char * fManageFiltersUrl
char * fFolderAdminUrl
PRInt32 fUidOfSingleMessageFetch
PRInt32 fFetchResponseIndex
PRInt32 numberOfCharsInThisChunk
PRInt32 charsReadSoFar
PRBool fLastChunk
nsIMAPBodyShellm_shell
nsImapProtocolfServerConnection
nsIImapHostSessionListfHostSessionList
nsMsgKeyArray fCopyResponseKeyArray

Detailed Description

Definition at line 58 of file nsImapServerResponseParser.h.


Member Enumeration Documentation

Enumerator:
kNonAuthenticated 
kAuthenticated 
kFolderSelected 

Definition at line 75 of file nsImapServerResponseParser.h.


Constructor & Destructor Documentation


Member Function Documentation

void nsImapServerResponseParser::acl_data ( ) [protected, virtual]

Definition at line 2438 of file nsImapServerResponseParser.cpp.

{
  AdvanceToNextToken();
  if (ContinueParse() && !fAtEndOfLine)
  {
    char *mailboxName = CreateAstring();  // PL_strdup(fNextToken);
    if (mailboxName && ContinueParse())
    {
      AdvanceToNextToken();
      while (ContinueParse() && !fAtEndOfLine)
      {
        char *userName = CreateAstring(); // PL_strdup(fNextToken);
        if (userName && ContinueParse())
        {
          AdvanceToNextToken();
          if (ContinueParse())
          {
            char *rights = CreateAstring(); // PL_strdup(fNextToken);
            if (rights)
            {
              fServerConnection.AddFolderRightsForUser(mailboxName, userName, rights);
              PR_Free(rights);
            }
            else
              HandleMemoryFailure();
            
            if (ContinueParse())
              AdvanceToNextToken();
          }
          PR_Free(userName);
        }
        else
          HandleMemoryFailure();
      }
      PR_Free(mailboxName);
    }
    else
      HandleMemoryFailure();
  }
}

Here is the call graph for this function:

Here is the caller graph for this function:

void nsIMAPGenericParser::AdvanceTokenizerStartingPoint ( int32  bytesToAdvance) [protected, inherited]

Definition at line 211 of file nsIMAPGenericParser.cpp.

{
  NS_PRECONDITION(bytesToAdvance>=0, "bytesToAdvance must not be negative");
  if (!fStartOfLineOfTokens)
  {
    AdvanceToNextToken();  // the tokenizer was not yet initialized, do it now
    if (!fStartOfLineOfTokens)
      return;
  }
    
  if(!fStartOfLineOfTokens)
      return;
  // The last call to AdvanceToNextToken() cleared the token separator to '\0'
  // iff |fCurrentTokenPlaceHolder|.  We must recover this token separator now.
  if (fCurrentTokenPlaceHolder)
  {
    int endTokenOffset = fCurrentTokenPlaceHolder - fStartOfLineOfTokens - 1;
    if (endTokenOffset >= 0)
      fStartOfLineOfTokens[endTokenOffset] = fCurrentLine[endTokenOffset];
  }

  NS_ASSERTION(bytesToAdvance + (fLineOfTokens-fStartOfLineOfTokens) <=
    (int32)strlen(fCurrentLine), "cannot advance beyond end of fLineOfTokens");
  fLineOfTokens += bytesToAdvance;
  fCurrentTokenPlaceHolder = fLineOfTokens;
}

Here is the call graph for this function:

Here is the caller graph for this function:

void nsIMAPGenericParser::AdvanceToNextLine ( ) [protected, inherited]

Definition at line 177 of file nsIMAPGenericParser.cpp.

{
  PR_FREEIF( fCurrentLine );
  PR_FREEIF( fStartOfLineOfTokens);
  
  PRBool ok = GetNextLineForParser(&fCurrentLine);
  if (!ok)
  {
    SetConnected(PR_FALSE);
    fStartOfLineOfTokens = nsnull;
    fLineOfTokens = nsnull;
    fCurrentTokenPlaceHolder = nsnull;
    fAtEndOfLine = PR_TRUE;
    fNextToken = CRLF;
  }
  else if (!fCurrentLine)
  {
    HandleMemoryFailure();
  }
  else
  {
     fNextToken = nsnull;
     // determine if there are any tokens (without calling AdvanceToNextToken);
     // otherwise we are already at end of line
     NS_ASSERTION(strlen(WHITESPACE) == 3, "assume 3 chars of whitespace");
     char *firstToken = fCurrentLine;
     while (*firstToken && (*firstToken == WHITESPACE[0] ||
            *firstToken == WHITESPACE[1] || *firstToken == WHITESPACE[2]))
       firstToken++;
     fAtEndOfLine = (*firstToken == '\0');
  }
}

Here is the call graph for this function:

Here is the caller graph for this function:

void nsIMAPGenericParser::AdvanceToNextToken ( ) [protected, inherited]

Definition at line 150 of file nsIMAPGenericParser.cpp.

Here is the call graph for this function:

Definition at line 2277 of file nsImapServerResponseParser.cpp.

Here is the call graph for this function:

Here is the caller graph for this function:

nsresult nsImapServerResponseParser::BeginMessageDownload ( const char *  content_type) [protected, virtual]

Definition at line 3205 of file nsImapServerResponseParser.cpp.

{
  // if we're downloading a message, assert that we know its size.
  NS_ASSERTION(fDownloadingHeaders || fSizeOfMostRecentMessage > 0, "most recent message has 0 or negative size");
  nsresult rv = fServerConnection.BeginMessageDownLoad(fSizeOfMostRecentMessage, 
    content_type);
  if (NS_FAILED(rv))
  {
    skip_to_CRLF();
    fServerConnection.PseudoInterrupt(PR_TRUE);
    fServerConnection.AbortMessageDownLoad();
  }
  return rv;
}

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 2559 of file nsImapServerResponseParser.cpp.

{
  AdvanceToNextToken();
  if (ContinueParse() && fNextToken && *fNextToken == '(')  // It has to start with an open paren.
  {
    // Turn the BODYSTRUCTURE response into a form that the nsIMAPBodypartMessage can be constructed from.
    nsIMAPBodypartMessage *message = new nsIMAPBodypartMessage(NULL, NULL, PR_TRUE,
                                                               nsCRT::strdup("message"), nsCRT::strdup("rfc822"),
                                                               NULL, NULL, NULL, 0);
    nsIMAPBodypart *body = bodystructure_part(PL_strdup("1"), message);
    if (body)
      message->SetBody(body);
    else
    {
      delete message;
      message = nsnull;
    }
    m_shell = new nsIMAPBodyShell(&fServerConnection, message, CurrentResponseUID(), GetSelectedMailboxName());
    // ignore syntax errors in parsing the body structure response. If there's an error
    // we'll just fall back to fetching the whole message.
    SetSyntaxError(PR_FALSE);
  }
  else
    SetSyntaxError(PR_TRUE);
}

Here is the call graph for this function:

Here is the caller graph for this function:

nsIMAPBodypart * nsImapServerResponseParser::bodystructure_leaf ( char *  partNum,
nsIMAPBodypart parentPart 
) [protected]

Definition at line 2606 of file nsImapServerResponseParser.cpp.

{
  // historical note: this code was originally in nsIMAPBodypartLeaf::ParseIntoObjects()
  char *bodyType = nsnull, *bodySubType = nsnull, *bodyID = nsnull, *bodyDescription = nsnull, *bodyEncoding = nsnull;
  PRInt32 partLength = 0;
  PRBool isValid = PR_TRUE;
  
  // body type  ("application", "text", "image", etc.)
  if (ContinueParse())
  {
    fNextToken++; // eat the first '('
    bodyType = CreateNilString();
    if (ContinueParse())
      AdvanceToNextToken();
  }
  
  // body subtype  ("gif", "html", etc.)
  if (isValid && ContinueParse())
  {
    bodySubType = CreateNilString();
    if (ContinueParse())
      AdvanceToNextToken();
  }
  
  // body parameter: parenthesized list
  if (isValid && ContinueParse())
  {
    if (fNextToken[0] == '(')
    {
      fNextToken++;
      skip_to_close_paren();
    }
    else if (!PL_strcasecmp(fNextToken, "NIL"))
      AdvanceToNextToken();
  }
  
  // body id
  if (isValid && ContinueParse())
  {
    bodyID = CreateNilString();
    if (ContinueParse())
      AdvanceToNextToken();
  }
  
  // body description
  if (isValid && ContinueParse())
  {
    bodyDescription = CreateNilString();
    if (ContinueParse())
      AdvanceToNextToken();
  }
  
  // body encoding
  if (isValid && ContinueParse())
  {
    bodyEncoding = CreateNilString();
    if (ContinueParse())
      AdvanceToNextToken();
  }
  
  // body size
  if (isValid && ContinueParse())
  {
    char *bodySizeString = CreateAtom();
    if (!bodySizeString)
      isValid = PR_FALSE;
    else
    {
      partLength = atoi(bodySizeString);
      PR_Free(bodySizeString);
      if (ContinueParse())
        AdvanceToNextToken();
    }
  }

  if (!isValid || !ContinueParse())
  {
    PR_FREEIF(partNum);
    PR_FREEIF(bodyType);
    PR_FREEIF(bodySubType);
    PR_FREEIF(bodyID);
    PR_FREEIF(bodyDescription);
    PR_FREEIF(bodyEncoding);
  }
  else
  {
    if (PL_strcasecmp(bodyType, "message") || PL_strcasecmp(bodySubType, "rfc822"))
    {
      skip_to_close_paren();
      return new nsIMAPBodypartLeaf(partNum, parentPart, bodyType, bodySubType,
          bodyID, bodyDescription, bodyEncoding, partLength);
    }
    
    // This part is of type "message/rfc822"  (probably a forwarded message)
    nsIMAPBodypartMessage *message = new nsIMAPBodypartMessage(partNum, parentPart, PR_FALSE,
      bodyType, bodySubType, bodyID, bodyDescription, bodyEncoding, partLength);

    // there are three additional fields: envelope structure, bodystructure, and size in lines    
    // historical note: this code was originally in nsIMAPBodypartMessage::ParseIntoObjects()

    // envelope (ignored)
    if (*fNextToken == '(')
    {
      fNextToken++;
      skip_to_close_paren();
    }
    else
      isValid = PR_FALSE;

    // bodystructure
    if (isValid && ContinueParse())
    {
      if (*fNextToken != '(')
        isValid = PR_FALSE;
      else
      {
        char *bodyPartNum = PR_smprintf("%s.1", partNum);
        if (bodyPartNum)
        {
          nsIMAPBodypart *body = bodystructure_part(bodyPartNum, message);
          if (body)
            message->SetBody(body);
          else
            isValid = PR_FALSE;
        }
      }
    }
    
    // ignore "size in text lines"

    if (isValid && ContinueParse()) {
      skip_to_close_paren();
      return message;
    }
    delete message;
  }

  // parsing failed, just move to the end of the parentheses group
  if (ContinueParse())
    skip_to_close_paren();
  return nsnull;
}

Here is the call graph for this function:

Here is the caller graph for this function:

nsIMAPBodypart * nsImapServerResponseParser::bodystructure_multipart ( char *  partNum,
nsIMAPBodypart parentPart 
) [protected]

Definition at line 2753 of file nsImapServerResponseParser.cpp.

{
  nsIMAPBodypartMultipart *multipart = new nsIMAPBodypartMultipart(partNum, parentPart);
  PRBool isValid = multipart->GetIsValid();
  // historical note: this code was originally in nsIMAPBodypartMultipart::ParseIntoObjects()
  if (ContinueParse())
  {
    fNextToken++; // eat the first '('
    // Parse list of children
    int childCount = 0;
    while (isValid && fNextToken[0] == '(' && ContinueParse())
    {
      childCount++;
      char *childPartNum = NULL;
      // note: the multipart constructor does some magic on partNumber
      if (PL_strcmp(multipart->GetPartNumberString(), "0")) // not top-level
        childPartNum = PR_smprintf("%s.%d", multipart->GetPartNumberString(), childCount);
      else // top-level
        childPartNum = PR_smprintf("%d", childCount);
      if (!childPartNum)
        isValid = PR_FALSE;
      else
      {
        nsIMAPBodypart *child = bodystructure_part(childPartNum, multipart);
        if (child)
          multipart->AppendPart(child);
        else
          isValid = PR_FALSE;
      }
    }

    // RFC3501:  media-subtype   = string
    // (multipart subtype: mixed, alternative, etc.)
    if (isValid && ContinueParse())
    {
      char *bodySubType = CreateNilString();
      multipart->SetBodySubType(bodySubType);
      if (ContinueParse())
        AdvanceToNextToken();
    }

    // extension data:
    // RFC3501:  body-ext-mpart = body-fld-param [SP body-fld-dsp [SP body-fld-lang
    //                            [SP body-fld-loc *(SP body-extension)]]]
    
    // body parameter parenthesized list (optional data), includes boundary parameter
    // RFC3501:  body-fld-param  = "(" string SP string *(SP string SP string) ")" / nil
    char *boundaryData = nsnull;
    if (isValid && ContinueParse() && *fNextToken == '(')
    {
      fNextToken++;
      while (ContinueParse() && *fNextToken != ')')
      {
        char *attribute = CreateNilString();
        if (ContinueParse())
          AdvanceToNextToken();
        if (ContinueParse() && !PL_strcasecmp(attribute, "BOUNDARY"))
        {
          char *boundary = CreateNilString();
          if (boundary)
            boundaryData = PR_smprintf("--%s", boundary);
          PR_FREEIF(boundary);
        }
        else if (ContinueParse())
        {
          char *value = CreateNilString();
          PR_FREEIF(value);
        }
        PR_FREEIF(attribute);
        if (ContinueParse())
          AdvanceToNextToken();
      }
      if (ContinueParse())
        fNextToken++;  // skip closing ')'
    }
    if (boundaryData)
      multipart->SetBoundaryData(boundaryData);
    else  
      isValid = PR_FALSE;   // Actually, we should probably generate a boundary here.
  }

  // always move to closing ')', even if part was not successfully read 
  if (ContinueParse())
    skip_to_close_paren();

  if (isValid)
    return multipart;
  delete multipart;
  return nsnull;
}

Here is the call graph for this function:

Here is the caller graph for this function:

nsIMAPBodypart * nsImapServerResponseParser::bodystructure_part ( char *  partNum,
nsIMAPBodypart parentPart 
) [protected]

Definition at line 2587 of file nsImapServerResponseParser.cpp.

{
  // Check to see if this buffer is a leaf or container
  // (Look at second character - if an open paren, then it is a container)
  if (*fNextToken != '(')
  {
    NS_ASSERTION(PR_FALSE, "bodystructure_part must begin with '('");
    return NULL;
  }
  
  if (fNextToken[1] == '(')
    return bodystructure_multipart(partNum, parentPart);
  else
    return bodystructure_leaf(partNum, parentPart);
}

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 2134 of file nsImapServerResponseParser.cpp.

{
  fCapabilityFlag = kCapabilityDefined;
  do {
    AdvanceToNextToken();
    // for now we only care about AUTH=LOGIN
    if (fNextToken) {
      if(! PL_strcasecmp(fNextToken, "AUTH=LOGIN"))
        fCapabilityFlag |= kHasAuthLoginCapability;
      else if (! PL_strcasecmp(fNextToken, "AUTH=PLAIN"))
        fCapabilityFlag |= kHasAuthPlainCapability;
      else if (! PL_strcasecmp(fNextToken, "AUTH=CRAM-MD5"))
        fCapabilityFlag |= kHasCRAMCapability;
      else if (! PL_strcasecmp(fNextToken, "AUTH=NTLM"))
        fCapabilityFlag |= kHasAuthNTLMCapability;
      else if (! PL_strcasecmp(fNextToken, "AUTH=GSSAPI"))
        fCapabilityFlag |= kHasAuthGssApiCapability;
      else if (! PL_strcasecmp(fNextToken, "AUTH=MSN"))
        fCapabilityFlag |= kHasAuthMSNCapability;
      else if (! PL_strcasecmp(fNextToken, "STARTTLS"))
        fCapabilityFlag |= kHasStartTLSCapability;
      else if (! PL_strcasecmp(fNextToken, "LOGINDISABLED"))
        fCapabilityFlag |= kLoginDisabled;
      else if (! PL_strcasecmp(fNextToken, "X-NETSCAPE"))
        fCapabilityFlag |= kHasXNetscapeCapability;
      else if (! PL_strcasecmp(fNextToken, "XSENDER"))
        fCapabilityFlag |= kHasXSenderCapability;
      else if (! PL_strcasecmp(fNextToken, "IMAP4"))
        fCapabilityFlag |= kIMAP4Capability;
      else if (! PL_strcasecmp(fNextToken, "IMAP4rev1"))
        fCapabilityFlag |= kIMAP4rev1Capability;
      else if (! PL_strncasecmp(fNextToken, "IMAP4", 5))
        fCapabilityFlag |= kIMAP4other;
      else if (! PL_strcasecmp(fNextToken, "X-NO-ATOMIC-RENAME"))
        fCapabilityFlag |= kNoHierarchyRename;
      else if (! PL_strcasecmp(fNextToken, "X-NON-HIERARCHICAL-RENAME"))
        fCapabilityFlag |= kNoHierarchyRename;
      else if (! PL_strcasecmp(fNextToken, "NAMESPACE"))
        fCapabilityFlag |= kNamespaceCapability;
      else if (! PL_strcasecmp(fNextToken, "MAILBOXDATA"))
        fCapabilityFlag |= kMailboxDataCapability;
      else if (! PL_strcasecmp(fNextToken, "ACL"))
        fCapabilityFlag |= kACLCapability;
      else if (! PL_strcasecmp(fNextToken, "XSERVERINFO"))
        fCapabilityFlag |= kXServerInfoCapability;
      else if (! PL_strcasecmp(fNextToken, "UIDPLUS"))
        fCapabilityFlag |= kUidplusCapability;
      else if (! PL_strcasecmp(fNextToken, "LITERAL+"))
        fCapabilityFlag |= kLiteralPlusCapability;
      else if (! PL_strcasecmp(fNextToken, "XAOL-OPTION"))
        fCapabilityFlag |= kAOLImapCapability;
      else if (! PL_strcasecmp(fNextToken, "QUOTA"))
        fCapabilityFlag |= kQuotaCapability;
      else if (! PL_strcasecmp(fNextToken, "LANGUAGE"))
        fCapabilityFlag |= kHasLanguageCapability;
      else if (! PL_strcasecmp(fNextToken, "IDLE"))
        fCapabilityFlag |= kHasIdleCapability;
    }
  } while (fNextToken && 
                      !fAtEndOfLine &&
                         ContinueParse());
  
  if (fHostSessionList)
    fHostSessionList->SetCapabilityForHost(
    fServerConnection.GetImapServerKey(), 
    fCapabilityFlag);
  nsImapProtocol *navCon = &fServerConnection;
  NS_ASSERTION(navCon, "null imap protocol connection while parsing capability response"); // we should always have this
  if (navCon)
    navCon->CommitCapability();
  skip_to_CRLF();
}

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 3161 of file nsImapServerResponseParser.cpp.

Here is the caller graph for this function:

Definition at line 141 of file nsImapServerResponseParser.cpp.

Here is the caller graph for this function:

PRBool nsIMAPGenericParser::Connected ( ) [inline, inherited]

Definition at line 62 of file nsIMAPGenericParser.h.

Here is the caller graph for this function:

PRBool nsIMAPGenericParser::ContinueParse ( ) [inline, inherited]

Definition at line 61 of file nsIMAPGenericParser.h.

{ return fParserState == stateOK; }

Here is the caller graph for this function:

char * nsIMAPGenericParser::CreateAstring ( ) [protected, inherited]

Definition at line 242 of file nsIMAPGenericParser.cpp.

{
  if (*fNextToken == '{')
    return CreateLiteral();        // literal
  else if (*fNextToken == '"')
    return CreateQuoted();         // quoted
  else
    return CreateAtom(PR_TRUE); // atom
}

Here is the call graph for this function:

Here is the caller graph for this function:

char * nsIMAPGenericParser::CreateAtom ( PRBool  isAstring = PR_FALSE) [protected, inherited]

Definition at line 264 of file nsIMAPGenericParser.cpp.

{
  char *rv = PL_strdup(fNextToken);
  if (!rv)
  {
    HandleMemoryFailure();
    return nsnull;
  }
  // We wish to stop at the following characters (in decimal ascii)
  // 1-31 (CTL), 32 (SP), 34 '"', 37 '%', 40-42 "()*", 92 '\\', 123 '{'
  // also, ']' is only allowed in astrings
  char *last = rv;
  char c = *last;
  while ((c > 42 || c == 33 || c == 35 || c == 36 || c == 38 || c == 39)
         && c != '\\' && c != '{' && (isAstring || c != ']'))
     c = *++last;
  if (rv == last) {
     SetSyntaxError(PR_TRUE, "no atom characters found");
     PL_strfree(rv);
     return nsnull;
  }
  if (*last)
  {
    // not the whole token was consumed  
    *last = '\0';
    AdvanceTokenizerStartingPoint((fNextToken - fLineOfTokens) + (last-rv));
  }
  return rv;
}

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 3089 of file nsImapServerResponseParser.cpp.

{
  nsImapMailboxSpec *returnSpec = new nsImapMailboxSpec;
  if (!returnSpec)
  {
    HandleMemoryFailure();
    return  nsnull;
  }
  NS_ADDREF(returnSpec);
  const char *mailboxNameToConvert = (mailboxName) ? mailboxName : fSelectedMailboxName;
  if (mailboxNameToConvert)
  {
    const char *serverKey = fServerConnection.GetImapServerKey();
    nsIMAPNamespace *ns = nsnull;
    if (serverKey && fHostSessionList)
      fHostSessionList->GetNamespaceForMailboxForHost(serverKey, mailboxNameToConvert, ns);       // for
      // delimiter
    returnSpec->hierarchySeparator = (ns) ? ns->GetDelimiter(): '/';
    
  }
  
  returnSpec->folderSelected = !mailboxName; // if mailboxName is null, we're doing a Status
  returnSpec->folder_UIDVALIDITY = fFolderUIDValidity;
  returnSpec->number_of_messages = (mailboxName) ? fStatusExistingMessages : fNumberOfExistingMessages;
  returnSpec->number_of_unseen_messages = (mailboxName) ? fStatusUnseenMessages : fNumberOfUnseenMessages;
  returnSpec->number_of_recent_messages = (mailboxName) ? fStatusRecentMessages : fNumberOfRecentMessages;
  
  returnSpec->supportedUserFlags = fSupportsUserDefinedFlags;

  returnSpec->box_flags = kNoFlags;       // stub
  returnSpec->onlineVerified = PR_FALSE;  // we're fabricating this.  The flags aren't verified.
  returnSpec->allocatedPathName = strdup(mailboxNameToConvert);
  returnSpec->connection = &fServerConnection;
  if (returnSpec->connection)
  {
    nsIURI * aUrl = nsnull;
    nsresult rv = NS_OK;
    returnSpec->connection->GetCurrentUrl()->QueryInterface(NS_GET_IID(nsIURI), (void **) &aUrl);
    if (NS_SUCCEEDED(rv) && aUrl) 
    {
      nsCAutoString host;
      aUrl->GetHost(host);
      returnSpec->hostName = ToNewCString(host);
    }
    NS_IF_RELEASE(aUrl);
    
  }
  else
    returnSpec->hostName = nsnull;

  if (fFlagState)
    returnSpec->flagState = fFlagState; //copies flag state
  else
    returnSpec->flagState = nsnull;
  
  return returnSpec;
  
}

Here is the call graph for this function:

Here is the caller graph for this function:

char * nsIMAPGenericParser::CreateLiteral ( ) [protected, inherited]

Definition at line 416 of file nsIMAPGenericParser.cpp.

{
  int32 numberOfCharsInMessage = atoi(fNextToken + 1);
  int32 charsReadSoFar = 0, currentLineLength = 0;
  int32 bytesToCopy = 0;
  
  uint32 numBytes = numberOfCharsInMessage + 1;
  NS_ASSERTION(numBytes, "overflow!");
  if (!numBytes)
    return nsnull;
  
  char *returnString = (char *) PR_Malloc(numBytes);
    if (!returnString)
        return nsnull;
 
    *(returnString + numberOfCharsInMessage) = 0; // Null terminate it first
    
    PRBool terminatedLine = PR_FALSE;
        if (fCurrentTokenPlaceHolder &&
          *fCurrentTokenPlaceHolder == nsCRT::LF &&
          *(fCurrentTokenPlaceHolder+1))
        {
          // This is a static buffer, with a CRLF between the literal size ({91}) and
          // the string itself
          fCurrentTokenPlaceHolder++;
        }
        else
        {
          // We have to read the next line from AdvanceToNextLine().
          terminatedLine = PR_TRUE;
        }
    while (ContinueParse() && (charsReadSoFar < numberOfCharsInMessage))
    {
      if(terminatedLine)
        AdvanceToNextLine();

      if (ContinueParse())
      {
        currentLineLength = strlen(terminatedLine ? fCurrentLine : fCurrentTokenPlaceHolder);
        bytesToCopy = (currentLineLength > numberOfCharsInMessage - charsReadSoFar ?
          numberOfCharsInMessage - charsReadSoFar : currentLineLength);
        NS_ASSERTION (bytesToCopy, "0 length literal?");
        
        memcpy(returnString + charsReadSoFar, terminatedLine ? fCurrentLine : fCurrentTokenPlaceHolder, bytesToCopy); 
        charsReadSoFar += bytesToCopy;
      }
      if (charsReadSoFar < numberOfCharsInMessage) // read the next line
          terminatedLine = PR_TRUE;
    }
    
    if (ContinueParse())
    {
      if (bytesToCopy == 0)
      {
        // the loop above was never executed, we just move to the next line
        if (terminatedLine)
          AdvanceToNextLine();
      }
      else if (currentLineLength == bytesToCopy)
      {
          // We have consumed the entire line.
          // Consider the input  "A1 {4}\r\nL2\r\n A3\r\n" which is read
          // line-by-line.  Reading 3 Astrings, this should result in 
          // "A1", "L2\r\n", and "A3".  Note that this confuses the parser, 
          // since the second line is "L2\r\n" where the "\r\n" is part of the
          // literal.  Hence, the 'full' imap line was not read in yet after the
          // second line of input (which is where we are now).  We now read the
          // next line to ensure that the next call to AdvanceToNextToken()
          // would lead to fNextToken=="A3" in our example.
          // Note that setting fAtEndOfLine=PR_TRUE is wrong here, since the "\r\n"
          // were just some characters from the literal; fAtEndOfLine would
          // give a misleading result.
          AdvanceToNextLine();
      }
      else
      {
        // Move fCurrentTokenPlaceHolder
        if (terminatedLine)
          AdvanceTokenizerStartingPoint (bytesToCopy);
        else
          AdvanceTokenizerStartingPoint ( bytesToCopy + 
          strlen(fNextToken) + 
          2 /* CRLF */ +
          (fNextToken - fLineOfTokens)
          );
      }       
    }
  
  return returnString;
}

Here is the call graph for this function:

Here is the caller graph for this function:

char * nsIMAPGenericParser::CreateNilString ( ) [protected, inherited]

Definition at line 299 of file nsIMAPGenericParser.cpp.

{
  if (!PL_strncasecmp(fNextToken, "NIL", 3))
  {
    if (strlen(fNextToken) != 3)
      fNextToken += 3;
    return NULL;
  }
  else
    return CreateString();
}

Here is the call graph for this function:

Here is the caller graph for this function:

char * nsIMAPGenericParser::CreateParenGroup ( ) [protected, inherited]

Definition at line 514 of file nsIMAPGenericParser.cpp.

{
#ifdef DEBUG_bienvenu
  NS_ASSERTION(fNextToken[0] == '(', "we don't have a paren group!");
#endif
  
  int numOpenParens = 1;
  
  // build up a buffer with the paren group.
  // start with an initial chunk, expand later if necessary
  nsCString buf;
  nsCString returnString;
  int bytesUsed = 0;
  
  // count the number of parens in the current token
  int count, tokenLen = strlen(fNextToken);
  for (count = 1; (count < tokenLen) && (numOpenParens > 0); count++)
  {
    if (fNextToken[count] == '(')
      numOpenParens++;
    else if (fNextToken[count] == ')')
      numOpenParens--;
  }
  
  if ((numOpenParens > 0) && ContinueParse())
  {
    // Copy that first token from before
    returnString =fNextToken;
    returnString.Append(" ");      // space that got stripped off the token
    
    PRBool extractReset = PR_TRUE;
    while (extractReset && ContinueParse())
    {
      extractReset = PR_FALSE;
      // Go through the current line and look for the last close paren.
      // We're not trying to parse it just yet, just separate it out.
      int len = strlen(fCurrentTokenPlaceHolder);
      for (count = 0; (count < len) && (numOpenParens > 0) && !extractReset; count++)
      {
        if (*fCurrentTokenPlaceHolder == '{')
        {
          AdvanceToNextToken();
          NS_ASSERTION(fNextToken, "out of memory?or invalid syntax");
          if (fNextToken)
          {
            tokenLen = strlen(fNextToken);
            if (fNextToken[tokenLen-1] == '}')
            {
              // ok, we're looking at a literal string here
              
              // first, flush buf
              if (bytesUsed > 0)
              {
                buf.Truncate(bytesUsed);
                returnString.Append(buf);
                buf.Truncate();
                bytesUsed = 0;
              }
              
              returnString.Append(fNextToken);   // append the {xx} to the buffer
              returnString.Append(CRLF);                // append a CRLF to the buffer
              char *lit = CreateLiteral();
              NS_ASSERTION(lit, "syntax error or out of memory");
              if (lit)
              {
                returnString.Append(lit);
                //fCurrentTokenPlaceHolder += nsCRT::strlen(lit);
                //AdvanceTokenizerStartingPoint(nsCRT::strlen(lit));
                //AdvanceToNextToken();
                extractReset = PR_TRUE;
                PR_Free(lit);
              }
            }
            else
            {
#ifdef DEBUG_bienvenu
              NS_ASSERTION(PR_FALSE, "syntax error creating paren group");   // maybe not an error, but definitely a rare condition
#endif
            }
          }
        }
        else if (*fCurrentTokenPlaceHolder == '"')
        {
          // We're looking at a quoted string here.
          // Ignore the characters within it.
          
          // first, flush buf
          if (bytesUsed > 0)
          {
            buf.Truncate(bytesUsed);
            returnString.Append(buf);
            buf.Truncate();
            bytesUsed = 0;
          }
          
          AdvanceToNextToken();
          NS_ASSERTION(fNextToken, "syntax error or out of memory creating paren group");
          if (fNextToken)
          {
            char *q = CreateQuoted();
            NS_ASSERTION(q, "syntax error or out of memory creating paren group");
            if (q)
            {
              returnString.Append("\"");
              returnString.Append(q);
              returnString.Append("\"");
              extractReset = PR_TRUE;
              PR_Free(q);
            }
          }
        }
        else if (*fCurrentTokenPlaceHolder == '(')
          numOpenParens++;
        else if (*fCurrentTokenPlaceHolder == ')')
          numOpenParens--;
        
        
        if (!extractReset)
        {
          // append this character to the buffer
          buf += *fCurrentTokenPlaceHolder;
          
          //.SetCharAt(*fCurrentTokenPlaceHolder, bytesUsed);
          bytesUsed++;
          fCurrentTokenPlaceHolder++;
        }
      }
    }
  }
  else if ((numOpenParens == 0) && ContinueParse())
  {
    // the whole paren group response was finished in a single token
    buf.Append(fNextToken);
  }
  
  
  if (numOpenParens != 0 || !ContinueParse())
  {
    SetSyntaxError(PR_TRUE, "closing ')' not found in paren group");
    returnString.SetLength(0);
  }
  else
  {
    // flush buf the final time
    if (bytesUsed > 0)
    {
      buf.Truncate(bytesUsed);
      returnString.Append(buf);
      buf.Truncate();
    }
    AdvanceToNextToken();
  }
  
  return ToNewCString(returnString);
}

Here is the call graph for this function:

Here is the caller graph for this function:

char * nsIMAPGenericParser::CreateQuoted ( PRBool  skipToEnd = PR_TRUE) [protected, inherited]

Definition at line 343 of file nsIMAPGenericParser.cpp.

{
  char *currentChar = fCurrentLine + 
    (fNextToken - fStartOfLineOfTokens)
    + 1;      // one char past opening '"'
  
  int  charIndex = 0;
  int  escapeCharsCut = 0;
  PRBool closeQuoteFound = PR_FALSE;
  nsCString returnString(currentChar);
  
  while (returnString.CharAt(charIndex))
  {
    if (returnString.CharAt(charIndex) == '"')
    {
      // don't check to see if it was escaped, 
      // that was handled in the next clause
      closeQuoteFound = PR_TRUE;
      break;
    }
    else if (returnString.CharAt(charIndex) == '\\')
    {
      // eat the escape character
      returnString.Cut(charIndex, 1);
      // whatever the escaped character was, we want it
      charIndex++;
      
      // account for charIndex not reflecting the eat of the escape character
      escapeCharsCut++;
    }
    else
      charIndex++;
  }
  
  if (closeQuoteFound)
  {
    returnString.Truncate(charIndex);
    //if ((charIndex == 0) && skipToEnd)  // it's an empty string.  Why skip to end?
    // skip_to_CRLF();
    //else if (charIndex == strlen(fCurrentLine))       // should we have this?
    //AdvanceToNextLine();
    //else 
    if (charIndex < (int) (strlen(fNextToken) - 2))     // -2 because of the start and end quotes
    {
      // the quoted string was fully contained within fNextToken,
      // and there is text after the quote in fNextToken that we
      // still need
      //                    int charDiff = strlen(fNextToken) - charIndex - 1;
      //                    fCurrentTokenPlaceHolder -= charDiff;
      //                    if (!nsCRT::strcmp(fCurrentTokenPlaceHolder, CRLF))
      //                           fAtEndOfLine = PR_TRUE;
      AdvanceTokenizerStartingPoint ((fNextToken - fLineOfTokens) + returnString.Length() + escapeCharsCut + 2);
    }
    else
    {
      fCurrentTokenPlaceHolder += escapeCharsCut + charIndex + 1 - strlen(fNextToken);
      if (!*fCurrentTokenPlaceHolder)
        *fCurrentTokenPlaceHolder = ' ';  // put the token delimiter back
                                                /*      if (!nsCRT::strcmp(fNextToken, CRLF))
                                                fAtEndOfLine = PR_TRUE;
      */
    }
  }
  else
    SetSyntaxError(PR_TRUE, "no closing '\"' found in quoted");
  
  return ToNewCString(returnString);
}

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 400 of file nsImapServerResponseParser.cpp.

Here is the caller graph for this function:

char * nsIMAPGenericParser::CreateString ( ) [protected, inherited]

Definition at line 316 of file nsIMAPGenericParser.cpp.

{
  if (*fNextToken == '{')
  {
    char *rv = CreateLiteral();           // literal
    return (rv);
  }
  else if (*fNextToken == '"')
  {
    char *rv = CreateQuoted();            // quoted
    return (rv);
  }
  else
  {
    SetSyntaxError(PR_TRUE, "string does not start with '{' or '\"'");
    return NULL;
  }
}

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 3033 of file nsImapServerResponseParser.cpp.

Definition at line 3064 of file nsImapServerResponseParser.cpp.

{
  return fCurrentResponseUID;
}

Here is the caller graph for this function:

Definition at line 1393 of file nsImapServerResponseParser.cpp.

{
  AdvanceToNextToken();
  fNextToken++; // eat '('
  for (int tableIndex = 0; tableIndex < (int)(sizeof(EnvelopeTable) / sizeof(EnvelopeTable[0])); tableIndex++)
  {
    PRBool headerNonNil = PR_TRUE;
    
    if (ContinueParse() && (*fNextToken != ')'))
    {
      nsCAutoString headerLine(EnvelopeTable[tableIndex].name);
      headerLine += ": ";
      if (EnvelopeTable[tableIndex].type == envelopeString)
      {
        nsXPIDLCString strValue;
        strValue.Adopt(CreateNilString());
        if (strValue)
        {
          headerLine.Append(strValue);
        }
        else
          headerNonNil = PR_FALSE;
      }
      else
      {
        nsCAutoString address;
        parse_address(address);
        headerLine += address;
        if (address.IsEmpty())
          headerNonNil = PR_FALSE;
      }
      if (headerNonNil)
        fServerConnection.HandleMessageDownLoadLine(headerLine.get(), PR_FALSE);
    }
    else
      break;
    // only fetch the next token if we aren't eating a parenthes
    if (ContinueParse() && (*fNextToken != ')') || tableIndex < (int)(sizeof(EnvelopeTable) / sizeof(EnvelopeTable[0])) - 1 )
      AdvanceToNextToken();
  }
  
  AdvanceToNextToken();
}

Here is the call graph for this function:

Here is the caller graph for this function:

void nsImapServerResponseParser::flags ( ) [protected, virtual]

Definition at line 1583 of file nsImapServerResponseParser.cpp.

{
  imapMessageFlagsType messageFlags = kNoImapMsgFlag;
  fCustomFlags.Clear();

  // clear the custom flags for this message
  // otherwise the old custom flags will stay around
  // see bug #191042
  if (fFlagState && CurrentResponseUID() != nsMsgKey_None)
    fFlagState->ClearCustomFlags(CurrentResponseUID());

  // eat the opening '('
  fNextToken++;
  while (ContinueParse() && (*fNextToken != ')'))
  {
    PRBool knownFlag = PR_FALSE;                                    
    if (*fNextToken == '\\')
    {
      switch (toupper(fNextToken[1])) {
      case 'S':
        if (!PL_strncasecmp(fNextToken, "\\Seen",5))
        {
          messageFlags |= kImapMsgSeenFlag;
          knownFlag = PR_TRUE;
        }
        break;
      case 'A':
        if (!PL_strncasecmp(fNextToken, "\\Answered",9))
        {
          messageFlags |= kImapMsgAnsweredFlag;
          knownFlag = PR_TRUE;
        }
        break;
      case 'F':
        if (!PL_strncasecmp(fNextToken, "\\Flagged",8))
        {
          messageFlags |= kImapMsgFlaggedFlag;
          knownFlag = PR_TRUE;
        }
        break;
      case 'D':
        if (!PL_strncasecmp(fNextToken, "\\Deleted",8))
        {
          messageFlags |= kImapMsgDeletedFlag;
          knownFlag = PR_TRUE;
        }
        else if (!PL_strncasecmp(fNextToken, "\\Draft",6))
        {
          messageFlags |= kImapMsgDraftFlag;
          knownFlag = PR_TRUE;
        }
        break;
      case 'R':
        if (!PL_strncasecmp(fNextToken, "\\Recent",7))
        {
          messageFlags |= kImapMsgRecentFlag;
          knownFlag = PR_TRUE;
        }
        break;
      default:
        break;
      }
    }
    else if (*fNextToken == '$')
    {
      switch (toupper(fNextToken[1])) {
      case 'M':
        if ((fSupportsUserDefinedFlags & (kImapMsgSupportUserFlag |
          kImapMsgSupportMDNSentFlag))
          && !PL_strncasecmp(fNextToken, "$MDNSent",8))
        {
          messageFlags |= kImapMsgMDNSentFlag;
          knownFlag = PR_TRUE;
        }
        break;
      case 'F':
        if ((fSupportsUserDefinedFlags & (kImapMsgSupportUserFlag |
          kImapMsgSupportForwardedFlag))
          && !PL_strncasecmp(fNextToken, "$Forwarded",10))
        {
          messageFlags |= kImapMsgForwardedFlag;
          knownFlag = PR_TRUE;
        }
        break;
      case 'L':
        if ((fSupportsUserDefinedFlags & (kImapMsgSupportUserFlag |
          kImapMsgLabelFlags))
          && !PL_strncasecmp(fNextToken, "$Label", 6))
        {
          PRInt32 labelValue = fNextToken[6];
          if (labelValue > '0')
          {
            // turn off any previous label flags
            messageFlags &= ~kImapMsgLabelFlags;
            // turn on this label flag
            messageFlags |= (labelValue - '0') << 9;
          }
          knownFlag = PR_TRUE;
        }
        break;
      default:
        break;
      }
    }
    if (!knownFlag && fFlagState)
    {
      nsCAutoString flag(fNextToken);
      PRInt32 parenIndex = flag.FindChar(')');
      if (parenIndex > 0)
        flag.Truncate(parenIndex);
      messageFlags |= kImapMsgCustomKeywordFlag;
      if (CurrentResponseUID() != nsMsgKey_None)
        fFlagState->AddUidCustomFlagPair(CurrentResponseUID(), flag.get());
      else
        fCustomFlags.AppendCString(flag);
    }
    if (PL_strcasestr(fNextToken, ")"))
    {
      // eat token chars until we get the ')'
      while (*fNextToken != ')')
        fNextToken++;
    }
    else
      AdvanceToNextToken();
  }
  
  if (ContinueParse())
    while(*fNextToken != ')')
      fNextToken++;
    
    fCurrentLineContainedFlagInfo = PR_TRUE;     // handled in PostProcessEndOfLine
    fSavedFlagInfo = messageFlags;
}

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 3053 of file nsImapServerResponseParser.cpp.

{
  return fFolderUIDValidity;
}

Here is the caller graph for this function:

Definition at line 134 of file nsImapServerResponseParser.h.

Here is the caller graph for this function:

Definition at line 121 of file nsImapServerResponseParser.h.

{ return fCapabilityFlag; }

Here is the caller graph for this function:

Definition at line 2908 of file nsImapServerResponseParser.cpp.

{
  return fDownloadingHeaders;
}

Here is the caller graph for this function:

Definition at line 2903 of file nsImapServerResponseParser.cpp.

{
  return (m_shell != nsnull);
}

Here is the caller graph for this function:

Definition at line 405 of file nsImapServerResponseParser.cpp.

{
  return fIMAPstate;
}

Definition at line 3156 of file nsImapServerResponseParser.cpp.

{
  return fLastChunk;
}

Definition at line 132 of file nsImapServerResponseParser.h.

{ return fMailAccountUrl; }

Definition at line 136 of file nsImapServerResponseParser.h.

Definition at line 137 of file nsImapServerResponseParser.h.

{return fFolderAdminUrl;}

Definition at line 135 of file nsImapServerResponseParser.h.

{ return fManageListsUrl; }
PRBool nsImapServerResponseParser::GetNextLineForParser ( char **  nextLine) [protected, virtual]

Implements nsIMAPGenericParser.

Definition at line 128 of file nsImapServerResponseParser.cpp.

{
  PRBool rv = PR_TRUE;
  *nextLine = fServerConnection.CreateNewLineFromSocket();
  if (fServerConnection.DeathSignalReceived() || (fServerConnection.GetConnectionStatus() <= 0))
    rv = PR_FALSE;
  // we'd really like to try to silently reconnect, but we shouldn't put this
  // message up just in the interrupt case
  if (fServerConnection.GetConnectionStatus() <= 0 && !fServerConnection.DeathSignalReceived())
    fServerConnection.AlertUserEventUsingId(IMAP_SERVER_DISCONNECTED);
  return rv;
}

Here is the call graph for this function:

Definition at line 119 of file nsImapServerResponseParser.h.

{ return fReportingErrors; }

Here is the caller graph for this function:

Definition at line 395 of file nsImapServerResponseParser.cpp.

Here is the caller graph for this function:

Definition at line 133 of file nsImapServerResponseParser.h.

{ return fXSenderInfo; }

Here is the caller graph for this function:

Reimplemented from nsIMAPGenericParser.

Definition at line 306 of file nsImapServerResponseParser.cpp.

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 3069 of file nsImapServerResponseParser.cpp.

{
  return fHighestRecordedUID;
}

Here is the caller graph for this function:

Definition at line 157 of file nsImapServerResponseParser.cpp.

Here is the call graph for this function:

Definition at line 1565 of file nsImapServerResponseParser.cpp.

{
  AdvanceToNextToken();
  if (ContinueParse())
  {
    nsCAutoString dateLine("Date: ");
    char *strValue = CreateNilString();
    if (strValue)
    {
      dateLine += strValue;
      nsCRT::free(strValue);
    }
    fServerConnection.HandleMessageDownLoadLine(dateLine.get(), PR_FALSE);
  }
  // advance the parser.
  AdvanceToNextToken();
}

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 3074 of file nsImapServerResponseParser.cpp.

{
  int i;
  for(i = 0; i < (int) PL_strlen(string); i++)
  {
    if (! isdigit(string[i]))
    {
      return PR_FALSE;
    }
  }
  
  return PR_TRUE;
}

Here is the caller graph for this function:

Definition at line 2261 of file nsImapServerResponseParser.cpp.

{
  // we may want to go out and store the language returned to us
  // by the language command in the host info session stuff. 

  // for now, just eat the language....
  do
  {
    // eat each language returned to us
    AdvanceToNextToken();
  } while (fNextToken && !fAtEndOfLine && ContinueParse());
}

Here is the call graph for this function:

Here is the caller graph for this function:

Reimplemented from nsIMAPGenericParser.

Definition at line 120 of file nsImapServerResponseParser.cpp.

Here is the call graph for this function:

Here is the caller graph for this function:

void nsImapServerResponseParser::mailbox ( nsImapMailboxSpec boxSpec) [protected, virtual]

Definition at line 901 of file nsImapServerResponseParser.cpp.

{
  char *boxname = nsnull;
  const char *serverKey = fServerConnection.GetImapServerKey();
  
  if (!PL_strcasecmp(fNextToken, "INBOX"))
  {
    boxname = PL_strdup("INBOX");
    AdvanceToNextToken();
  }
  else 
  {
    boxname = CreateAstring();
    AdvanceToNextToken();
  }
  
  if (boxname && fHostSessionList)
  {
    // should the namespace check go before or after the Utf7 conversion?
    fHostSessionList->SetNamespaceHierarchyDelimiterFromMailboxForHost(
      serverKey, boxname, boxSpec->hierarchySeparator);
    
    
    nsIMAPNamespace *ns = nsnull;
    fHostSessionList->GetNamespaceForMailboxForHost(serverKey, boxname, ns);
    if (ns)
    {
      switch (ns->GetType())
      {
      case kPersonalNamespace:
        boxSpec->box_flags |= kPersonalMailbox;
        break;
      case kPublicNamespace:
        boxSpec->box_flags |= kPublicMailbox;
        break;
      case kOtherUsersNamespace:
        boxSpec->box_flags |= kOtherUsersMailbox;
        break;
      default:       // (kUnknownNamespace)
        break;
      }
      boxSpec->namespaceForFolder = ns;
    }
    
    //        char *convertedName =
    //            fServerConnection.CreateUtf7ConvertedString(boxname, PR_FALSE);
    //        PRUnichar *unicharName;
    //        unicharName = fServerConnection.CreatePRUnicharStringFromUTF7(boxname);
    //        PL_strfree(boxname);
    //        boxname = convertedName;
  }
  
  if (!boxname)
  {
    if (!fServerConnection.DeathSignalReceived())
      HandleMemoryFailure();
  }
  else
  {
    NS_ASSERTION(boxSpec->connection, "box spec has null connection");
    NS_ASSERTION(boxSpec->connection->GetCurrentUrl(), "box spec has connection with null url");
    //boxSpec->hostName = nsnull;
    //if (boxSpec->connection && boxSpec->connection->GetCurrentUrl())
    boxSpec->connection->GetCurrentUrl()->AllocateCanonicalPath(boxname, boxSpec->hierarchySeparator, &boxSpec->allocatedPathName);
    nsIURI * aURL = nsnull;
    boxSpec->connection->GetCurrentUrl()->QueryInterface(NS_GET_IID(nsIURI), (void **) &aURL);
    if (aURL) {
      nsCAutoString host;
      aURL->GetHost(host);
      boxSpec->hostName = ToNewCString(host);
    }
    NS_IF_RELEASE(aURL);
    if (boxname)
      PL_strfree( boxname);
    // storage for the boxSpec is now owned by server connection
    fServerConnection.DiscoverMailboxSpec(boxSpec);
    
    // if this was cancelled by the user,then we sure don't want to
    // send more mailboxes their way
    if (fServerConnection.GetConnectionStatus() < 0)
      SetConnected(PR_FALSE);
  }
}

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 797 of file nsImapServerResponseParser.cpp.

{
  if (!PL_strcasecmp(fNextToken, "FLAGS")) 
  {
    // this handles the case where we got the permanent flags response
    // before the flags response, in which case, we want to ignore thes flags.
    if (fGotPermanentFlags)
      skip_to_CRLF();
    else
      parse_folder_flags();
  }
  else if (!PL_strcasecmp(fNextToken, "LIST"))
  {
    AdvanceToNextToken();
    if (ContinueParse())
      mailbox_list(PR_FALSE);
  }
  else if (!PL_strcasecmp(fNextToken, "LSUB"))
  {
    AdvanceToNextToken();
    if (ContinueParse())
      mailbox_list(PR_TRUE);
  }
  else if (!PL_strcasecmp(fNextToken, "MAILBOX"))
    skip_to_CRLF();
  else if (!PL_strcasecmp(fNextToken, "SEARCH"))
  {
    fSearchResults->AddSearchResultLine(fCurrentLine);
    fServerConnection.NotifySearchHit(fCurrentLine);
    skip_to_CRLF();
  }
}

Here is the call graph for this function:

Here is the caller graph for this function:

void nsImapServerResponseParser::mailbox_list ( PRBool  discoveredFromLsub) [protected, virtual]

Definition at line 836 of file nsImapServerResponseParser.cpp.

{
  nsImapMailboxSpec *boxSpec = new nsImapMailboxSpec;
  NS_ADDREF(boxSpec);
  PRBool needsToFreeBoxSpec = PR_TRUE;
  if (!boxSpec)
    HandleMemoryFailure();
  else
  {
    boxSpec->folderSelected = PR_FALSE;
    boxSpec->box_flags = kNoFlags;
    boxSpec->allocatedPathName = nsnull;
    boxSpec->hostName = nsnull;
    boxSpec->connection = &fServerConnection;
    boxSpec->flagState = nsnull;
    boxSpec->discoveredFromLsub = discoveredFromLsub;
    boxSpec->onlineVerified = PR_TRUE;
    boxSpec->box_flags &= ~kNameSpace;
    
    PRBool endOfFlags = PR_FALSE;
    fNextToken++;    // eat the first "("
    do {
      if (!PL_strncasecmp(fNextToken, "\\Marked", 7))
        boxSpec->box_flags |= kMarked;    
      else if (!PL_strncasecmp(fNextToken, "\\Unmarked", 9))
        boxSpec->box_flags |= kUnmarked;  
      else if (!PL_strncasecmp(fNextToken, "\\Noinferiors", 12))
        boxSpec->box_flags |= kNoinferiors;      
      else if (!PL_strncasecmp(fNextToken, "\\Noselect", 9))
        boxSpec->box_flags |= kNoselect;  
      // we ignore flag extensions
      
      endOfFlags = *(fNextToken + strlen(fNextToken) - 1) == ')';
      AdvanceToNextToken();
    } while (!endOfFlags && ContinueParse());
    
    if (ContinueParse())
    {
      if (*fNextToken == '"')
      {
        fNextToken++;
        if (*fNextToken == '\\')   // handle escaped char
          boxSpec->hierarchySeparator = *(fNextToken + 1);
        else
          boxSpec->hierarchySeparator = *fNextToken;
      }
      else    // likely NIL.  Discovered late in 4.02 that we do not handle literals here (e.g. {10} <10 chars>), although this is almost impossibly unlikely
        boxSpec->hierarchySeparator = kOnlineHierarchySeparatorNil;
      AdvanceToNextToken(); 
      if (ContinueParse())
      {
        // nsImapProtocol::DiscoverMailboxSpec() eventually frees the
        // boxSpec
        needsToFreeBoxSpec = PR_FALSE;
        mailbox(boxSpec);
      }
    }
  }
  if (needsToFreeBoxSpec)
    NS_RELEASE(boxSpec); // mscott - do we have any fields we need to
  // release?
}

Here is the call graph for this function:

Here is the caller graph for this function:

void nsImapServerResponseParser::mime_data ( ) [protected, virtual]

Definition at line 2480 of file nsImapServerResponseParser.cpp.

{
  if (PL_strstr(fNextToken, "MIME"))
    mime_header_data();
  else
    mime_part_data();
}

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 2493 of file nsImapServerResponseParser.cpp.

{
  char *partNumber = PL_strdup(fNextToken);
  if (partNumber)
  {
    char *start = partNumber+5, *end = partNumber+5;    // 5 == nsCRT::strlen("BODY[")
    while (ContinueParse() && end && *end != 'M' && *end != 'm')
    {
      end++;
    }
    if (end && (*end == 'M' || *end == 'm'))
    {
      *(end-1) = 0;
      AdvanceToNextToken();
      char *mimeHeaderData = CreateAstring();    // is it really this simple?
      AdvanceToNextToken();
      if (m_shell)
      {
        m_shell->AdoptMimeHeader(start, mimeHeaderData);
      }
    }
    else
    {
      SetSyntaxError(PR_TRUE);
    }
    PR_Free(partNumber);    // partNumber is not adopted by the body shell.
  }
  else
  {
    HandleMemoryFailure();
  }
}

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 2528 of file nsImapServerResponseParser.cpp.

{
  char *checkOriginToken = PL_strdup(fNextToken);
  if (checkOriginToken)
  {
    PRUint32 origin = 0;
    PRBool originFound = PR_FALSE;
    char *whereStart = PL_strchr(checkOriginToken, '<');
    if (whereStart)
    {
      char *whereEnd = PL_strchr(whereStart, '>');
      if (whereEnd)
      {
        *whereEnd = 0;
        whereStart++;
        origin = atoi(whereStart);
        originFound = PR_TRUE;
      }
    }
    PR_Free(checkOriginToken);
    AdvanceToNextToken();
    msg_fetch_content(originFound, origin, MESSAGE_RFC822);    // keep content type as message/rfc822, even though the
    // MIME part might not be, because then libmime will
    // still handle and decode it.
  }
  else
    HandleMemoryFailure();
}

Here is the call graph for this function:

Here is the caller graph for this function:

void nsImapServerResponseParser::msg_fetch ( ) [protected, virtual]

Definition at line 1045 of file nsImapServerResponseParser.cpp.

{
  nsresult res;
  PRBool bNeedEndMessageDownload = PR_FALSE;
  
  // we have not seen a uid response or flags for this fetch, yet
  fCurrentResponseUID = 0;
  fCurrentLineContainedFlagInfo = PR_FALSE;
  fSizeOfMostRecentMessage = 0;  
  // show any incremental progress, for instance, for header downloading
  fServerConnection.ShowProgress();
  
  fNextToken++;      // eat the '(' character
  
  // some of these productions are ignored for now
  while (ContinueParse() && (*fNextToken != ')') )
  {
    if (!PL_strcasecmp(fNextToken, "FLAGS"))
    {
      if (fCurrentResponseUID == 0)
        res = fFlagState->GetUidOfMessage(fFetchResponseIndex - 1, &fCurrentResponseUID);
      
      AdvanceToNextToken();
      if (ContinueParse())
        flags();
      
      if (ContinueParse())
      {       // eat the closing ')'
        fNextToken++;
        // there may be another ')' to close out
        // msg_fetch.  If there is then don't advance
        if (*fNextToken != ')')
          AdvanceToNextToken();
      }
    }
    else if (!PL_strcasecmp(fNextToken, "UID"))
    {
      AdvanceToNextToken();
      if (ContinueParse())
      {
        fCurrentResponseUID = atoi(fNextToken);
        if (fCurrentResponseUID > fHighestRecordedUID)
          fHighestRecordedUID = fCurrentResponseUID;
        // size came before UID
        if (fSizeOfMostRecentMessage)
          fReceivedHeaderOrSizeForUID = CurrentResponseUID();
        // if this token ends in ')', then it is the last token
        // else we advance
        if ( *(fNextToken + strlen(fNextToken) - 1) == ')')
          fNextToken += strlen(fNextToken) - 1;
        else
          AdvanceToNextToken();
      }
    }
    else if (!PL_strcasecmp(fNextToken, "RFC822") ||
      !PL_strcasecmp(fNextToken, "RFC822.HEADER") ||
      !PL_strncasecmp(fNextToken, "BODY[HEADER",11) ||
      !PL_strncasecmp(fNextToken, "BODY[]", 6) ||
      !PL_strcasecmp(fNextToken, "RFC822.TEXT") ||
      (!PL_strncasecmp(fNextToken, "BODY[", 5) &&
                              PL_strstr(fNextToken, "HEADER"))
                                  )
    {
      if (fCurrentResponseUID == 0)
        fFlagState->GetUidOfMessage(fFetchResponseIndex - 1, &fCurrentResponseUID);
      
      if (!PL_strcasecmp(fNextToken, "RFC822.HEADER") ||
        !PL_strcasecmp(fNextToken, "BODY[HEADER]"))
      {
        // all of this message's headers
        AdvanceToNextToken();
        fDownloadingHeaders = PR_TRUE;
        BeginMessageDownload(MESSAGE_RFC822); // initialize header parser
        bNeedEndMessageDownload = PR_FALSE;
        if (ContinueParse())
          msg_fetch_headers(nsnull);
      }
      else if (!PL_strncasecmp(fNextToken, "BODY[HEADER.FIELDS",19))
      {
        fDownloadingHeaders = PR_TRUE;
        BeginMessageDownload(MESSAGE_RFC822); // initialize header parser
        // specific message header fields
        while (ContinueParse() && fNextToken[strlen(fNextToken)-1] != ']')
          AdvanceToNextToken();
        if (ContinueParse())
        {
          bNeedEndMessageDownload = PR_FALSE;
          AdvanceToNextToken();
          if (ContinueParse())
            msg_fetch_headers(nsnull);
        }
      }
      else
      {
        char *whereHeader = PL_strstr(fNextToken, "HEADER");
        if (whereHeader)
        {
          char *startPartNum = fNextToken + 5;
          if (whereHeader > startPartNum)
          {
            PRInt32 partLength = whereHeader - startPartNum - 1; //-1 for the dot!
            char *partNum = (char *)PR_CALLOC((partLength + 1) * sizeof (char));
            if (partNum)
            {
              PL_strncpy(partNum, startPartNum, partLength);
              if (ContinueParse())
              {
                if (PL_strstr(fNextToken, "FIELDS"))
                {
                  while (ContinueParse() && fNextToken[strlen(fNextToken)-1] != ']')
                    AdvanceToNextToken();
                }
                if (ContinueParse())
                {
                  AdvanceToNextToken();
                  if (ContinueParse())
                    msg_fetch_headers(partNum);
                }
              }
              PR_Free(partNum);
            }
          }
          else
            SetSyntaxError(PR_TRUE);
        }
        else
        {
          fDownloadingHeaders = PR_FALSE;
          
          PRBool chunk = PR_FALSE;
          PRInt32 origin = 0;
          if (!PL_strncasecmp(fNextToken, "BODY[]<", 7))
          {
            char *tokenCopy = 0;
            tokenCopy = PL_strdup(fNextToken);
            if (tokenCopy)
            {
              char *originString = tokenCopy + 7;       // where the byte number starts
              char *closeBracket = PL_strchr(tokenCopy,'>');
              if (closeBracket && originString && *originString)
              {
                *closeBracket = 0;
                origin = atoi(originString);
                chunk = PR_TRUE;
              }
              PR_Free(tokenCopy);
            }
          }
          
          AdvanceToNextToken();
          if (ContinueParse())
          {
            msg_fetch_content(chunk, origin, MESSAGE_RFC822);
          }
        }
      }
      }
      else if (!PL_strcasecmp(fNextToken, "RFC822.SIZE") || !PL_strcasecmp(fNextToken, "XAOL.SIZE"))
      {
        AdvanceToNextToken();
        if (ContinueParse())
        {
          PRBool sendEndMsgDownload = (GetDownloadingHeaders() 
                                        && fReceivedHeaderOrSizeForUID == CurrentResponseUID());
          fSizeOfMostRecentMessage = atoi(fNextToken);
          fReceivedHeaderOrSizeForUID = CurrentResponseUID();
          if (sendEndMsgDownload)
          {
            fServerConnection.NormalMessageEndDownload();
            fReceivedHeaderOrSizeForUID = nsMsgKey_None;
          }

          // if we are in the process of fetching everything RFC822 then we should
          // turn around and force the total download size to be set to this value.
          // this helps if the server gaves us a bogus size for the message in response to the 
          // envelope command.
          if (fFetchEverythingRFC822)
            SetTotalDownloadSize(fSizeOfMostRecentMessage);
          
          if (fSizeOfMostRecentMessage == 0 && CurrentResponseUID())
          {
            // on no, bogus Netscape 2.0 mail server bug
            char uidString[100];
            sprintf(uidString, "%ld", (long)CurrentResponseUID());
            
            if (!fZeroLengthMessageUidString.IsEmpty())
              fZeroLengthMessageUidString += ",";
            
            fZeroLengthMessageUidString += uidString;
          }
          
          // if this token ends in ')', then it is the last token
          // else we advance
          if ( *(fNextToken + strlen(fNextToken) - 1) == ')')
            fNextToken += strlen(fNextToken) - 1;
          else
            AdvanceToNextToken();
        }
      }
      else if (!PL_strcasecmp(fNextToken, "XSENDER"))
      {
        PR_FREEIF(fXSenderInfo);
        AdvanceToNextToken();
        if (! fNextToken) 
          SetSyntaxError(PR_TRUE);
        else
        {
          fXSenderInfo = CreateAstring(); 
          AdvanceToNextToken();
        }
      }
      // I only fetch RFC822 so I should never see these BODY responses
      else if (!PL_strcasecmp(fNextToken, "BODY"))
        skip_to_CRLF(); // I never ask for this
      else if (!PL_strcasecmp(fNextToken, "BODYSTRUCTURE"))
      {
        if (fCurrentResponseUID == 0)
          fFlagState->GetUidOfMessage(fFetchResponseIndex - 1, &fCurrentResponseUID);
        bodystructure_data();
      }
      else if (!PL_strncasecmp(fNextToken, "BODY[TEXT", 9))
      {
        mime_data();
      }
      else if (!PL_strncasecmp(fNextToken, "BODY[", 5) && PL_strncasecmp(fNextToken, "BODY[]", 6))
      {
        fDownloadingHeaders = PR_FALSE;
        // A specific MIME part, or MIME part header
        mime_data();
      }
      else if (!PL_strcasecmp(fNextToken, "ENVELOPE"))
      {
        fDownloadingHeaders = PR_TRUE;
        bNeedEndMessageDownload = PR_TRUE;
        BeginMessageDownload(MESSAGE_RFC822);
        envelope_data(); 
      }
      else if (!PL_strcasecmp(fNextToken, "INTERNALDATE"))
      {
        fDownloadingHeaders = PR_TRUE; // we only request internal date while downloading headers
        if (!bNeedEndMessageDownload)
          BeginMessageDownload(MESSAGE_RFC822);
        bNeedEndMessageDownload = PR_TRUE;
        internal_date(); 
      }
      else if (!PL_strcasecmp(fNextToken, "XAOL-ENVELOPE"))
      {
        fDownloadingHeaders = PR_TRUE;
        if (!bNeedEndMessageDownload)
          BeginMessageDownload(MESSAGE_RFC822);
        bNeedEndMessageDownload = PR_TRUE;
        xaolenvelope_data();
      }
      else
      {
        nsImapAction imapAction; 
        if (!fServerConnection.GetCurrentUrl())
          return;
        fServerConnection.GetCurrentUrl()->GetImapAction(&imapAction);
        nsXPIDLCString userDefinedFetchAttribute;
        fServerConnection.GetCurrentUrl()->GetCustomAttributeToFetch(getter_Copies(userDefinedFetchAttribute));
        if (imapAction == nsIImapUrl::nsImapUserDefinedFetchAttribute && !strcmp(userDefinedFetchAttribute.get(), fNextToken))
        {
          AdvanceToNextToken();
          char *fetchResult = CreateParenGroup();
          // look through the tokens until we find the closing ')'
          // we can have a result like the following:
          // ((A B) (C D) (E F))
          fServerConnection.GetCurrentUrl()->SetCustomAttributeResult(fetchResult);
          PR_Free(fetchResult);
          break;
        }
        else
          SetSyntaxError(PR_TRUE);
      }
      
        }
        
        if (ContinueParse())
        {
          if (CurrentResponseUID() && CurrentResponseUID() != nsMsgKey_None 
            && fCurrentLineContainedFlagInfo && fFlagState)
          {
            fFlagState->AddUidFlagPair(CurrentResponseUID(), fSavedFlagInfo, fFetchResponseIndex - 1);
            for (PRInt32 i = 0; i < fCustomFlags.Count(); i++)
              fFlagState->AddUidCustomFlagPair(CurrentResponseUID(), fCustomFlags.CStringAt(i)->get());
            fCustomFlags.Clear();
          }
          
          if (fFetchingAllFlags)
            fCurrentLineContainedFlagInfo = PR_FALSE;   // do not fire if in PostProcessEndOfLine          
          
          AdvanceToNextToken();    // eat the ')' ending token
                                                                      // should be at end of line
          if (bNeedEndMessageDownload)
          {
            if (ContinueParse())
            {
              // complete the message download
              fServerConnection.NormalMessageEndDownload();
            }
            else
              fServerConnection.AbortMessageDownLoad();
          }
          
        }
}

Here is the call graph for this function:

Here is the caller graph for this function:

void nsImapServerResponseParser::msg_fetch_content ( PRBool  chunk,
PRInt32  origin,
const char *  content_type 
) [protected, virtual]

Definition at line 2048 of file nsImapServerResponseParser.cpp.

{
  // setup the stream for downloading this message.
  // Don't do it if we are filling in a shell or downloading a part.
  // DO do it if we are downloading a whole message as a result of
  // an invalid shell trying to generate.
  if ((!chunk || (origin == 0)) && !GetDownloadingHeaders() &&
    (GetFillingInShell() ? m_shell->GetGeneratingWholeMessage() : PR_TRUE))
  {
    if (NS_FAILED(BeginMessageDownload(content_type)))
      return;
  }
  
  if (PL_strcasecmp(fNextToken, "NIL"))
  {
    if (*fNextToken == '"')
      fLastChunk = msg_fetch_quoted(chunk, origin);
    else
      fLastChunk = msg_fetch_literal(chunk, origin);
  }
  else
    AdvanceToNextToken();   // eat "NIL"
  
  if (fLastChunk && (GetFillingInShell() ? m_shell->GetGeneratingWholeMessage() : PR_TRUE))
  {
    // complete the message download
    if (ContinueParse())
    {
      if (fReceivedHeaderOrSizeForUID == CurrentResponseUID())
      {
        fServerConnection.NormalMessageEndDownload();
        fReceivedHeaderOrSizeForUID = nsMsgKey_None;
      }
      else
         fReceivedHeaderOrSizeForUID = CurrentResponseUID();
    }
    else
      fServerConnection.AbortMessageDownLoad();
  }
}

Here is the call graph for this function:

Here is the caller graph for this function:

void nsImapServerResponseParser::msg_fetch_headers ( const char *  partNum) [protected, virtual]

Definition at line 2028 of file nsImapServerResponseParser.cpp.

{
  if (GetFillingInShell())
  {
    char *headerData = CreateAstring();
    AdvanceToNextToken();
    m_shell->AdoptMessageHeaders(headerData, partNum);
  }
  else
  {
    msg_fetch_content(PR_FALSE, 0, MESSAGE_RFC822);
  }
}

Here is the call graph for this function:

Here is the caller graph for this function:

PRBool nsImapServerResponseParser::msg_fetch_literal ( PRBool  chunk,
PRInt32  origin 
) [protected, virtual]

Definition at line 2940 of file nsImapServerResponseParser.cpp.

{
  numberOfCharsInThisChunk = atoi(fNextToken + 1); // might be the whole message
  charsReadSoFar = 0;
  static PRBool lastCRLFwasCRCRLF = PR_FALSE;
  
  PRBool lastChunk = !chunk || (origin + numberOfCharsInThisChunk >= fTotalDownloadSize);
  
  nsImapAction imapAction; 
  if (!fServerConnection.GetCurrentUrl())
    return PR_TRUE;
  fServerConnection.GetCurrentUrl()->GetImapAction(&imapAction);
  if (!lastCRLFwasCRCRLF && 
    fServerConnection.GetIOTunnellingEnabled() && 
    (numberOfCharsInThisChunk > fServerConnection.GetTunnellingThreshold()) &&
    (imapAction != nsIImapUrl::nsImapOnlineToOfflineCopy) &&
    (imapAction != nsIImapUrl::nsImapOnlineToOfflineMove))
  {
    // One day maybe we'll make this smarter and know how to handle CR/LF boundaries across tunnels.
    // For now, we won't, even though it might not be too hard, because it is very rare and will add
    // some complexity.
    charsReadSoFar = fServerConnection.OpenTunnel(numberOfCharsInThisChunk);
  }
  
  // If we opened a tunnel, finish everything off here.  Otherwise, get everything here.
  // (just like before)
  
  while (ContinueParse() && !fServerConnection.DeathSignalReceived() && (charsReadSoFar < numberOfCharsInThisChunk))
  {
    AdvanceToNextLine();
    if (ContinueParse())
    {
      if (lastCRLFwasCRCRLF && (*fCurrentLine == nsCRT::CR))
      {
        char *usableCurrentLine = PL_strdup(fCurrentLine + 1);
        PR_Free(fCurrentLine);
        fCurrentLine = usableCurrentLine;
      }
      
      if (ContinueParse())
      {
        charsReadSoFar += strlen(fCurrentLine);
        if (!fDownloadingHeaders && fCurrentCommandIsSingleMessageFetch)
        {
          fServerConnection.ProgressEventFunctionUsingId(IMAP_DOWNLOADING_MESSAGE);
          if (fTotalDownloadSize > 0)
            fServerConnection.PercentProgressUpdateEvent(0,charsReadSoFar + origin, fTotalDownloadSize);
        }
        if (charsReadSoFar > numberOfCharsInThisChunk)
        {     // this is rare.  If this msg ends in the middle of a line then only display the actual message.
          char *displayEndOfLine = (fCurrentLine + strlen(fCurrentLine) - (charsReadSoFar - numberOfCharsInThisChunk));
          char saveit = *displayEndOfLine;
          *displayEndOfLine = 0;
          fServerConnection.HandleMessageDownLoadLine(fCurrentLine, !lastChunk);
          *displayEndOfLine = saveit;
          lastCRLFwasCRCRLF = (*(displayEndOfLine - 1) == nsCRT::CR);
        }
        else
        {
          lastCRLFwasCRCRLF = (*(fCurrentLine + strlen(fCurrentLine) - 1) == nsCRT::CR);
          fServerConnection.HandleMessageDownLoadLine(fCurrentLine, !lastChunk && (charsReadSoFar == numberOfCharsInThisChunk), fCurrentLine);
        }
      }
    }
  }
  
  // This would be a good thing to log.
  if (lastCRLFwasCRCRLF)
    PR_LOG(IMAP, PR_LOG_ALWAYS, ("PARSER: CR/LF fell on chunk boundary."));
  
  if (ContinueParse())
  {
    if (charsReadSoFar > numberOfCharsInThisChunk)
    {
      // move the lexical analyzer state to the end of this message because this message
      // fetch ends in the middle of this line.
      //fCurrentTokenPlaceHolder = fLineOfTokens + nsCRT::strlen(fCurrentLine) - (charsReadSoFar - numberOfCharsInThisChunk);
      AdvanceTokenizerStartingPoint(strlen(fCurrentLine) - (charsReadSoFar - numberOfCharsInThisChunk));
      AdvanceToNextToken();
    }
    else
    {
      skip_to_CRLF();
      AdvanceToNextToken();
    }
  }
  else
  {
    lastCRLFwasCRCRLF = PR_FALSE;
  }
  return lastChunk;
}

Here is the call graph for this function:

Here is the caller graph for this function:

PRBool nsImapServerResponseParser::msg_fetch_quoted ( PRBool  chunk,
PRInt32  origin 
) [protected, virtual]

Definition at line 2099 of file nsImapServerResponseParser.cpp.

{
  
#ifdef DEBUG_chrisf
        PR_ASSERT(!chunk);
#endif
         
         char *q = CreateQuoted();
         if (q)
         {
           fServerConnection.HandleMessageDownLoadLine(q, PR_FALSE, q);
           PR_Free(q);
         }
         
         AdvanceToNextToken();
         
         PRBool lastChunk = !chunk || ((origin + numberOfCharsInThisChunk) >= fTotalDownloadSize);
         return lastChunk;
}

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 2120 of file nsImapServerResponseParser.cpp.

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 2398 of file nsImapServerResponseParser.cpp.

{
  AdvanceToNextToken();
  if (ContinueParse() && !fAtEndOfLine)
  {
    char *mailboxName = CreateAstring(); // PL_strdup(fNextToken);
    if (mailboxName)
    {
      AdvanceToNextToken();
      if (ContinueParse())
      {
        char *myrights = CreateAstring(); // PL_strdup(fNextToken);
        if (myrights)
        {
          nsImapProtocol *navCon = &fServerConnection;
          NS_ASSERTION(navCon, "null connection parsing my rights");  // we should always have this
          if (navCon)
            navCon->AddFolderRightsForUser(mailboxName, nsnull /* means "me" */, myrights);
          PR_Free(myrights);
        }
        else
        {
          HandleMemoryFailure();
        }
        if (ContinueParse())
          AdvanceToNextToken();
      }
      PR_Free(mailboxName);
    }
    else
    {
      HandleMemoryFailure();
    }
  }
  else
  {
    SetSyntaxError(PR_TRUE);
  }
}

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 2287 of file nsImapServerResponseParser.cpp.

{
       EIMAPNamespaceType namespaceType = kPersonalNamespace;
       PRBool namespacesCommitted = PR_FALSE;
  const char* serverKey = fServerConnection.GetImapServerKey();
       while ((namespaceType != kUnknownNamespace) && ContinueParse())
       {
              AdvanceToNextToken();
              while (fAtEndOfLine && ContinueParse())
                     AdvanceToNextToken();
              if (!PL_strcasecmp(fNextToken,"NIL"))
              {
                     // No namespace for this type.
                     // Don't add anything to the Namespace object.
              }
              else if (fNextToken[0] == '(')
              {
                     // There may be multiple namespaces of the same type.
                     // Go through each of them and add them to our Namespace object.

                     fNextToken++;
                     while (fNextToken[0] == '(' && ContinueParse())
                     {
                            // we have another namespace for this namespace type
                            fNextToken++;
                            if (fNextToken[0] != '"')
                            {
                                   SetSyntaxError(PR_TRUE);
                            }
                            else
                            {
                                   char *namespacePrefix = CreateQuoted(PR_FALSE);

                                   AdvanceToNextToken();
                                   char *quotedDelimiter = fNextToken;
                                   char namespaceDelimiter = '\0';

                                   if (quotedDelimiter[0] == '"')
                                   {
                                          quotedDelimiter++;
                                          namespaceDelimiter = quotedDelimiter[0];
                                   }
                                   else if (!PL_strncasecmp(quotedDelimiter, "NIL", 3))
                                   {
                                          // NIL hierarchy delimiter.  Leave namespace delimiter nsnull.
                                   }
                                   else
                                   {
                                          // not quoted or NIL.
                                          SetSyntaxError(PR_TRUE);
                                   }
                                   if (ContinueParse())
                                   {
            // add code to parse the TRANSLATE attribute if it is present....
            // we'll also need to expand the name space code to take in the translated prefix name.

                                          nsIMAPNamespace *newNamespace = new nsIMAPNamespace(namespaceType, namespacePrefix, namespaceDelimiter, PR_FALSE);
                                          // add it to a temporary list in the host
                                          if (newNamespace && fHostSessionList)
                                                 fHostSessionList->AddNewNamespaceForHost(
                                serverKey, newNamespace);

                                          skip_to_close_paren();      // Ignore any extension data
       
                                          PRBool endOfThisNamespaceType = (fNextToken[0] == ')');
                                          if (!endOfThisNamespaceType && fNextToken[0] != '(')    // no space between namespaces of the same type
                                          {
                                                 SetSyntaxError(PR_TRUE);
                                          }
                                   }
                                   PR_Free(namespacePrefix);
                            }
                     }
              }
              else
              {
                     SetSyntaxError(PR_TRUE);
              }
              switch (namespaceType)
              {
              case kPersonalNamespace:
                     namespaceType = kOtherUsersNamespace;
                     break;
              case kOtherUsersNamespace:
                     namespaceType = kPublicNamespace;
                     break;
              default:
                     namespaceType = kUnknownNamespace;
                     break;
              }
       }
       if (ContinueParse())
       {
              nsImapProtocol *navCon = &fServerConnection;
              NS_ASSERTION(navCon, "null protocol connection while parsing namespace");    // we should always have this
              if (navCon)
              {
                     navCon->CommitNamespacesForHostEvent();
                     namespacesCommitted = PR_TRUE;
              }
       }
       skip_to_CRLF();

       if (!namespacesCommitted && fHostSessionList)
       {
              PRBool success;
              fHostSessionList->FlushUncommittedNamespacesForHost(serverKey,
                                                            success);
       }
}

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 3038 of file nsImapServerResponseParser.cpp.

Here is the caller graph for this function:

Definition at line 3043 of file nsImapServerResponseParser.cpp.

Definition at line 3048 of file nsImapServerResponseParser.cpp.

Definition at line 997 of file nsImapServerResponseParser.cpp.

{
  PRInt32 tokenNumber = atoi(fNextToken);
  AdvanceToNextToken();
  
  if (ContinueParse())
  {
    if (!PL_strcasecmp(fNextToken, "FETCH"))
    {
      fFetchResponseIndex = tokenNumber;
      AdvanceToNextToken();
      if (ContinueParse())
        msg_fetch(); 
    }
    else if (!PL_strcasecmp(fNextToken, "EXISTS"))
    {
      fNumberOfExistingMessages = tokenNumber;
      AdvanceToNextToken();
    }
    else if (!PL_strcasecmp(fNextToken, "RECENT"))
    {
      fNumberOfRecentMessages = tokenNumber;
      AdvanceToNextToken();
    }
    else if (!PL_strcasecmp(fNextToken, "EXPUNGE"))
    {
      if (!fServerConnection.GetIgnoreExpunges())
        fFlagState->ExpungeByIndex((PRUint32) tokenNumber);
      skip_to_CRLF();
    }
    else
      msg_obsolete();
  }
}

Here is the call graph for this function:

Here is the caller graph for this function:

void nsImapServerResponseParser::parse_address ( nsCAutoString addressLine) [protected, virtual]

Definition at line 1501 of file nsImapServerResponseParser.cpp.

{
  if (!nsCRT::strcmp(fNextToken, "NIL"))
    return;
  PRBool firstAddress = PR_TRUE;
  // should really look at chars here
  NS_ASSERTION(*fNextToken == '(', "address should start with '('");
  fNextToken++; // eat the next '('
  while (ContinueParse() && *fNextToken == '(')
  {
    NS_ASSERTION(*fNextToken == '(', "address should start with '('");
    fNextToken++; // eat the next '('
    
    if (!firstAddress)
      addressLine += ", ";
    
    firstAddress = PR_FALSE;
    char *personalName = CreateNilString();
    AdvanceToNextToken();
    char *atDomainList = CreateNilString();
    if (ContinueParse())
    {
      AdvanceToNextToken();
      char *mailboxName = CreateNilString();
      if (ContinueParse())
      {
        AdvanceToNextToken();
        char *hostName = CreateNilString();
        // our tokenizer doesn't handle "NIL)" quite like we
        // expect, so we need to check specially for this.
        if (hostName || *fNextToken != ')')
          AdvanceToNextToken();    // skip hostName
        addressLine += mailboxName;
        if (hostName)
        {
          addressLine += '@';
          addressLine += hostName;
          nsCRT::free(hostName);
        }
        if (personalName)
        {
          addressLine += " (";
          addressLine += personalName;
          addressLine += ')';
        }
      }
    }
    PR_Free(personalName);
    PR_Free(atDomainList);
    
    if (*fNextToken == ')')
      fNextToken++;
    // if the next token isn't a ')' for the address term,
    // then we must have another address pair left....so get the next
    // token and continue parsing in this loop...
    if ( *fNextToken == '\0' )
      AdvanceToNextToken();
    
  }
  if (*fNextToken == ')')
    fNextToken++;
  //   AdvanceToNextToken();       // skip "))"
}

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 1773 of file nsImapServerResponseParser.cpp.

{
  PRUint16 labelFlags = 0;

  do 
  {
    AdvanceToNextToken();
    if (*fNextToken == '(')
      fNextToken++;
    if (!PL_strncasecmp(fNextToken, "$MDNSent", 8))
      fSupportsUserDefinedFlags |= kImapMsgSupportMDNSentFlag;
    else if (!PL_strncasecmp(fNextToken, "$Forwarded", 10))
      fSupportsUserDefinedFlags |= kImapMsgSupportForwardedFlag;
    else if (!PL_strncasecmp(fNextToken, "\\Seen", 5))
      fSettablePermanentFlags |= kImapMsgSeenFlag;
    else if (!PL_strncasecmp(fNextToken, "\\Answered", 9))
      fSettablePermanentFlags |= kImapMsgAnsweredFlag;
    else if (!PL_strncasecmp(fNextToken, "\\Flagged", 8))
      fSettablePermanentFlags |= kImapMsgFlaggedFlag;
    else if (!PL_strncasecmp(fNextToken, "\\Deleted", 8))
      fSettablePermanentFlags |= kImapMsgDeletedFlag;
    else if (!PL_strncasecmp(fNextToken, "\\Draft", 6))
      fSettablePermanentFlags |= kImapMsgDraftFlag;
    else if (!PL_strncasecmp(fNextToken, "$Label1", 7))
      labelFlags |= 1;
    else if (!PL_strncasecmp(fNextToken, "$Label2", 7))
      labelFlags |= 2;
    else if (!PL_strncasecmp(fNextToken, "$Label3", 7))
      labelFlags |= 4;
    else if (!PL_strncasecmp(fNextToken, "$Label4", 7))
      labelFlags |= 8;
    else if (!PL_strncasecmp(fNextToken, "$Label5", 7))
      labelFlags |= 16;
    else if (!PL_strncasecmp(fNextToken, "\\*", 2))
    {
      fSupportsUserDefinedFlags |= kImapMsgSupportUserFlag;
      fSupportsUserDefinedFlags |= kImapMsgSupportForwardedFlag;
      fSupportsUserDefinedFlags |= kImapMsgSupportMDNSentFlag;
      fSupportsUserDefinedFlags |= kImapMsgLabelFlags;
    }
  } while (!fAtEndOfLine && ContinueParse());

  if (labelFlags == 31)
    fSupportsUserDefinedFlags |= kImapMsgLabelFlags;

  if (fFlagState)
    fFlagState->SetSupportedUserFlags(fSupportsUserDefinedFlags);
}

Here is the call graph for this function:

Here is the caller graph for this function:

void nsImapServerResponseParser::ParseIMAPServerResponse ( const char *  currentCommand,
PRBool  aIgnoreBadAndNOResponses 
) [virtual]

Definition at line 178 of file nsImapServerResponseParser.cpp.

{
  
  NS_ASSERTION(currentCommand && *currentCommand != '\r' && 
    *currentCommand != '\n' && *currentCommand != ' ', "Invailid command string");
  PRBool sendingIdleDone = !strcmp(currentCommand, "DONE"CRLF);
  if (sendingIdleDone)
    fWaitingForMoreClientInput = PR_FALSE;

  // Reinitialize the parser
  SetConnected(PR_TRUE);
  SetSyntaxError(PR_FALSE);
  
  // Reinitialize our state
  InitializeState();
  
  // the default is to not pipeline
  fNumberOfTaggedResponsesExpected = 1;
  int numberOfTaggedResponsesReceived = 0;
  
  char *copyCurrentCommand = PL_strdup(currentCommand);
  if (!copyCurrentCommand)
  {
    HandleMemoryFailure();
    return;
  }
  if (!fServerConnection.DeathSignalReceived())
  {
    char *placeInTokenString = nsnull;
    char *tagToken = nsnull;
    char *commandToken = nsnull;
    PRBool inIdle = PR_FALSE;
    if (!sendingIdleDone)
    {
      tagToken = nsCRT::strtok(copyCurrentCommand, WHITESPACE, &placeInTokenString);
      commandToken = nsCRT::strtok(placeInTokenString, WHITESPACE,&placeInTokenString);
    }
    else
      commandToken = "DONE";
    if (tagToken)
    {
      PR_Free( fCurrentCommandTag );
      fCurrentCommandTag = PL_strdup(tagToken);
      if (!fCurrentCommandTag)
        HandleMemoryFailure();
      inIdle = commandToken && !strcmp(commandToken, "IDLE");
    }
    
    if (commandToken && ContinueParse())
      PreProcessCommandToken(commandToken, currentCommand);
    
    if (ContinueParse())
    {
      ResetLexAnalyzer();
      
      do {
        AdvanceToNextToken();
        while (ContinueParse() && !PL_strcmp(fNextToken, "*") )
        {
          response_data();
          if (ContinueParse())
          {
            if (!fAtEndOfLine)
              SetSyntaxError(PR_TRUE);
            else if (!inIdle && !fCurrentCommandFailed)
              AdvanceToNextToken();
          }
        }
        
        if (ContinueParse() && *fNextToken == '+')      // never pipeline APPEND or AUTHENTICATE
        {
          NS_ASSERTION((fNumberOfTaggedResponsesExpected - numberOfTaggedResponsesReceived) == 1, 
            " didn't get the number of tagged responses we expected");
          numberOfTaggedResponsesReceived = fNumberOfTaggedResponsesExpected;
          if (commandToken && !nsCRT::strcasecmp(commandToken, "authenticate") && placeInTokenString && 
            (!nsCRT::strncasecmp(placeInTokenString, "CRAM-MD5", strlen("CRAM-MD5"))
             || !nsCRT::strncasecmp(placeInTokenString, "NTLM", strlen("NTLM"))
             || !nsCRT::strncasecmp(placeInTokenString, "GSSAPI", strlen("GSSAPI"))
             || !nsCRT::strncasecmp(placeInTokenString, "MSN", strlen("MSN"))))
          {
            // we need to store the challenge from the server if we are using CRAM-MD5 or NTLM. 
            authChallengeResponse_data();
          }
        }
        else
          numberOfTaggedResponsesReceived++;
        
        if (numberOfTaggedResponsesReceived < fNumberOfTaggedResponsesExpected)
        {
          response_tagged();
          fProcessingTaggedResponse = PR_FALSE;
        }
        
      } while (ContinueParse() && !inIdle && (numberOfTaggedResponsesReceived < fNumberOfTaggedResponsesExpected));
      
      // check and see if the server is waiting for more input
      // it's possible that we ate this + while parsing certain responses (like cram data),
      // in these cases, the parsing routine for that specific command will manually set
      // fWaitingForMoreClientInput so we don't lose that information....
      if (*fNextToken == '+' || inIdle)
      {
        fWaitingForMoreClientInput = PR_TRUE;
      }
      else if (!fWaitingForMoreClientInput) // if we aren't still waiting for more input....
      {
        if (ContinueParse())
          response_done();
        
        if (ContinueParse() && !CommandFailed())
        {
          // a successful command may change the eIMAPstate
          ProcessOkCommand(commandToken);
        }
        else if (CommandFailed())
        {
          // a failed command may change the eIMAPstate
          ProcessBadCommand(commandToken);
          if (fReportingErrors && !aIgnoreBadAndNOResponses)
            fServerConnection.AlertUserEventFromServer(fCurrentLine);
        }
      }
    }
  }
  else
    SetConnected(PR_FALSE);
  PL_strfree(copyCurrentCommand);
}

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 765 of file nsImapServerResponseParser.cpp.

{
  // for now we only have to do one thing here
  // a fetch response to a 'uid store' command might return the flags
  // before it returns the uid of the message.  So we need both before
  // we report the new flag info to the front end
  
  // also check and be sure that there was a UID in the current response
  if (fCurrentLineContainedFlagInfo && CurrentResponseUID())
  {
    fCurrentLineContainedFlagInfo = PR_FALSE;
    fServerConnection.NotifyMessageFlags(fSavedFlagInfo, CurrentResponseUID());
  }
}

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 410 of file nsImapServerResponseParser.cpp.

Here is the caller graph for this function:

void nsImapServerResponseParser::PreProcessCommandToken ( const char *  commandToken,
const char *  currentCommand 
) [protected, virtual]

Definition at line 315 of file nsImapServerResponseParser.cpp.

{
  fCurrentCommandIsSingleMessageFetch = PR_FALSE;
  fWaitingForMoreClientInput = PR_FALSE;
  
  if (!PL_strcasecmp(commandToken, "SEARCH"))
    fSearchResults->ResetSequence();
  else if (!PL_strcasecmp(commandToken, "SELECT") && currentCommand)
  {
    // the mailbox name must be quoted, so strip the quotes
    const char *openQuote = PL_strstr(currentCommand, "\"");
    NS_ASSERTION(openQuote, "expected open quote in imap server response");
    if (!openQuote)
    { // ill formed select command
      openQuote = PL_strstr(currentCommand, " ");
    }
    PR_Free( fSelectedMailboxName);
    fSelectedMailboxName = PL_strdup(openQuote + 1);
    if (fSelectedMailboxName)
    {
      // strip the escape chars and the ending quote
      char *currentChar = fSelectedMailboxName;
      while (*currentChar)
      {
        if (*currentChar == '\\')
        {
          PL_strcpy(currentChar, currentChar+1);
          currentChar++;    // skip what we are escaping
        }
        else if (*currentChar == '\"')
          *currentChar = 0; // end quote
        else
          currentChar++;
      }
    }
    else
      HandleMemoryFailure();
    
    // we don't want bogus info for this new box
    //delete fFlagState;    // not our object
    //fFlagState = nsnull;
  }
  else if (!PL_strcasecmp(commandToken, "CLOSE"))
  {
    return;   // just for debugging
    // we don't want bogus info outside the selected state
    //delete fFlagState;    // not our object
    //fFlagState = nsnull;
  }
  else if (!PL_strcasecmp(commandToken, "UID"))
  {
    char *copyCurrentCommand = PL_strdup(currentCommand);
    if (!copyCurrentCommand)
    {
      HandleMemoryFailure();
      return;
    }
    if (!fServerConnection.DeathSignalReceived())
    {
      char *placeInTokenString = nsnull;
      char *tagToken           = nsCRT::strtok(copyCurrentCommand, WHITESPACE,&placeInTokenString);
      char *uidToken           = nsCRT::strtok(placeInTokenString, WHITESPACE,&placeInTokenString);
      char *fetchToken         = nsCRT::strtok(placeInTokenString, WHITESPACE,&placeInTokenString);
      uidToken = nsnull; // use variable to quiet compiler warning
      tagToken = nsnull; // use variable to quiet compiler warning
      if (!PL_strcasecmp(fetchToken, "FETCH") )
      {
        char *uidStringToken = nsCRT::strtok(placeInTokenString, WHITESPACE, &placeInTokenString);
        if (!PL_strchr(uidStringToken, ',') && !PL_strchr(uidStringToken, ':'))     // , and : are uid delimiters
        {
          fCurrentCommandIsSingleMessageFetch = PR_TRUE;
          fUidOfSingleMessageFetch = atoi(uidStringToken);
        }
      }
    }
    PL_strfree(copyCurrentCommand);
  }
}

Here is the call graph for this function:

Here is the caller graph for this function:

void nsImapServerResponseParser::ProcessBadCommand ( const char *  commandToken) [protected, virtual]

Definition at line 504 of file nsImapServerResponseParser.cpp.

{
  if (!PL_strcasecmp(commandToken, "LOGIN") ||
    !PL_strcasecmp(commandToken, "AUTHENTICATE"))
    fIMAPstate = kNonAuthenticated;
  else if (!PL_strcasecmp(commandToken, "LOGOUT"))
    fIMAPstate = kNonAuthenticated;       // ??
  else if (!PL_strcasecmp(commandToken, "SELECT") ||
    !PL_strcasecmp(commandToken, "EXAMINE"))
    fIMAPstate = kAuthenticated;   // nothing selected
  else if (!PL_strcasecmp(commandToken, "CLOSE"))
    fIMAPstate = kAuthenticated;   // nothing selected
  if (GetFillingInShell())
  {
    if (!m_shell->IsBeingGenerated())
    {
      delete m_shell;
      m_shell = nsnull;
    }
  }
}

Here is the call graph for this function:

Here is the caller graph for this function:

void nsImapServerResponseParser::ProcessOkCommand ( const char *  commandToken) [protected, virtual]

Definition at line 415 of file nsImapServerResponseParser.cpp.

{
  if (!PL_strcasecmp(commandToken, "LOGIN") ||
    !PL_strcasecmp(commandToken, "AUTHENTICATE"))
    fIMAPstate = kAuthenticated;
  else if (!PL_strcasecmp(commandToken, "LOGOUT"))
    fIMAPstate = kNonAuthenticated;
  else if (!PL_strcasecmp(commandToken, "SELECT") ||
    !PL_strcasecmp(commandToken, "EXAMINE"))
    fIMAPstate = kFolderSelected;
  else if (!PL_strcasecmp(commandToken, "CLOSE"))
  {
    fIMAPstate = kAuthenticated;
    // we no longer have a selected mailbox.
    PR_FREEIF( fSelectedMailboxName );
  }
  else if ((!PL_strcasecmp(commandToken, "LIST")) ||
                      (!PL_strcasecmp(commandToken, "LSUB")))
  {
    //fServerConnection.MailboxDiscoveryFinished();
    // This used to be reporting that we were finished
    // discovering folders for each time we issued a
    // LIST or LSUB.  So if we explicitly listed the
    // INBOX, or Trash, or namespaces, we would get multiple
    // "done" states, even though we hadn't finished.
    // Move this to be called from the connection object
    // itself.
  }
  else if (!PL_strcasecmp(commandToken, "FETCH"))
  {
    if (!fZeroLengthMessageUidString.IsEmpty())
    {
      // "Deleting zero length message");
      fServerConnection.Store(fZeroLengthMessageUidString.get(), "+Flags (\\Deleted)", PR_TRUE);
      if (LastCommandSuccessful())
        fServerConnection.Expunge();
      
      fZeroLengthMessageUidString.Truncate();
    }
  }
  if (GetFillingInShell())
  {
    // There is a BODYSTRUCTURE response.  Now let's generate the stream...
    // that is, if we're not doing it already
    if (!m_shell->IsBeingGenerated())
    {
      nsImapProtocol *navCon = &fServerConnection;
      
      char *imapPart = nsnull;
      
      fServerConnection.GetCurrentUrl()->GetImapPartToFetch(&imapPart);
      m_shell->Generate(imapPart);
      PR_Free(imapPart);
      
      if ((navCon && navCon->GetPseudoInterrupted())
        || fServerConnection.DeathSignalReceived())
      {
        // we were pseudointerrupted or interrupted
        if (!m_shell->IsShellCached())
        {
          // if it's not in the cache, then we were (pseudo)interrupted while generating
          // for the first time.  Delete it.
          delete m_shell;
        }
        navCon->PseudoInterrupt(PR_FALSE);
      }
      else if (m_shell->GetIsValid())
      {
        // If we have a valid shell that has not already been cached, then cache it.
        if (!m_shell->IsShellCached() && fHostSessionList)     // cache is responsible for destroying it
        {
          PR_LOG(IMAP, PR_LOG_ALWAYS, 
            ("BODYSHELL:  Adding shell to cache."));
          const char *serverKey = fServerConnection.GetImapServerKey();
          fHostSessionList->AddShellToCacheForHost(
            serverKey, m_shell);
        }
      }
      else
      {
        // The shell isn't valid, so we don't cache it.
        // Therefore, we have to destroy it here.
        delete m_shell;
      }
      m_shell = nsnull;
    }
  }
}

Here is the call graph for this function:

Here is the caller graph for this function:

void nsImapServerResponseParser::quota_data ( ) [protected, virtual]

Definition at line 2845 of file nsImapServerResponseParser.cpp.

{
  nsCString quotaroot;
  if (!PL_strcasecmp(fNextToken, "QUOTAROOT"))
  {
    nsCString quotaroot; 
    AdvanceToNextToken();
    while (ContinueParse() && !fAtEndOfLine)
    {
      quotaroot.Adopt(CreateAstring());
      AdvanceToNextToken();
    }
  }
  else if(!PL_strcasecmp(fNextToken, "QUOTA"))
  {
    PRUint32 used, max;
    char *parengroup;

    AdvanceToNextToken();
    if (! fNextToken)
      SetSyntaxError(PR_TRUE);
    else
    {
      quotaroot.Adopt(CreateAstring());

      if(ContinueParse() && !fAtEndOfLine)
      {
        AdvanceToNextToken();
        if(fNextToken)
        {
          if(!PL_strcasecmp(fNextToken, "(STORAGE"))
          {
            parengroup = CreateParenGroup();
            if(parengroup && (PR_sscanf(parengroup, "(STORAGE %lu %lu)", &used, &max) == 2) )
            {
              fServerConnection.UpdateFolderQuotaData(quotaroot, used, max);
              skip_to_CRLF();
            }
            else
              SetSyntaxError(PR_TRUE);

            PR_Free(parengroup);
          }
          else
            // Ignore other limits, we just check STORAGE for now
            skip_to_CRLF();
        }
        else
          SetSyntaxError(PR_TRUE);
      }
      else
        HandleMemoryFailure();
    }
  }
  else
    SetSyntaxError(PR_TRUE);
}

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 2926 of file nsImapServerResponseParser.cpp.

Here is the call graph for this function:

void nsImapServerResponseParser::ResetFlagInfo ( int  numberOfInterestingMessages)

Definition at line 3149 of file nsImapServerResponseParser.cpp.

{
  if (fFlagState)
    fFlagState->Reset(numberOfInterestingMessages);
}

Here is the caller graph for this function:

void nsIMAPGenericParser::ResetLexAnalyzer ( ) [protected, inherited]

Definition at line 106 of file nsImapServerResponseParser.h.

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 2021 of file nsImapServerResponseParser.cpp.

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 1720 of file nsImapServerResponseParser.cpp.

Here is the call graph for this function:

Here is the caller graph for this function:

void nsImapServerResponseParser::resp_text ( ) [protected, virtual]

Definition at line 1741 of file nsImapServerResponseParser.cpp.

{
  if (ContinueParse() && (*fNextToken == '['))
    resp_text_code();
              
  if (ContinueParse())
  {
    if (!PL_strcmp(fNextToken, "=?"))
      text_mime2();
    else
      text();
  }
}

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 1842 of file nsImapServerResponseParser.cpp.

{
  // this is a special case way of advancing the token
  // strtok won't break up "[ALERT]" into separate tokens
  if (strlen(fNextToken) > 1)
    fNextToken++;
  else 
    AdvanceToNextToken();
  
  if (ContinueParse())
  {
    if (!PL_strcasecmp(fNextToken,"ALERT]"))
    {
      char *alertMsg = fCurrentTokenPlaceHolder; // advance past ALERT]
      if (alertMsg && *alertMsg && (!fLastAlert || PL_strcmp(fNextToken, fLastAlert)))
      {
        fServerConnection.AlertUserEvent(alertMsg);
        PR_Free(fLastAlert);
        fLastAlert = PL_strdup(alertMsg);
      }
      AdvanceToNextToken();
    }
    else if (!PL_strcasecmp(fNextToken,"PARSE]"))
    {
      // do nothing for now
      AdvanceToNextToken();
    }
    else if (!PL_strcasecmp(fNextToken,"NETSCAPE]"))
    {
      skip_to_CRLF();
    }
    else if (!PL_strcasecmp(fNextToken,"PERMANENTFLAGS"))
    {
      PRUint32 saveSettableFlags = fSettablePermanentFlags;
      fSupportsUserDefinedFlags = 0;             // assume no unless told
      fSettablePermanentFlags = 0;            // assume none, unless told otherwise.
      parse_folder_flags();
      // if the server tells us there are no permanent flags, we're
      // just going to pretend that the FLAGS response flags, if any, are
      // permanent in case the server is broken. This will allow us
      // to store delete and seen flag changes - if they're not permanent, 
      // they're not permanent, but at least we'll try to set them.
      if (!fSettablePermanentFlags)
        fSettablePermanentFlags = saveSettableFlags;
      fGotPermanentFlags = PR_TRUE;
    }
    else if (!PL_strcasecmp(fNextToken,"READ-ONLY]"))
    {
      fCurrentFolderReadOnly = PR_TRUE;
      AdvanceToNextToken();
    }
    else if (!PL_strcasecmp(fNextToken,"READ-WRITE]"))
    {
      fCurrentFolderReadOnly = PR_FALSE;
      AdvanceToNextToken();
    }
    else if (!PL_strcasecmp(fNextToken,"TRYCREATE]"))
    {
      // do nothing for now
      AdvanceToNextToken();
    }
    else if (!PL_strcasecmp(fNextToken,"UIDVALIDITY"))
    {
      AdvanceToNextToken();
      if (ContinueParse())
      {
        fFolderUIDValidity = atoi(fNextToken);
        fHighestRecordedUID = 0;
        AdvanceToNextToken();
      }
    }
    else if (!PL_strcasecmp(fNextToken,"UNSEEN"))
    {
      AdvanceToNextToken();
      if (ContinueParse())
      {
        fNumberOfUnseenMessages = atoi(fNextToken);
        AdvanceToNextToken();
      }
    }
    else if (!PL_strcasecmp(fNextToken, "APPENDUID"))
    {
      AdvanceToNextToken();
      if (ContinueParse())
      {
        // ** jt -- the returned uidvalidity is the destination folder
        // uidvalidity; don't use it for current folder
        // fFolderUIDValidity = atoi(fNextToken);
        // fHighestRecordedUID = 0; ??? this should be wrong
        AdvanceToNextToken();
        if (ContinueParse())
        {
          fCurrentResponseUID = atoi(fNextToken);
          AdvanceToNextToken();
        }
      }
    }
    else if (!PL_strcasecmp(fNextToken, "COPYUID"))
    {
      AdvanceToNextToken();
      if (ContinueParse())
      {
        // ** jt -- destination folder uidvalidity
        // fFolderUIDValidity = atoi(fNextToken);
        // original message set; ignore it
        AdvanceToNextToken();
        if (ContinueParse())
        {
          // the resulting message set; should be in the form of
          // either uid or uid1:uid2
          AdvanceToNextToken();
          // clear copy response uid
          fServerConnection.SetCopyResponseUid(fNextToken);
        }
        if (ContinueParse())
          AdvanceToNextToken();
      }
    }
    else      // just text
    {
      // do nothing but eat tokens until we see the ] or CRLF
      // we should see the ] but we don't want to go into an
      // endless loop if the CRLF is not there
      do 
      {
        AdvanceToNextToken();
      } while (!PL_strcasestr(fNextToken, "]") && !fAtEndOfLine 
                && ContinueParse());
    }
  }
}

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 547 of file nsImapServerResponseParser.cpp.

{
  AdvanceToNextToken();
  
  if (ContinueParse())
  {
    switch (toupper(fNextToken[0]))
    {
    case 'O':               // OK
      if (toupper(fNextToken[1]) == 'K')
        resp_cond_state();
      else SetSyntaxError(PR_TRUE);
      break;
    case 'N':               // NO
      if (toupper(fNextToken[1]) == 'O')
        resp_cond_state();
      else if (!PL_strcasecmp(fNextToken, "NAMESPACE"))
        namespace_data();
      else SetSyntaxError(PR_TRUE);
      break;
    case 'B':               // BAD
      if (!PL_strcasecmp(fNextToken, "BAD"))
        resp_cond_state();
      else if (!PL_strcasecmp(fNextToken, "BYE"))
        resp_cond_bye();
      else SetSyntaxError(PR_TRUE);
      break;
    case 'F':
      if (!PL_strcasecmp(fNextToken, "FLAGS"))
        mailbox_data();
      else SetSyntaxError(PR_TRUE);
      break;
    case 'P':
      if (PL_strcasecmp(fNextToken, "PERMANENTFLAGS"))
        mailbox_data();
      else SetSyntaxError(PR_TRUE);
      break;
    case 'L':
      if (!PL_strcasecmp(fNextToken, "LIST")  || !PL_strcasecmp(fNextToken, "LSUB"))
        mailbox_data();
      else if (!PL_strcasecmp(fNextToken, "LANGUAGE"))
        language_data();
      else
        SetSyntaxError(PR_TRUE);
      break;
    case 'M':
      if (!PL_strcasecmp(fNextToken, "MAILBOX"))
        mailbox_data();
      else if (!PL_strcasecmp(fNextToken, "MYRIGHTS"))
        myrights_data();
      else SetSyntaxError(PR_TRUE);
      break;
    case 'S':
      if (!PL_strcasecmp(fNextToken, "SEARCH"))
        mailbox_data();
      else if (!PL_strcasecmp(fNextToken, "STATUS"))
      {
        AdvanceToNextToken();
        if (fNextToken)
        {
          char *mailboxName = CreateAstring();
          PL_strfree( mailboxName); 
        }
        while (      ContinueParse() &&
          !fAtEndOfLine )
        {
          AdvanceToNextToken();
          if (!fNextToken)
            break;
          
          if (*fNextToken == '(') fNextToken++;
          if (!PL_strcasecmp(fNextToken, "UIDNEXT"))
          {
            AdvanceToNextToken();
            if (fNextToken)
            {
              fStatusNextUID = atoi(fNextToken);
              // if this token ends in ')', then it is the last token
              // else we advance
              if ( *(fNextToken + strlen(fNextToken) - 1) == ')')
                fNextToken += strlen(fNextToken) - 1;
            }
          }
          else if (!PL_strcasecmp(fNextToken, "MESSAGES"))
          {
            AdvanceToNextToken();
            if (fNextToken)
            {
              fStatusExistingMessages = atoi(fNextToken);
              // if this token ends in ')', then it is the last token
              // else we advance
              if ( *(fNextToken + strlen(fNextToken) - 1) == ')')
                fNextToken += strlen(fNextToken) - 1;
            }
          }
          else if (!PL_strcasecmp(fNextToken, "UNSEEN"))
          {
            AdvanceToNextToken();
            if (fNextToken)
            {
              fStatusUnseenMessages = atoi(fNextToken);
              // if this token ends in ')', then it is the last token
              // else we advance
              if ( *(fNextToken + strlen(fNextToken) - 1) == ')')
                fNextToken += strlen(fNextToken) - 1;
            }
          }
          else if (!PL_strcasecmp(fNextToken, "RECENT"))
          {
            AdvanceToNextToken();
            if (fNextToken)
            {
              fStatusRecentMessages = atoi(fNextToken);
              // if this token ends in ')', then it is the last token
              // else we advance
              if ( *(fNextToken + strlen(fNextToken) - 1) == ')')
                fNextToken += strlen(fNextToken) - 1;
            }
          }
          else if (*fNextToken == ')')
            break;
          else if (!fAtEndOfLine)
            SetSyntaxError(PR_TRUE);
        } 
      } else SetSyntaxError(PR_TRUE);
      break;
    case 'C':
      if (!PL_strcasecmp(fNextToken, "CAPABILITY"))
        capability_data();
      else SetSyntaxError(PR_TRUE);
      break;
    case 'V':
      if (!PL_strcasecmp(fNextToken, "VERSION"))
      {
        // figure out the version of the Netscape server here
        PR_FREEIF(fNetscapeServerVersionString);
        AdvanceToNextToken();
        if (! fNextToken) 
          SetSyntaxError(PR_TRUE);
        else
        {
          fNetscapeServerVersionString = CreateAstring();
          AdvanceToNextToken();
          if (fNetscapeServerVersionString)
          {
            fServerIsNetscape3xServer = (*fNetscapeServerVersionString == '3');
          }
        }
        skip_to_CRLF();
      }
      else SetSyntaxError(PR_TRUE);
      break;
    case 'A':
      if (!PL_strcasecmp(fNextToken, "ACL"))
      {
        acl_data();
      }
      else if (!PL_strcasecmp(fNextToken, "ACCOUNT-URL"))
      {
        PR_FREEIF(fMailAccountUrl);
        AdvanceToNextToken();
        if (! fNextToken) 
          SetSyntaxError(PR_TRUE);
        else
        {
          fMailAccountUrl = CreateAstring();
          AdvanceToNextToken();
        }
      } 
      else SetSyntaxError(PR_TRUE);
      break;
    case 'X':
      if (!PL_strcasecmp(fNextToken, "XSERVERINFO"))
        xserverinfo_data();
      else if (!PL_strcasecmp(fNextToken, "XMAILBOXINFO"))
        xmailboxinfo_data();
      else if (!PL_strcasecmp(fNextToken, "XAOL-OPTION"))
        skip_to_CRLF();
      else 
      {
        // check if custom command
        nsXPIDLCString customCommand;
        fServerConnection.GetCurrentUrl()->GetCommand(getter_Copies(customCommand));
        if (customCommand.Equals(fNextToken))
        {
          nsCAutoString customCommandResponse;
          while (Connected() && !fAtEndOfLine)
          {
            AdvanceToNextToken();
            customCommandResponse.Append(fNextToken);
            customCommandResponse.Append(" ");
          }
          fServerConnection.GetCurrentUrl()->SetCustomCommandResult(customCommandResponse.get());
        }
        else
          SetSyntaxError(PR_TRUE);
      }
      break;
    case 'Q':
      if (!PL_strcasecmp(fNextToken, "QUOTAROOT")  || !PL_strcasecmp(fNextToken, "QUOTA"))
        quota_data();
      else
        SetSyntaxError(PR_TRUE);
      break;
    default:
      if (IsNumericString(fNextToken))
        numeric_mailbox_data();
      else
        SetSyntaxError(PR_TRUE);
      break;
    }
    
    if (ContinueParse())
      PostProcessEndOfLine();
  }
}

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 1977 of file nsImapServerResponseParser.cpp.

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 2010 of file nsImapServerResponseParser.cpp.

 {
   // eat the "*"
   AdvanceToNextToken();
   if (ContinueParse())
     resp_cond_bye();
 }

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 1990 of file nsImapServerResponseParser.cpp.

Here is the call graph for this function:

Here is the caller graph for this function: