Back to index

lightning-sunbird  0.9+nobinonly
Public Member Functions | Static Public Member Functions | Private Member Functions | Private Attributes
nsPop3Protocol Class Reference

#include <nsPop3Protocol.h>

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

List of all members.

Public Member Functions

 nsPop3Protocol (nsIURI *aURL)
virtual ~nsPop3Protocol ()
NS_DECL_ISUPPORTS_INHERITED
NS_DECL_NSIPOP3PROTOCOL
nsresult 
Initialize (nsIURI *aURL)
virtual nsresult LoadUrl (nsIURI *aURL, nsISupports *aConsumer=nsnull)
const char * GetUsername ()
void SetUsername (const char *name)
nsresult GetPassword (char **aPassword, PRBool *okayValue)
NS_IMETHOD OnTransportStatus (nsITransport *transport, nsresult status, PRUint32 progress, PRUint32 progressMax)
NS_IMETHOD OnStopRequest (nsIRequest *request, nsISupports *aContext, nsresult aStatus)
NS_IMETHOD Cancel (nsresult status)
void markMessages (in nsVoidArray aUidl)
boolean checkMessage (in string aUidl)

Static Public Member Functions

static void MarkMsgInHashTable (PLHashTable *hashTable, const Pop3UidlEntry *uidl, PRBool *changed)
static nsresult MarkMsgForHost (const char *hostName, const char *userName, nsIFileSpec *mailDirectory, nsVoidArray &UIDLArray)

Private Member Functions

void UpdateProgressPercent (PRUint32 totalDone, PRUint32 total)
void UpdateStatus (PRInt32 aStatusID)
void UpdateStatusWithString (const PRUnichar *aString)
virtual nsresult ProcessProtocolState (nsIURI *url, nsIInputStream *inputStream, PRUint32 sourceOffset, PRUint32 length)
virtual nsresult CloseSocket ()
virtual PRInt32 SendData (nsIURI *aURL, const char *dataBuffer, PRBool aSuppressLogging=PR_FALSE)
void FreeMsgInfo ()
void Abort ()
void SetCapFlag (PRUint32 flag)
void ClearCapFlag (PRUint32 flag)
PRBool TestCapFlag (PRUint32 flag)
void BackupAuthFlags ()
void RestoreAuthFlags ()
nsresult HandleLine (char *line, PRUint32 line_length)
nsresult GetApopTimestamp ()
PRInt32 WaitForStartOfConnectionResponse (nsIInputStream *inputStream, PRUint32 length)
PRInt32 WaitForResponse (nsIInputStream *inputStream, PRUint32 length)
PRInt32 Error (PRInt32 err_code)
PRInt32 SendAuth ()
PRInt32 AuthResponse (nsIInputStream *inputStream, PRUint32 length)
PRInt32 SendCapa ()
PRInt32 CapaResponse (nsIInputStream *inputStream, PRUint32 length)
PRInt32 SendTLSResponse ()
PRInt32 ProcessAuth ()
PRInt32 AuthFallback ()
PRInt32 AuthLogin ()
PRInt32 AuthLoginResponse ()
PRInt32 AuthNtlm ()
PRInt32 AuthNtlmResponse ()
PRInt32 AuthGSSAPI ()
PRInt32 AuthGSSAPIResponse (PRBool first)
PRInt32 SendUsername ()
PRInt32 SendPassword ()
PRInt32 SendStatOrGurl (PRBool sendStat)
PRInt32 SendStat ()
PRInt32 GetStat ()
PRInt32 SendGurl ()
PRInt32 GurlResponse ()
PRInt32 SendList ()
PRInt32 GetList (nsIInputStream *inputStream, PRUint32 length)
PRInt32 SendFakeUidlTop ()
PRInt32 StartUseTopForFakeUidl ()
PRInt32 GetFakeUidlTop (nsIInputStream *inputStream, PRUint32 length)
PRInt32 SendXtndXlstMsgid ()
PRInt32 GetXtndXlstMsgid (nsIInputStream *inputStream, PRUint32 length)
PRInt32 SendUidlList ()
PRInt32 GetUidlList (nsIInputStream *inputStream, PRUint32 length)
PRInt32 GetMsg ()
PRInt32 SendTop ()
PRInt32 SendXsender ()
PRInt32 XsenderResponse ()
PRInt32 SendRetr ()
PRInt32 RetrResponse (nsIInputStream *inputStream, PRUint32 length)
PRInt32 TopResponse (nsIInputStream *inputStream, PRUint32 length)
PRInt32 SendDele ()
PRInt32 DeleResponse ()
PRInt32 CommitState (PRBool remove_last_entry)

Private Attributes

nsCString m_ApopTimestamp
nsCOMPtr< nsIMsgStringServicemStringService
nsCString m_username
nsCString m_senderInfo
nsCString m_commandResponse
nsCOMPtr< nsIMsgStatusFeedbackm_statusFeedback
nsCString m_GSSAPICache
PRInt32 m_bytesInMsgReceived
PRInt32 m_totalFolderSize
PRInt32 m_totalDownloadSize
PRInt32 m_totalBytesReceived
nsCOMPtr< nsIURIm_url
nsCOMPtr< nsIPop3Sinkm_nsIPop3Sink
nsCOMPtr< nsIPop3IncomingServerm_pop3Server
nsMsgLineStreamBuffer * m_lineStreamBuffer
Pop3ConDatam_pop3ConData
PRBool m_parsingMultiLineMessageId
PRBool m_tlsEnabled
PRInt32 m_socketType
PRBool m_useSecAuth
PRBool m_password_already_sent
PRInt32 m_origAuthFlags
PRInt32 m_listpos

Detailed Description

Definition at line 292 of file nsPop3Protocol.h.


Constructor & Destructor Documentation


Member Function Documentation

void nsPop3Protocol::Abort ( ) [private]

Definition at line 790 of file nsPop3Protocol.cpp.

{
  if(m_pop3ConData->msg_closure)
  {
      m_nsIPop3Sink->IncorporateAbort(m_pop3ConData->only_uidl != nsnull);
      m_pop3ConData->msg_closure = nsnull;
  }
  // need this to close the stream on the inbox.
  m_nsIPop3Sink->AbortMailDelivery(this);
  m_pop3Server->SetRunningProtocol(nsnull);

}

Here is the caller graph for this function:

Definition at line 1478 of file nsPop3Protocol.cpp.

{
    if (m_pop3ConData->command_succeeded)
        if(m_password_already_sent)
        {
            m_nsIPop3Sink->SetUserAuthenticated(PR_TRUE);
            ClearFlag(POP3_PASSWORD_FAILED);
            m_pop3ConData->next_state = (m_pop3ConData->get_url) 
              ? POP3_SEND_GURL : POP3_SEND_STAT;
        }
        else
            m_pop3ConData->next_state = POP3_SEND_PASSWORD;
    else
    {
        // response code received shows that login failed not because of
        // wrong credential -> stop login without retry or pw dialog, only alert
        if (TestFlag(POP3_STOPLOGIN))
            return(Error((m_password_already_sent) 
                         ? POP3_PASSWORD_FAILURE : POP3_USERNAME_FAILURE));

        // response code received shows that server is certain about the
        // credential was wrong, or fallback has been disabled by pref
        // -> no fallback, show alert and pw dialog
        PRBool logonFallback = PR_TRUE;
        nsCOMPtr<nsIMsgIncomingServer> server = do_QueryInterface(m_pop3Server);
        if (server)
          server->GetLogonFallback(&logonFallback);
        if (!logonFallback)
          SetFlag(POP3_AUTH_FAILURE);

        if (TestFlag(POP3_AUTH_FAILURE))
        {
            Error((m_password_already_sent) 
                         ? POP3_PASSWORD_FAILURE : POP3_USERNAME_FAILURE);
            SetFlag(POP3_PASSWORD_FAILED);
            ClearFlag(POP3_AUTH_FAILURE);
            m_pop3ConData->logonFailureCount++;
            return 0;
        }

        // we have no certain response code -> fallback and try again
        if (m_useSecAuth)
        {
            // If one authentication failed, we're going to
            // fall back on a less secure login method.
            if (TestCapFlag(POP3_HAS_AUTH_GSSAPI))
                ClearCapFlag(POP3_HAS_AUTH_GSSAPI);
            else if (TestCapFlag(POP3_HAS_AUTH_CRAM_MD5))
                // if CRAM-MD5 enabled, disable it
                ClearCapFlag(POP3_HAS_AUTH_CRAM_MD5);
            else if (TestCapFlag(POP3_HAS_AUTH_NTLM))
                // if NTLM enabled, disable it
                ClearCapFlag(POP3_HAS_AUTH_NTLM|POP3_HAS_AUTH_MSN);
            else if (TestCapFlag(POP3_HAS_AUTH_APOP))
            {
                // if APOP enabled, disable it
                ClearCapFlag(POP3_HAS_AUTH_APOP);
                // unsure because APOP failed and we can't determine why
                Error(CANNOT_PROCESS_APOP_AUTH);
            }
        }
        else
        {
            // If one authentication failed, we're going to
            // fall back on a less secure login method.
            if (TestCapFlag(POP3_HAS_AUTH_PLAIN))
                // if PLAIN enabled, disable it
                ClearCapFlag(POP3_HAS_AUTH_PLAIN);
            else if(TestCapFlag(POP3_HAS_AUTH_LOGIN))
                // if LOGIN enabled, disable it
                ClearCapFlag(POP3_HAS_AUTH_LOGIN);
            else if(TestCapFlag(POP3_HAS_AUTH_USER))
            {
                if(m_password_already_sent)
                    // if USER enabled, disable it
                    ClearCapFlag(POP3_HAS_AUTH_USER);
                else
                    // if USER enabled,
                    // it was the username which was wrong -
                    // no fallback but return error
                    return(Error(POP3_USERNAME_FAILURE));
            }
        }

        // Only forget the password if we've no mechanism left.
        if (m_useSecAuth && !TestCapFlag(POP3_HAS_AUTH_ANY_SEC) ||
            !m_useSecAuth && !TestCapFlag(POP3_HAS_AUTH_ANY))
        {
            // Let's restore the original auth flags from AuthResponse so we can
            // try them again with new password and username
            RestoreAuthFlags();
            m_pop3Server->SetPop3CapabilityFlags(m_pop3ConData->capability_flags);

            Error(POP3_PASSWORD_FAILURE);
            /* The password failed.
      
               Sever the connection and go back to the `read password' state,
               which, upon success, will re-open the connection.  Set a flag
               which causes the prompt to be different that time (to indicate
               that the old password was bogus.)
        
               But if we're just checking for new mail (biff) then don't bother
               prompting the user for a password: just fail silently. 
            */

            SetFlag(POP3_PASSWORD_FAILED);
            m_pop3ConData->logonFailureCount++;

            if (m_nsIPop3Sink) 
                m_nsIPop3Sink->SetMailAccountURL(NULL);

            return 0;
        }

        m_pop3Server->SetPop3CapabilityFlags(m_pop3ConData->capability_flags);

        m_pop3ConData->command_succeeded = PR_TRUE;

        m_pop3ConData->next_state = POP3_PROCESS_AUTH;
    }

    if (TestCapFlag(POP3_AUTH_MECH_UNDEFINED))
    {
        ClearCapFlag(POP3_AUTH_MECH_UNDEFINED);
        m_pop3Server->SetPop3CapabilityFlags(m_pop3ConData->capability_flags);
    }
    
    m_pop3ConData->pause_for_read = PR_FALSE;

    return 0;
}

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 1675 of file nsPop3Protocol.cpp.

{
    nsCOMPtr<nsIMsgIncomingServer> server = do_QueryInterface(m_pop3Server);
    if (server) {
        nsCAutoString cmd;
        nsCAutoString service("pop@");
        nsXPIDLCString hostName;
        nsresult rv;

        server->GetRealHostName(getter_Copies(hostName));
        service.Append(hostName);
        rv = DoGSSAPIStep1(service.get(), m_username.get(), cmd);
        if (NS_SUCCEEDED(rv)) {
            m_GSSAPICache.Assign(cmd);
            m_pop3ConData->next_state_after_response = POP3_AUTH_GSSAPI_FIRST;
            m_pop3ConData->pause_for_read = PR_TRUE;
            return SendData(m_url, "AUTH GSSAPI" CRLF);
        }
    }

    ClearCapFlag(POP3_HAS_AUTH_GSSAPI);
    m_pop3ConData->next_state = POP3_PROCESS_AUTH;
    m_pop3ConData->pause_for_read = PR_FALSE;
    return NS_OK;
}

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 1701 of file nsPop3Protocol.cpp.

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 1613 of file nsPop3Protocol.cpp.

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 1622 of file nsPop3Protocol.cpp.

{
    // need the test to be here instead in AuthFallback() to
    // differentiate between command AUTH LOGIN failed and
    // sending username using LOGIN mechanism failed.
    if (!m_pop3ConData->command_succeeded) 
    {
        // we failed with LOGIN, remove it
        ClearCapFlag(POP3_HAS_AUTH_LOGIN);

        m_pop3ConData->next_state = POP3_PROCESS_AUTH;
    }
    else
        m_pop3ConData->next_state = POP3_SEND_USERNAME;

    m_pop3ConData->pause_for_read = PR_FALSE;

    return 0;
}

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 1645 of file nsPop3Protocol.cpp.

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 1655 of file nsPop3Protocol.cpp.

{
    // need the test to be here instead in AuthFallback() to
    // differentiate between command AUTH NTLM failed and
    // sending username using NTLM mechanism failed.
    if (!m_pop3ConData->command_succeeded) 
    {
        // we failed with NTLM, remove it
        ClearCapFlag(POP3_HAS_AUTH_NTLM|POP3_HAS_AUTH_MSN);

        m_pop3ConData->next_state = POP3_PROCESS_AUTH;
    }
    else
        m_pop3ConData->next_state = POP3_SEND_USERNAME;

    m_pop3ConData->pause_for_read = PR_FALSE;

    return 0;
}

Here is the call graph for this function:

Here is the caller graph for this function:

PRInt32 nsPop3Protocol::AuthResponse ( nsIInputStream inputStream,
PRUint32  length 
) [private]

Definition at line 1154 of file nsPop3Protocol.cpp.

{
    char * line;
    PRUint32 ln = 0;
    nsresult rv;

    if (TestCapFlag(POP3_AUTH_MECH_UNDEFINED))
    {
        ClearCapFlag(POP3_AUTH_MECH_UNDEFINED);
        m_pop3Server->SetPop3CapabilityFlags(m_pop3ConData->capability_flags);
    }
    
    if (!m_pop3ConData->command_succeeded) 
    {
        /* AUTH command not implemented 
         * so no secure mechanisms available
         */
        m_pop3ConData->command_succeeded = PR_TRUE;
        m_pop3Server->SetPop3CapabilityFlags(m_pop3ConData->capability_flags);
        m_pop3ConData->next_state = POP3_SEND_CAPA;
        return 0;
    }
    
    PRBool pauseForMoreData = PR_FALSE;
    line = m_lineStreamBuffer->ReadNextLine(inputStream, ln, pauseForMoreData, &rv);
    if (NS_FAILED(rv))
      return -1;

    if(pauseForMoreData || !line) 
    {
        m_pop3ConData->pause_for_read = PR_TRUE; /* pause */
        PR_Free(line);
        return(0);
    }
    
    PR_LOG(POP3LOGMODULE, PR_LOG_ALWAYS,("RECV: %s", line));

    if (!PL_strcmp(line, ".")) 
    {
        m_pop3Server->SetPop3CapabilityFlags(m_pop3ConData->capability_flags);

        // now that we've read all the AUTH responses, go for it
        m_pop3ConData->next_state = POP3_SEND_CAPA;
        m_pop3ConData->pause_for_read = PR_FALSE; /* don't pause */
    }
    else if (!PL_strcasecmp (line, "CRAM-MD5")) 
    {
        nsCOMPtr<nsISignatureVerifier> verifier = do_GetService(SIGNATURE_VERIFIER_CONTRACTID, &rv);
        // this checks if psm is installed...
        if (NS_SUCCEEDED(rv))
            SetCapFlag(POP3_HAS_AUTH_CRAM_MD5);
    }
    else if (!PL_strcasecmp (line, "NTLM")) 
    {
        nsCOMPtr<nsISignatureVerifier> verifier = do_GetService(SIGNATURE_VERIFIER_CONTRACTID, &rv);
        // this checks if psm is installed...
        if (NS_SUCCEEDED(rv))
            SetCapFlag(POP3_HAS_AUTH_NTLM);
    }
    else if (!PL_strcasecmp (line, "MSN"))
    {
        nsCOMPtr<nsISignatureVerifier> verifier = do_GetService(SIGNATURE_VERIFIER_CONTRACTID, &rv);
        // this checks if psm is installed...
        if (NS_SUCCEEDED(rv))
            SetCapFlag(POP3_HAS_AUTH_NTLM|POP3_HAS_AUTH_MSN);
    }
    else if (!PL_strcasecmp (line, "GSSAPI"))
        SetCapFlag(POP3_HAS_AUTH_GSSAPI);
    else if (!PL_strcasecmp (line, "PLAIN")) 
        SetCapFlag(POP3_HAS_AUTH_PLAIN);
    else if (!PL_strcasecmp (line, "LOGIN")) 
        SetCapFlag(POP3_HAS_AUTH_LOGIN);

    PR_Free(line);
    return 0;
}

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 1467 of file nsPop3Protocol.cpp.

Here is the caller graph for this function:

Definition at line 803 of file nsPop3Protocol.cpp.

Here is the call graph for this function:

PRInt32 nsPop3Protocol::CapaResponse ( nsIInputStream inputStream,
PRUint32  length 
) [private]

Definition at line 1252 of file nsPop3Protocol.cpp.

{
    char * line;
    PRUint32 ln = 0;

    if (!m_pop3ConData->command_succeeded) 
    {
        /* CAPA command not implemented */
        m_pop3ConData->command_succeeded = PR_TRUE;
        m_pop3Server->SetPop3CapabilityFlags(m_pop3ConData->capability_flags);
        m_pop3ConData->next_state = POP3_PROCESS_AUTH;
        return 0;
    }

    PRBool pauseForMoreData = PR_FALSE;
    nsresult rv;
    line = m_lineStreamBuffer->ReadNextLine(inputStream, ln, pauseForMoreData, &rv);
    if (NS_FAILED(rv))
      return -1;

    if(pauseForMoreData || !line) 
    {
        m_pop3ConData->pause_for_read = PR_TRUE; /* pause */
        PR_Free(line);
        return(0);
    }
    
    PR_LOG(POP3LOGMODULE, PR_LOG_ALWAYS,("RECV: %s", line));

    if (!PL_strcmp(line, ".")) 
    {
        // now that we've read all the CAPA responses, go for it
        m_pop3ConData->next_state = POP3_PROCESS_AUTH;
        m_pop3ConData->pause_for_read = PR_FALSE; /* don't pause */
    }
    else
    if (!PL_strcasecmp(line, "XSENDER")) 
    {
        SetCapFlag(POP3_HAS_XSENDER);
        m_pop3Server->SetPop3CapabilityFlags(m_pop3ConData->capability_flags);
    }
    else
    // see RFC 2449, chapter 6.4
    if (!PL_strcasecmp(line, "RESP-CODES")) 
    {
        SetCapFlag(POP3_HAS_RESP_CODES);
        m_pop3Server->SetPop3CapabilityFlags(m_pop3ConData->capability_flags);
    }
    else
    // see RFC 3206, chapter 6
    if (!PL_strcasecmp(line, "AUTH-RESP-CODE")) 
    {
        SetCapFlag(POP3_HAS_AUTH_RESP_CODE);
        m_pop3Server->SetPop3CapabilityFlags(m_pop3ConData->capability_flags);
    }
    else
    // see RFC 2595, chapter 4
    if (!PL_strcasecmp(line, "STLS")) 
    {
        nsresult rv;
        nsCOMPtr<nsISignatureVerifier> verifier = do_GetService(SIGNATURE_VERIFIER_CONTRACTID, &rv);
        // this checks if psm is installed...
        if (NS_SUCCEEDED(rv))
        {
            SetCapFlag(POP3_HAS_STLS);
            m_pop3Server->SetPop3CapabilityFlags(m_pop3ConData->capability_flags);
        }
    }
    else
    // see RFC 2449, chapter 6.3
    if (!PL_strncasecmp(line, "SASL", 4) && strlen(line) > 6)
    {
        nsCAutoString responseLine;
        responseLine.Assign(line + 5);

        if (responseLine.Find("PLAIN", PR_TRUE) >= 0)  
            SetCapFlag(POP3_HAS_AUTH_PLAIN);

        if (responseLine.Find("LOGIN", PR_TRUE) >= 0)  
            SetCapFlag(POP3_HAS_AUTH_LOGIN);

        if (responseLine.Find("GSSAPI", PR_TRUE) >= 0)
            SetCapFlag(POP3_HAS_AUTH_GSSAPI);

        nsresult rv;
        nsCOMPtr<nsISignatureVerifier> verifier = do_GetService(SIGNATURE_VERIFIER_CONTRACTID, &rv);
        // this checks if psm is installed...
        if (NS_SUCCEEDED(rv))
        {
            if (responseLine.Find("CRAM-MD5", PR_TRUE) >= 0)
                SetCapFlag(POP3_HAS_AUTH_CRAM_MD5);

            if (responseLine.Find("NTLM", PR_TRUE) >= 0)  
                SetCapFlag(POP3_HAS_AUTH_NTLM);

            if (responseLine.Find("MSN", PR_TRUE) >= 0)
                SetCapFlag(POP3_HAS_AUTH_NTLM|POP3_HAS_AUTH_MSN);
        }

        m_pop3Server->SetPop3CapabilityFlags(m_pop3ConData->capability_flags);
        // for use after mechs disabled fallbacks when login failed
        BackupAuthFlags();
    }

    PR_Free(line);
    return 0;
}

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 646 of file nsPop3Protocol.cpp.

Here is the caller graph for this function:

nsresult nsPop3Protocol::CloseSocket ( ) [private, virtual]

Definition at line 4039 of file nsPop3Protocol.cpp.

Here is the caller graph for this function:

PRInt32 nsPop3Protocol::CommitState ( PRBool  remove_last_entry) [private]

Definition at line 3521 of file nsPop3Protocol.cpp.

{
  /* If we are leaving messages on the server, pull out the last
    uidl from the hash, because it might have been put in there before
    we got it into the database. 
  */
  if (remove_last_entry && m_pop3ConData->msg_info && 
      m_pop3ConData->last_accessed_msg < m_pop3ConData->number_of_messages) 
  {
    Pop3MsgInfo* info = m_pop3ConData->msg_info + m_pop3ConData->last_accessed_msg; 
    if (info && info->uidl && !m_pop3ConData->only_uidl &&
      m_pop3ConData->newuidl && m_pop3ConData->newuidl->nentries > 0) 
    {  
      PRBool val = PL_HashTableRemove (m_pop3ConData->newuidl, info->uidl);
      NS_ASSERTION(val, "uidl not in hash table");
    }
  }
  
  // only use newuidl if we successfully finished looping through all the
  // messages in the inbox.
  if (m_pop3ConData->newuidl)
  {
    if (m_pop3ConData->last_accessed_msg >= m_pop3ConData->number_of_messages)
    {
      PL_HashTableDestroy(m_pop3ConData->uidlinfo->hash);
      m_pop3ConData->uidlinfo->hash = m_pop3ConData->newuidl;
      m_pop3ConData->newuidl = nsnull;
    }
    else
    {
      /* If we are leaving messages on the server, pull out the last
        uidl from the hash, because it might have been put in there before
        we got it into the database.
      */
      if (remove_last_entry && m_pop3ConData->msg_info &&
          !m_pop3ConData->only_uidl && m_pop3ConData->newuidl->nentries > 0)
      {
        Pop3MsgInfo* info = m_pop3ConData->msg_info + m_pop3ConData->last_accessed_msg;
        if (info && info->uidl)
        {
          PRBool val = PL_HashTableRemove(m_pop3ConData->newuidl, info->uidl);
          NS_ASSERTION(val, "uidl not in hash table");
        }
      }

      // Add the entries in newuidl to m_pop3ConData->uidlinfo->hash to keep
      // track of the messages we *did* download in this session.
      PL_HashTableEnumerateEntries(m_pop3ConData->newuidl, net_pop3_copy_hash_entries, (void *)m_pop3ConData->uidlinfo->hash);
    }
  }
  
  if (!m_pop3ConData->only_check_for_new_mail) 
  {
    nsresult rv;
    nsCOMPtr<nsIFileSpec> mailDirectory;
    
    // get the mail directory
    nsCOMPtr<nsIMsgIncomingServer> server =
      do_QueryInterface(m_pop3Server, &rv);
    if (NS_FAILED(rv)) return -1;
    
    rv = server->GetLocalPath(getter_AddRefs(mailDirectory));
    if (NS_FAILED(rv)) return -1;
    
    // write the state in the mail directory
    net_pop3_write_state(m_pop3ConData->uidlinfo,
      mailDirectory);
  }
  return 0;
}

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 3467 of file nsPop3Protocol.cpp.

{
    Pop3UidlHost *host = NULL;
       
    host = m_pop3ConData->uidlinfo;

    /* the return from the delete will come here
     */
    if(!m_pop3ConData->command_succeeded)
        return(Error(POP3_DELE_FAILURE));
    
    
    /* ###chrisf
        the delete succeeded.  Write out state so that we
        keep track of all the deletes which have not yet been
        committed on the server.  Flush this state upon successful
        QUIT.
        
        We will do this by adding each successfully deleted message id
        to a list which we will write out to popstate.dat in 
        net_pop3_write_state().
        */
    if (host)
    {
        if (m_pop3ConData->msg_info &&
            m_pop3ConData->msg_info[m_pop3ConData->last_accessed_msg-1].uidl)
        { 
            if (m_pop3ConData->newuidl)
              if (m_pop3ConData->leave_on_server)
              {
                PL_HashTableRemove(m_pop3ConData->newuidl, (void*)
                  m_pop3ConData->msg_info[m_pop3ConData->last_accessed_msg-1].uidl); 
              }
              else
              {
                put_hash(m_pop3ConData->newuidl,
                  m_pop3ConData->msg_info[m_pop3ConData->last_accessed_msg-1].uidl, DELETE_CHAR, 0);   
                /* kill message in new hash table */
              }
            else
                PL_HashTableRemove(host->hash, 
              (void*) m_pop3ConData->msg_info[m_pop3ConData->last_accessed_msg-1].uidl);
        }
    }

    m_pop3ConData->next_state = POP3_GET_MSG;

    m_pop3ConData->pause_for_read = PR_FALSE;
    
    return(0);
}

Here is the call graph for this function:

Here is the caller graph for this function:

PRInt32 nsPop3Protocol::Error ( PRInt32  err_code) [private]

Definition at line 1061 of file nsPop3Protocol.cpp.

{
    // the error code is just the resource id for the error string...
    // so print out that error message!
    nsresult rv = NS_OK;
    nsCOMPtr<nsIMsgMailNewsUrl> mailnewsUrl = do_QueryInterface(m_url, &rv);
    // we handle POP3_TMP_DOWNLOAD_FAILED earlier...
    if (err_code != POP3_TMP_DOWNLOAD_FAILED && NS_SUCCEEDED(rv))
    {
        nsCOMPtr<nsIMsgWindow> msgWindow;
        nsCOMPtr<nsIPrompt> dialog;
        rv = mailnewsUrl->GetMsgWindow(getter_AddRefs(msgWindow)); //it is ok to have null msgWindow, for example when biffing
        if (NS_SUCCEEDED(rv) && msgWindow)
        {
            rv = msgWindow->GetPromptDialog(getter_AddRefs(dialog));
            if (NS_SUCCEEDED(rv))
            {
              nsXPIDLString alertString;
              mStringService->GetStringByID(err_code, getter_Copies(alertString));
              if (m_pop3ConData->command_succeeded)  //not a server error message
                dialog->Alert(nsnull, alertString.get()); 
              else
              {
                nsXPIDLString serverSaidPrefix;
                nsCOMPtr<nsIMsgIncomingServer> server = do_QueryInterface(m_pop3Server);
                nsXPIDLCString hostName;
                // Fomat string with hostname.
                if (server)
                  rv = server->GetRealHostName(getter_Copies(hostName));
                if (NS_SUCCEEDED(rv))
                {
                  nsAutoString hostStr;
                  hostStr.AssignWithConversion(hostName.get());
                  const PRUnichar *params[] = { hostStr.get() };
                  nsCOMPtr<nsIStringBundle> bundle;
                  rv = mStringService->GetBundle(getter_AddRefs(bundle));
                  if (NS_SUCCEEDED(rv))
                    bundle->FormatStringFromID(POP3_SERVER_SAID, params, 1, getter_Copies(serverSaidPrefix));
                }

                nsAutoString message(alertString + NS_LITERAL_STRING(" ") +
                                     serverSaidPrefix + NS_LITERAL_STRING(" "));
                AppendASCIItoUTF16(m_commandResponse, message);
                dialog->Alert(nsnull,message.get()); 
              }
            }
        }
    }
    m_pop3ConData->next_state = POP3_ERROR_DONE;
    m_pop3ConData->pause_for_read = PR_FALSE;
    return -1;
}

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 922 of file nsPop3Protocol.cpp.

Here is the caller graph for this function:

Definition at line 4082 of file nsPop3Protocol.cpp.

{
  PRInt32 startMark = m_commandResponse.Length(), endMark = -1;

  while (PR_TRUE)
  {
    // search for previous <
    if ((startMark = m_commandResponse.RFindChar('<', startMark - 1)) < 0)
      return NS_ERROR_FAILURE;

    // search for next >
    if ((endMark = m_commandResponse.FindChar('>', startMark)) < 0)
      continue;

    // look for an @ between start and end as a raw test
    PRInt32 at = m_commandResponse.FindChar('@', startMark);
    if (at < 0 || at >= endMark)
      continue;

    // now test if sub only consists of chars in ASCII range
    nsCString sub(Substring(m_commandResponse, startMark, endMark - startMark + 1));
    if (nsCRT::IsAscii(sub.get()))
    {
      // set m_ApopTimestamp to the validated substring
      m_ApopTimestamp.Assign(sub);
      break;
    }
  }

  return NS_OK;
}

Here is the call graph for this function:

Here is the caller graph for this function:

PRInt32 nsPop3Protocol::GetFakeUidlTop ( nsIInputStream inputStream,
PRUint32  length 
) [private]

Definition at line 2214 of file nsPop3Protocol.cpp.

{
  char * line, *newStr;
  PRUint32 ln = 0;
  
  /* check list response 
  * This will get called multiple times
  * but it's alright since command_succeeded
  * will remain constant
  */
  nsresult rv;
  if(!m_pop3ConData->command_succeeded) 
  {
    
    /* UIDL, XTND and TOP are all unsupported for this mail server.
       Tell the user to join the 20th century.
    
       Tell the user this, and refuse to download any messages until they've
       gone into preferences and turned off the `Keep Mail on Server' and
       `Maximum Message Size' prefs.  Some people really get their panties
       in a bunch if we download their mail anyway. (bug 11561)
    */
    
    // set up status first, so if the rest fails, state is ok
    m_pop3ConData->next_state = POP3_ERROR_DONE;
    m_pop3ConData->pause_for_read = PR_FALSE;
    
    // get the hostname first, convert to unicode
    nsCAutoString hostName;
    m_url->GetHost(hostName);
    
    NS_ConvertUTF8toUCS2 hostNameUnicode(hostName);
    
    const PRUnichar *formatStrings[] =
    {
      hostNameUnicode.get(),
    };
    
    // get the strings for the format
    nsCOMPtr<nsIStringBundle> bundle;
    rv = mStringService->GetBundle(getter_AddRefs(bundle));
    NS_ENSURE_SUCCESS(rv, -1);
    
    nsXPIDLString statusString;
    rv = bundle->FormatStringFromID(POP3_SERVER_DOES_NOT_SUPPORT_UIDL_ETC,
      formatStrings, 1,
      getter_Copies(statusString));
    NS_ENSURE_SUCCESS(rv, -1);
    
    
    UpdateStatusWithString(statusString);
    
    return -1;
    
  }
  
  PRBool pauseForMoreData = PR_FALSE;
  line = m_lineStreamBuffer->ReadNextLine(inputStream, ln, pauseForMoreData, &rv);
  if (NS_FAILED(rv))
    return -1;
  
  if(pauseForMoreData || !line)
  {
    m_pop3ConData->pause_for_read = PR_TRUE;
    PR_Free(line);
    return 0;
  }
  
  PR_LOG(POP3LOGMODULE, PR_LOG_ALWAYS,("RECV: %s", line));
  
  if(!PL_strcmp(line, "."))
  {
    m_pop3ConData->current_msg_to_top--;
    if (!m_pop3ConData->current_msg_to_top || 
      (m_pop3ConData->found_new_message_boundary &&
      !m_pop3ConData->delete_server_message_during_top_traversal))
    {
      /* we either ran out of messages or reached the edge of new
      messages and no messages are marked deleted */
      if (m_pop3ConData->only_check_for_new_mail)
      {
        m_pop3ConData->biffstate = nsIMsgFolder::nsMsgBiffState_NewMail;
        m_nsIPop3Sink->SetBiffStateAndUpdateFE(nsIMsgFolder::nsMsgBiffState_NewMail, m_pop3ConData->really_new_messages, PR_TRUE);
        m_pop3ConData->next_state = POP3_SEND_QUIT;
      }
      else
      {
        m_pop3ConData->list_done = PR_TRUE;
        m_pop3ConData->next_state = POP3_GET_MSG;
      }
      m_pop3ConData->pause_for_read = PR_FALSE;
      
      /* if all of the messages are new, toss all hash table entries */
      if (!m_pop3ConData->current_msg_to_top &&
        !m_pop3ConData->found_new_message_boundary)
        PL_HashTableEnumerateEntries(m_pop3ConData->uidlinfo->hash, hash_clear_mapper, nsnull);
    }
    else
    {
      /* this message is done, go to the next */
      m_pop3ConData->next_state = POP3_SEND_FAKE_UIDL_TOP;
      m_pop3ConData->pause_for_read = PR_FALSE;
    }
  }
  else
  {
    if(m_parsingMultiLineMessageId && !(*line == ' ' || *line == '\t'))
    {
      // We already read the Message-Id-line, but didn't get
      // a message id. Treat it as not present and continue.
      m_pop3ConData->number_of_messages_not_seen_before++;
      m_parsingMultiLineMessageId = PR_FALSE;
    }

    int state = 0;

    /* we are looking for a string of the form
    Message-Id: <199602071806.KAA14787@neon.netscape.com> */
    if (!PL_strncasecmp(line, "MESSAGE-ID:", 11) || m_parsingMultiLineMessageId)
    {
      if(m_parsingMultiLineMessageId)
      {
        m_parsingMultiLineMessageId = PR_FALSE;
        // skip leading whitespace of folded header
        newStr = line;
        while(*newStr == ' ' || *newStr == '\t')
          newStr++;
      }
      else
        // skip "MESSAGE-ID:"
        newStr = line + 11;

      char *message_id_token = nsCRT::strtok(newStr, " ", &newStr);
      if (message_id_token)
      {
        Pop3UidlEntry *uidlEntry = (Pop3UidlEntry *) PL_HashTableLookup(m_pop3ConData->uidlinfo->hash, message_id_token);
        if (uidlEntry)
          state = uidlEntry->status;
      }
      else
      {
        m_parsingMultiLineMessageId = PR_TRUE;
        return 0;
      }

      if (!m_pop3ConData->only_uidl && message_id_token && (state == 0))
      { /* we have not seen this message before */
        m_pop3ConData->number_of_messages_not_seen_before++;
        m_pop3ConData->msg_info[m_pop3ConData->current_msg_to_top-1].uidl = 
          PL_strdup(message_id_token);
        if (!m_pop3ConData->msg_info[m_pop3ConData->current_msg_to_top-1].uidl)
        {
          PR_Free(line);
          return MK_OUT_OF_MEMORY;
        }
      }
      else if (m_pop3ConData->only_uidl && message_id_token &&
        !PL_strcmp(m_pop3ConData->only_uidl, message_id_token))
      {
        m_pop3ConData->last_accessed_msg = m_pop3ConData->current_msg_to_top - 1;
        m_pop3ConData->found_new_message_boundary = PR_TRUE;
        m_pop3ConData->msg_info[m_pop3ConData->current_msg_to_top-1].uidl =
          PL_strdup(message_id_token);
        if (!m_pop3ConData->msg_info[m_pop3ConData->current_msg_to_top-1].uidl)
        {
          PR_Free(line);
          return MK_OUT_OF_MEMORY;
        }
      }
      else if (!m_pop3ConData->only_uidl)
      { /* we have seen this message and we care about the edge,
        stop looking for new ones */
        if (m_pop3ConData->number_of_messages_not_seen_before != 0)
        {
          m_pop3ConData->last_accessed_msg =
            m_pop3ConData->current_msg_to_top;
          m_pop3ConData->found_new_message_boundary = PR_TRUE;
          /* we stay in this state so we can process the rest of the
          lines in the top message */
        }
        else
        {
          m_pop3ConData->next_state = POP3_SEND_QUIT;
          m_pop3ConData->pause_for_read = PR_FALSE;
        }
      }
    }
  }
  
  PR_Free(line);
  return 0;
}

Here is the call graph for this function:

Here is the caller graph for this function:

PRInt32 nsPop3Protocol::GetList ( nsIInputStream inputStream,
PRUint32  length 
) [private]

Definition at line 2109 of file nsPop3Protocol.cpp.

{
  char * line;
  PRUint32 ln = 0;
  PRInt32 msg_num;
  
  /* check list response 
  * This will get called multiple times
  * but it's alright since command_succeeded
  * will remain constant
  */
  if(!m_pop3ConData->command_succeeded)
    return(Error(POP3_LIST_FAILURE));
  
  PRBool pauseForMoreData = PR_FALSE;
  nsresult rv;
  line = m_lineStreamBuffer->ReadNextLine(inputStream, ln, pauseForMoreData, &rv);
  if (NS_FAILED(rv))
    return -1;
  
  if(pauseForMoreData || !line)
  {
    m_pop3ConData->pause_for_read = PR_TRUE;
    PR_Free(line);
    return(ln);
  }
  
  PR_LOG(POP3LOGMODULE, PR_LOG_ALWAYS,("RECV: %s", line));
  
  /* parse the line returned from the list command 
  * it looks like
  * #msg_number #bytes
  *
  * list data is terminated by a ".CRLF" line
  */
  if(!PL_strcmp(line, "."))
  {
    // limit the list if fewer entries than given in STAT response
    if(m_listpos < m_pop3ConData->number_of_messages)
      m_pop3ConData->number_of_messages = m_listpos;
    m_pop3ConData->next_state = POP3_SEND_UIDL_LIST;
    m_pop3ConData->pause_for_read = PR_FALSE;
    PR_Free(line);
    return(0);
  }
  
  char *token, *newStr;
  token = nsCRT::strtok(line, " ", &newStr);
  if (token)
  {
    msg_num = atol(token);
    m_listpos++;
    
    if(m_listpos <= m_pop3ConData->number_of_messages && m_listpos > 0)
    {
      token = nsCRT::strtok(newStr, " ", &newStr);
      if (token)
      {
        m_pop3ConData->msg_info[m_listpos-1].size = atol(token);
        m_pop3ConData->msg_info[m_listpos-1].msgnum = msg_num;
      }
    }
  }

  PR_Free(line);
  return(0);
}

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 2680 of file nsPop3Protocol.cpp.

{
  char c = 0;
  int i;
  PRBool prefBool = PR_FALSE;
  PRInt32 popstateTimestamp = TimeInSecondsFromPRTime(PR_Now());
  
  if(m_pop3ConData->last_accessed_msg >= m_pop3ConData->number_of_messages) 
  {
    /* Oh, gee, we're all done. */
    if(m_pop3ConData->msg_del_started)
    {
      if (!m_pop3ConData->only_uidl) 
      {
        if (m_pop3ConData->only_check_for_new_mail)
          m_nsIPop3Sink->SetBiffStateAndUpdateFE(m_pop3ConData->biffstate, m_pop3ConData->really_new_messages, PR_TRUE);      
        /* update old style biff */
        else 
            m_nsIPop3Sink->SetBiffStateAndUpdateFE(nsIMsgFolder::nsMsgBiffState_NewMail, m_pop3ConData->really_new_messages, PR_FALSE);
      }
      m_nsIPop3Sink->EndMailDelivery(this);
    }
    
    m_pop3ConData->next_state = POP3_SEND_QUIT;
    return 0;
  }
  
  if (m_totalDownloadSize < 0) {
  /* First time.  Figure out how many bytes we're about to get.
  If we didn't get any message info, then we are going to get
  everything, and it's easy.  Otherwise, if we only want one
  uidl, than that's the only one we'll get.  Otherwise, go
  through each message info, decide if we're going to get that
  message, and add the number of bytes for it. When a message is too
  large (per user's preferences) only add the size we are supposed
    to get. */
    m_pop3ConData->really_new_messages = 0;
    m_pop3ConData->real_new_counter = 1;
    if (m_pop3ConData->msg_info) {
      m_totalDownloadSize = 0;
      // init i with last_accessed_msg to prevend inspecting unpopulated
      // msg_info[i].uidl when coming from GetFakeUidlTop() -
      // because that would result in incorrect really_new_messages
      for (i = m_pop3ConData->last_accessed_msg;
           i < m_pop3ConData->number_of_messages; i++) 
      {
        c = 0;
        popstateTimestamp = TimeInSecondsFromPRTime(PR_Now());
        if (m_pop3ConData->only_uidl) {
          if (m_pop3ConData->msg_info[i].uidl &&
            PL_strcmp(m_pop3ConData->msg_info[i].uidl, 
            m_pop3ConData->only_uidl) == 0) 
          {
            /*if (m_pop3ConData->msg_info[i].size > m_pop3ConData->size_limit)
            m_totalDownloadSize = m_pop3ConData->size_limit;   */     /* if more than max, only count max */
            /*else*/
              m_totalDownloadSize = m_pop3ConData->msg_info[i].size;
              m_pop3ConData->really_new_messages = 1;
              /* we are only getting one message */ 
              m_pop3ConData->real_new_counter = 1;
              break;
          }
          continue;
        }
        if (m_pop3ConData->msg_info[i].uidl)
        {
          Pop3UidlEntry *uidlEntry = (Pop3UidlEntry *) PL_HashTableLookup(m_pop3ConData->uidlinfo->hash, m_pop3ConData->msg_info[i].uidl);
          if (uidlEntry)
          {
            c = uidlEntry->status;
            popstateTimestamp = uidlEntry->dateReceived;
          }
        }
        if ((c == KEEP) && !m_pop3ConData->leave_on_server)
        {   /* This message has been downloaded but kept on server, we
          * no longer want to keep it there */ 
          if (m_pop3ConData->newuidl == NULL)
          {
            m_pop3ConData->newuidl = PL_NewHashTable(20,
              PL_HashString, 
              PL_CompareStrings,
              PL_CompareValues,
              &gHashAllocOps,
              nsnull);
            if (!m_pop3ConData->newuidl)
              return MK_OUT_OF_MEMORY;
          }
          c = DELETE_CHAR;
          put_hash(m_pop3ConData->newuidl,
            m_pop3ConData->msg_info[i].uidl, DELETE_CHAR, popstateTimestamp);
          /*Mark message to be deleted in new table */ 
          put_hash(m_pop3ConData->uidlinfo->hash,
            m_pop3ConData->msg_info[i].uidl, DELETE_CHAR, popstateTimestamp);
          /*and old one too */ 
        }
        if ((c != KEEP) && (c != DELETE_CHAR) && (c != TOO_BIG)) 
        { /* message left on server */
          /*if (m_pop3ConData->msg_info[i].size > m_pop3ConData->size_limit)
                m_totalDownloadSize +=
          m_pop3ConData->size_limit;      */     
          /* if more than max, only count max */
          /*else*/
          m_totalDownloadSize += m_pop3ConData->msg_info[i].size; 
          m_pop3ConData->really_new_messages++;
          /* a message we will really download */
        }
      }
    }
    else 
    {
      m_totalDownloadSize = m_totalFolderSize;
    }
    if (m_pop3ConData->only_check_for_new_mail) 
    {
      if (m_totalDownloadSize > 0)
      {
        m_pop3ConData->biffstate = nsIMsgFolder::nsMsgBiffState_NewMail; 
        m_nsIPop3Sink->SetBiffStateAndUpdateFE(nsIMsgFolder::nsMsgBiffState_NewMail, m_pop3ConData->really_new_messages, PR_TRUE);
      }
      m_pop3ConData->next_state = POP3_SEND_QUIT;
      return(0);
    }
    /* get the amount of available space on the drive
    * and make sure there is enough
    */ 
    if(m_totalDownloadSize > 0) // skip all this if there aren't any messages
    {
      nsresult rv;
      PRInt64 mailboxSpaceLeft = LL_Zero();
      nsCOMPtr <nsIMsgFolder> folder;
      nsCOMPtr <nsIFileSpec> path;
      
      // Get the path to the current mailbox
      //      
      NS_ENSURE_TRUE(m_nsIPop3Sink, NS_ERROR_UNEXPECTED); 
      rv = m_nsIPop3Sink->GetFolder(getter_AddRefs(folder));
      if (NS_FAILED(rv)) return rv;
      rv = folder->GetPath(getter_AddRefs(path));
      if (NS_FAILED(rv)) return rv;
      
      // call GetDiskSpaceAvailable
      rv = path->GetDiskSpaceAvailable(&mailboxSpaceLeft);
      if (NS_FAILED(rv))
      {
        // The call to GetDiskSpaceAvailable FAILED!
        // This will happen on certain platforms where GetDiskSpaceAvailable
        // is not implemented. Since people on those platforms still need
        // to check mail, we will simply bypass the disk-space check.
        // 
        // We'll leave a debug message to warn people.
        
#ifdef DEBUG
        printf("Call to GetDiskSpaceAvailable FAILED! \n");
#endif
      }
      else
      {
#ifdef DEBUG
        printf("GetDiskSpaceAvailable returned: %d bytes\n", mailboxSpaceLeft);
#endif
        
        // Original comment from old implementation follows...
        /* When checking for disk space available, take into consideration
        * possible database 
        * changes, therefore ask for a little more than what the message
        * size is. Also, due to disk sector sizes, allocation blocks,
        * etc. The space "available" may be greater than the actual space
        * usable. */
        
        // The big if statement                  
        PRInt64 llResult;
        PRInt64 llExtraSafetySpace;
        PRInt64 llTotalDownloadSize;
        LL_I2L(llExtraSafetySpace, EXTRA_SAFETY_SPACE);
        LL_I2L(llTotalDownloadSize, m_totalDownloadSize);
        
        LL_ADD(llResult, llTotalDownloadSize, llExtraSafetySpace);
        if (LL_CMP(llResult, >, mailboxSpaceLeft))             
        {
          // Not enough disk space!
#ifdef DEBUG
          printf("Not enough disk space! Raising error! \n");
#endif
          // Should raise an error at this point.
          // First, we need to delete our references to the two interfaces..
          
          return (Error(MK_POP3_OUT_OF_DISK_SPACE));
        }
      }
      // Delete our references to the two interfaces..
    }
    }
    
    
    /* Look at this message, and decide whether to ignore it, get it, just get
    the TOP of it, or delete it. */
    
    m_pop3Server->GetAuthLogin(&prefBool);
    
    if (prefBool && (TestCapFlag(POP3_HAS_XSENDER)))
      m_pop3ConData->next_state = POP3_SEND_XSENDER;
    else
      m_pop3ConData->next_state = POP3_SEND_RETR;
    m_pop3ConData->truncating_cur_msg = PR_FALSE;
    m_pop3ConData->pause_for_read = PR_FALSE;
    if (m_pop3ConData->msg_info) 
    {
      Pop3MsgInfo* info = m_pop3ConData->msg_info + m_pop3ConData->last_accessed_msg;
      if (m_pop3ConData->only_uidl) 
      {
        if (info->uidl == NULL || PL_strcmp(info->uidl, m_pop3ConData->only_uidl))
          m_pop3ConData->next_state = POP3_GET_MSG;
        else
          m_pop3ConData->next_state = POP3_SEND_RETR;
      }
      else 
      {
        c = 0;
        if (m_pop3ConData->newuidl == NULL) 
        {
          m_pop3ConData->newuidl = PL_NewHashTable(20, PL_HashString, PL_CompareStrings, PL_CompareValues, &gHashAllocOps, nsnull);
          if (!m_pop3ConData->newuidl)
            return MK_OUT_OF_MEMORY;
        }
        if (info->uidl) 
        {
          Pop3UidlEntry *uidlEntry = (Pop3UidlEntry *) PL_HashTableLookup(m_pop3ConData->uidlinfo->hash, info->uidl);
          if (uidlEntry)
          {
            c = uidlEntry->status;
            popstateTimestamp = uidlEntry->dateReceived;
          }
        }
        m_pop3ConData->truncating_cur_msg = PR_FALSE;
        if (c == DELETE_CHAR) 
        {
          m_pop3ConData->next_state = POP3_SEND_DELE;
        }
        else if (c == KEEP) 
        {
          m_pop3ConData->next_state = POP3_GET_MSG;
        }
        else if (c == FETCH_BODY) 
        {
          m_pop3ConData->next_state = POP3_SEND_RETR;
         PL_HashTableRemove (m_pop3ConData->uidlinfo->hash, (void*)
              info->uidl);
        }
        else if ((c != TOO_BIG) &&
          (TestCapFlag(POP3_TOP_UNDEFINED | POP3_HAS_TOP)) &&
         (m_pop3ConData->headers_only ||
         ((m_pop3ConData->size_limit > 0) &&
          (info->size > m_pop3ConData->size_limit) && 
          !m_pop3ConData->only_uidl))) 
        { 
          /* message is too big */
          m_pop3ConData->truncating_cur_msg = PR_TRUE;
          m_pop3ConData->next_state = POP3_SEND_TOP;
          put_hash(m_pop3ConData->newuidl, info->uidl, TOO_BIG, popstateTimestamp); 
         } 
         else if (c == TOO_BIG) 
         {
         /* message previously left on server, see if the max download size 
            has changed, because we may want to download the message this time 
            around. Otherwise ignore the message, we have the header. */
            if ((m_pop3ConData->size_limit > 0) && (info->size <=
              m_pop3ConData->size_limit)) 
              PL_HashTableRemove (m_pop3ConData->uidlinfo->hash, (void*)
              info->uidl);
            /* remove from our table, and download */
            else
            {
              m_pop3ConData->truncating_cur_msg = PR_TRUE;
              m_pop3ConData->next_state = POP3_GET_MSG;
              /* ignore this message and get next one */
              put_hash(m_pop3ConData->newuidl, info->uidl, TOO_BIG, popstateTimestamp);
            }
          }
      }
      if (m_pop3ConData->next_state != POP3_SEND_DELE) 
      { 
        
        /* This is a message we have decided to keep on the server.  Notate
        that now for the future.  (Don't change the popstate file at all
        if only_uidl is set; in that case, there might be brand new messages
        on the server that we *don't* want to mark KEEP; we just want to
        leave them around until the user next does a GetNewMail.) */
        
        // if this is a message we already know about (i.e., it was in popstate.dat already),
        // we need to maintain the original date the message was downloaded.
        if (info->uidl && !m_pop3ConData->only_uidl && !m_pop3ConData->truncating_cur_msg)
            /* message already marked as too_big */
            put_hash(m_pop3ConData->newuidl, info->uidl, KEEP, popstateTimestamp); 
      }
      if (m_pop3ConData->next_state == POP3_GET_MSG) 
        m_pop3ConData->last_accessed_msg++; 
        /* Make sure we check the next message next time! */
    }
    return 0;
}

Here is the call graph for this function:

Here is the caller graph for this function:

nsresult nsPop3Protocol::GetPassword ( char **  aPassword,
PRBool okayValue 
)

Definition at line 693 of file nsPop3Protocol.cpp.

{
  nsresult rv = NS_OK;
  nsCOMPtr<nsIMsgIncomingServer> server = do_QueryInterface(m_pop3Server);
  
  if (server)
  {
    PRBool isAuthenticated;
    m_nsIPop3Sink->GetUserAuthenticated(&isAuthenticated);

    // pass the failed password into the password prompt so that
    // it will be pre-filled, in case it failed because of a
    // server problem and not because it was wrong.
    if (!m_lastPasswordSent.IsEmpty())
      *aPassword = ToNewCString(m_lastPasswordSent);

    // clear the password if the last one failed
    if (TestFlag(POP3_PASSWORD_FAILED))
    {
      // if we've already gotten a password and it wasn't correct..clear
      // out the password and try again.
      rv = server->SetPassword("");
    }
    
    // first, figure out the correct prompt text to use...
    nsXPIDLCString hostName;
    nsXPIDLCString userName;
    PRUnichar *passwordPromptString =nsnull;
    
    server->GetRealHostName(getter_Copies(hostName));
    server->GetRealUsername(getter_Copies(userName));
    nsXPIDLString passwordTemplate;
    nsCOMPtr<nsIMsgMailNewsUrl> mailnewsUrl = do_QueryInterface(m_url, &rv);
    nsCOMPtr<nsIMsgWindow> msgWindow;
    if (mailnewsUrl)
      mailnewsUrl->GetMsgWindow(getter_AddRefs(msgWindow));
    // if the last prompt got us a bad password then show a special dialog
    if (TestFlag(POP3_PASSWORD_FAILED))
    {
      // if we haven't successfully logged onto the server in this session
      // and tried at least twice or if the server threw the specific error,
      // forget the password. 
      // Only do this if it's not check for new mail, since biff shouldn't
      // cause passwords to get forgotten at all. 
      if ((!isAuthenticated || m_pop3ConData->logonFailureCount > 2) && msgWindow)
        rv = server->ForgetPassword();
      if (NS_FAILED(rv)) return rv;
      mStringService->GetStringByID(POP3_PREVIOUSLY_ENTERED_PASSWORD_IS_INVALID_ETC, getter_Copies(passwordTemplate));
    } // otherwise this is the first time we've asked about the server's password so show a first time prompt
    else
      mStringService->GetStringByID(POP3_ENTER_PASSWORD_PROMPT, getter_Copies(passwordTemplate));
    if (passwordTemplate)
      passwordPromptString = nsTextFormatter::smprintf(passwordTemplate, (const char *) userName, (const char *) hostName);
    // now go get the password!!!!
    nsXPIDLString passwordTitle;
    mStringService->GetStringByID(POP3_ENTER_PASSWORD_PROMPT_TITLE, getter_Copies(passwordTitle));
    if (passwordPromptString)
    {
      if (passwordTitle)
        rv =  server->GetPasswordWithUI(passwordPromptString, passwordTitle.get(),
                                        msgWindow, okayValue, aPassword);
      nsTextFormatter::smprintf_free(passwordPromptString);
      ClearFlag(POP3_PASSWORD_FAILED|POP3_AUTH_FAILURE);
    }
    
    if (NS_FAILED(rv))
      m_pop3ConData->next_state = POP3_ERROR_DONE;
  } // if we have a server
  else
    rv = NS_MSG_INVALID_OR_MISSING_SERVER;
  
  return rv;
}

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 1960 of file nsPop3Protocol.cpp.

{
  char *num;
  char* newStr;
  char* oldStr;

    /* check stat response */
  if(!m_pop3ConData->command_succeeded)
    return(Error(POP3_STAT_FAILURE));

    /* stat response looks like:  %d %d
     * The first number is the number of articles
     * The second number is the number of bytes
     *
     *  grab the first and second arg of stat response
     */
  oldStr = ToNewCString(m_commandResponse);
  num = nsCRT::strtok(oldStr, " ", &newStr);
  if (num)
  {
    m_pop3ConData->number_of_messages = atol(num);
    num = nsCRT::strtok(newStr, " ", &newStr);
    m_commandResponse = newStr;
    if (num)
      m_totalFolderSize = (PRInt32) atol(num);  //we always initialize m_totalFolderSize to 0
  }
  else
    m_pop3ConData->number_of_messages = 0;

  PR_Free(oldStr);
  m_pop3ConData->really_new_messages = 0;
  m_pop3ConData->real_new_counter = 1;

  m_totalDownloadSize = -1; /* Means we need to calculate it, later. */

  if(m_pop3ConData->number_of_messages <= 0) 
  {
      /* We're all done.  We know we have no mail. */
     m_pop3ConData->next_state = POP3_SEND_QUIT;
     PL_HashTableEnumerateEntries(m_pop3ConData->uidlinfo->hash, hash_clear_mapper, nsnull);
     /* Hack - use nsPop3Sink to wipe out any stale Partial messages */
      m_nsIPop3Sink->BeginMailDelivery(PR_FALSE, nsnull, nsnull);
      m_nsIPop3Sink->AbortMailDelivery(this);
     return(0);
  }

  if (m_pop3ConData->only_check_for_new_mail && !m_pop3ConData->leave_on_server &&
      m_pop3ConData->size_limit < 0) 
  {
      /* We're just checking for new mail, and we're not playing any games that
         involve keeping messages on the server.  Therefore, we now know enough
         to finish up.  If we had no messages, that would have been handled
         above; therefore, we know we have some new messages. */
      m_pop3ConData->biffstate = nsIMsgFolder::nsMsgBiffState_NewMail;
      m_pop3ConData->next_state = POP3_SEND_QUIT;
      return(0);
  }


  if (!m_pop3ConData->only_check_for_new_mail) 
  {
      // The following was added to prevent the loss of Data when we try and
      // write to somewhere we dont have write access error to (See bug 62480)
      // (Note: This is only a temp hack until the underlying XPCOM is fixed
      // to return errors)

      nsresult rv;
      nsCOMPtr <nsIMsgWindow> msgWindow;
      nsCOMPtr<nsIMsgMailNewsUrl> mailnewsUrl = do_QueryInterface(m_url);
      if (mailnewsUrl)
        rv = mailnewsUrl->GetMsgWindow(getter_AddRefs(msgWindow));
//         NS_ASSERTION(NS_SUCCEEDED(rv) && msgWindow, "no msg window");

      rv = m_nsIPop3Sink->BeginMailDelivery(m_pop3ConData->only_uidl != nsnull, msgWindow,
                                                    &m_pop3ConData->msg_del_started);
      if (NS_FAILED(rv))
        if (rv == NS_MSG_FOLDER_BUSY)
          return(Error(POP3_MESSAGE_FOLDER_BUSY));
        else
          return(Error(POP3_MESSAGE_WRITE_ERROR));
      if(!m_pop3ConData->msg_del_started)
      {
        return(Error(POP3_MESSAGE_WRITE_ERROR));
      }
  }

  m_pop3ConData->next_state = POP3_SEND_LIST;
  return 0;
}

Here is the call graph for this function:

Here is the caller graph for this function:

PRInt32 nsPop3Protocol::GetUidlList ( nsIInputStream inputStream,
PRUint32  length 
) [private]

Definition at line 2572 of file nsPop3Protocol.cpp.

{
    char * line;
    PRUint32 ln;
    PRInt32 msg_num;

    /* check list response 
     * This will get called multiple times
     * but it's alright since command_succeeded
     * will remain constant
     */
    ClearCapFlag(POP3_UIDL_UNDEFINED);

    if(!m_pop3ConData->command_succeeded) 
    {
        m_pop3ConData->next_state = POP3_SEND_XTND_XLST_MSGID;
        m_pop3ConData->pause_for_read = PR_FALSE;
        ClearCapFlag(POP3_HAS_UIDL);
        m_pop3Server->SetPop3CapabilityFlags(m_pop3ConData->capability_flags);
        return(0);
    }
    else
    {
        SetCapFlag(POP3_HAS_UIDL);
        m_pop3Server->SetPop3CapabilityFlags(m_pop3ConData->capability_flags);
    }
    
    PRBool pauseForMoreData = PR_FALSE;
    nsresult rv;
    line = m_lineStreamBuffer->ReadNextLine(inputStream, ln, pauseForMoreData, &rv);
   if (NS_FAILED(rv))
     return -1;

    if(pauseForMoreData || !line)
    {
        PR_Free(line);
        m_pop3ConData->pause_for_read = PR_TRUE;
        return ln;
    }

    PR_LOG(POP3LOGMODULE, PR_LOG_ALWAYS,("RECV: %s", line));

    /* parse the line returned from the list command 
     * it looks like
     * #msg_number uidl
     *
     * list data is terminated by a ".CRLF" line
     */
    if(!PL_strcmp(line, "."))
    {
        // limit the list if fewer entries than given in STAT response
        if(m_listpos < m_pop3ConData->number_of_messages)
          m_pop3ConData->number_of_messages = m_listpos;
        m_pop3ConData->list_done = PR_TRUE;
        m_pop3ConData->next_state = POP3_GET_MSG;
        m_pop3ConData->pause_for_read = PR_FALSE;
        PR_Free(line);
        return(0);
    }
    
    char *newStr;
    char *token = nsCRT::strtok(line, " ", &newStr);
    if (token)
    {
      msg_num = atol(token);
      m_listpos++;

      if(m_listpos <= m_pop3ConData->number_of_messages && m_listpos > 0) 
      {
        char *uidl = nsCRT::strtok(newStr, " ", &newStr);

        if (!uidl)
            /* This is bad.  The server didn't give us a UIDL for this message.
               I've seen this happen when somehow the mail spool has a message
               that contains a header that reads "X-UIDL: \n".  But how that got
               there, I have no idea; must be a server bug.  Or something. */
            uidl = "";

        // seeking right entry, but try the one that should it be first
        PRInt32 i;
        if(m_pop3ConData->msg_info[m_listpos - 1].msgnum == msg_num)
          i = m_listpos - 1;
        else
          for(i = 0; i < m_pop3ConData->number_of_messages &&
                     m_pop3ConData->msg_info[i].msgnum != msg_num; i++)
            ;

        m_pop3ConData->msg_info[i].uidl = PL_strdup(uidl);
        if (!m_pop3ConData->msg_info[i].uidl)
        {
          PR_Free(line);
          return MK_OUT_OF_MEMORY;
        }
      }
    }
    PR_Free(line);
    return(0);
}

Here is the call graph for this function:

Here is the caller graph for this function:

const char* nsPop3Protocol::GetUsername ( ) [inline]

Definition at line 304 of file nsPop3Protocol.h.

{ return m_username.get(); };

Here is the call graph for this function:

PRInt32 nsPop3Protocol::GetXtndXlstMsgid ( nsIInputStream inputStream,
PRUint32  length 
) [private]

Definition at line 2456 of file nsPop3Protocol.cpp.

{
  char * line;
  PRUint32 ln = 0;
  PRInt32 msg_num;
  
  /* check list response 
  * This will get called multiple times
  * but it's alright since command_succeeded
  * will remain constant
  */
  ClearCapFlag(POP3_XTND_XLST_UNDEFINED);
  
  if(!m_pop3ConData->command_succeeded) {
    ClearCapFlag(POP3_HAS_XTND_XLST);
    m_pop3Server->SetPop3CapabilityFlags(m_pop3ConData->capability_flags);
    m_pop3ConData->next_state = POP3_START_USE_TOP_FOR_FAKE_UIDL;
    m_pop3ConData->pause_for_read = PR_FALSE;
    return(0);
  }
  else
  {
    SetCapFlag(POP3_HAS_XTND_XLST);
    m_pop3Server->SetPop3CapabilityFlags(m_pop3ConData->capability_flags);
  }        
  
  PRBool pauseForMoreData = PR_FALSE;
  nsresult rv;
  line = m_lineStreamBuffer->ReadNextLine(inputStream, ln, pauseForMoreData, &rv);
  if (NS_FAILED(rv))
    return -1;
  
  if(pauseForMoreData || !line)
  {
    m_pop3ConData->pause_for_read = PR_TRUE;
    PR_Free(line);
    return ln;
  }
  
  PR_LOG(POP3LOGMODULE, PR_LOG_ALWAYS,("RECV: %s", line));
  
  /* parse the line returned from the list command 
  * it looks like
  * 1 Message-ID: <3117E4DC.2699@netscape.com>
  *
  * list data is terminated by a ".CRLF" line
  */
  if(!PL_strcmp(line, "."))
  {
    // limit the list if fewer entries than given in STAT response
    if(m_listpos < m_pop3ConData->number_of_messages)
      m_pop3ConData->number_of_messages = m_listpos;
    m_pop3ConData->list_done = PR_TRUE;
    m_pop3ConData->next_state = POP3_GET_MSG;
    m_pop3ConData->pause_for_read = PR_FALSE;
    PR_Free(line);
    return(0);
  }
  
  char *newStr;
  char *token = nsCRT::strtok(line, " ", &newStr);
  if (token)
  {
    msg_num = atol(token);
    m_listpos++;

    if(m_listpos <= m_pop3ConData->number_of_messages && m_listpos > 0) 
    {
      char *eatMessageIdToken = nsCRT::strtok(newStr, " ", &newStr);
      char *uidl = nsCRT::strtok(newStr, " ", &newStr); /* not really a uidl but a unique token -km */
      
      if (!uidl)
        /* This is bad.  The server didn't give us a UIDL for this message.
        I've seen this happen when somehow the mail spool has a message
        that contains a header that reads "X-UIDL: \n".  But how that got
        there, I have no idea; must be a server bug.  Or something. */
        uidl = "";

      // seeking right entry, but try the one that should it be first
      PRInt32 i;
      if(m_pop3ConData->msg_info[m_listpos - 1].msgnum == msg_num)
        i = m_listpos - 1;
      else
        for(i = 0; i < m_pop3ConData->number_of_messages &&
                   m_pop3ConData->msg_info[i].msgnum != msg_num; i++)
          ;
      
      m_pop3ConData->msg_info[i].uidl = PL_strdup(uidl);
      if (!m_pop3ConData->msg_info[i].uidl)
      {
        PR_Free(line);
        return MK_OUT_OF_MEMORY;
      }
    }
  }
  
  PR_Free(line);
  return(0);
}

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 2064 of file nsPop3Protocol.cpp.

Here is the call graph for this function:

Here is the caller graph for this function:

nsresult nsPop3Protocol::HandleLine ( char *  line,
PRUint32  line_length 
) [private]

Definition at line 3390 of file nsPop3Protocol.cpp.

{
    nsresult rv = NS_OK;
    
    NS_ASSERTION(m_pop3ConData->msg_closure, "m_pop3ConData->msg_closure is null in nsPop3Protocol::HandleLine()");
    if (!m_pop3ConData->msg_closure)
        return NS_ERROR_NULL_POINTER;
    
    if (!m_senderInfo.IsEmpty() && !m_pop3ConData->seenFromHeader)
    {
        if (line_length > 6 && !PL_strncasecmp("From: ", line, 6))
        {
            m_pop3ConData->seenFromHeader = PR_TRUE;
            if (PL_strstr(line, m_senderInfo.get()) == NULL)
                m_nsIPop3Sink->SetSenderAuthedFlag(m_pop3ConData->msg_closure,
                                                     PR_FALSE);
        }
    }

    // line contains only a single dot and linebreak -> message end
    if (line_length == 1 + MSG_LINEBREAK_LEN && line[0] == '.')
    {
        m_pop3ConData->assumed_end = PR_TRUE;    /* in case byte count from server is */
                                    /* wrong, mark we may have had the end */ 
        if (!m_pop3ConData->dot_fix || m_pop3ConData->truncating_cur_msg ||
            (m_pop3ConData->parsed_bytes >= (m_pop3ConData->pop3_size -3))) 
        {
            nsCOMPtr<nsIMsgMailNewsUrl> mailnewsUrl = do_QueryInterface(m_url, &rv);
            nsCOMPtr<nsIMsgWindow> msgWindow;
            if (NS_SUCCEEDED(rv))
              rv = mailnewsUrl->GetMsgWindow(getter_AddRefs(msgWindow));
            rv = m_nsIPop3Sink->IncorporateComplete(msgWindow,
              m_pop3ConData->truncating_cur_msg ? m_pop3ConData->cur_msg_size : 0);

            // The following was added to prevent the loss of Data when we try
            // and write to somewhere we dont have write access error to (See
            // bug 62480)
            // (Note: This is only a temp hack until the underlying XPCOM is
            // fixed to return errors)

            if (NS_FAILED(rv))
              return (Error((rv == NS_MSG_ERROR_COPYING_FROM_TMP_DOWNLOAD)
                             ? POP3_TMP_DOWNLOAD_FAILED 
                             : POP3_MESSAGE_WRITE_ERROR));

            m_pop3ConData->msg_closure = nsnull;
            return rv;
        }
    }
    /* Check if the line begins with the termination octet. If so
       and if another termination octet follows, we step over the
       first occurence of it. */
    else if (line_length > 1 && line[0] == '.' && line[1] == '.') {
        line++;
        line_length--;
    
    }

    return m_nsIPop3Sink->IncorporateWrite(line, line_length);
}

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 531 of file nsPop3Protocol.cpp.

{
  nsresult rv = NS_OK;

  m_pop3ConData = (Pop3ConData *)PR_NEWZAP(Pop3ConData);
  if(!m_pop3ConData)
    return NS_ERROR_OUT_OF_MEMORY;

  m_totalBytesReceived = 0;
  m_bytesInMsgReceived = 0; 
  m_totalFolderSize = 0;    
  m_totalDownloadSize = 0;
  m_totalBytesReceived = 0;
  m_tlsEnabled = PR_FALSE;
  m_socketType = nsIMsgIncomingServer::tryTLS;

  if (aURL)
  {
    // extract out message feedback if there is any.
    nsCOMPtr<nsIMsgMailNewsUrl> mailnewsUrl = do_QueryInterface(aURL);
    if (mailnewsUrl)
    {
      nsCOMPtr<nsIMsgIncomingServer> server;
      mailnewsUrl->GetStatusFeedback(getter_AddRefs(m_statusFeedback));
      mailnewsUrl->GetServer(getter_AddRefs(server));
      NS_ENSURE_TRUE(server, NS_MSG_INVALID_OR_MISSING_SERVER);

      rv = server->GetSocketType(&m_socketType);
      NS_ENSURE_SUCCESS(rv,rv);

      rv = server->GetUseSecAuth(&m_useSecAuth);
      NS_ENSURE_SUCCESS(rv,rv);

      m_pop3Server = do_QueryInterface(server);
      if (m_pop3Server)
        m_pop3Server->GetPop3CapabilityFlags(&m_pop3ConData->capability_flags);
    }

    m_url = do_QueryInterface(aURL);

    // When we are making a secure connection, we need to make sure that we
    // pass an interface requestor down to the socket transport so that PSM can
    // retrieve a nsIPrompt instance if needed.
    nsCOMPtr<nsIInterfaceRequestor> ir;
    if (m_socketType != nsIMsgIncomingServer::defaultSocket)
    {
      nsCOMPtr<nsIMsgWindow> msgwin;
      mailnewsUrl->GetMsgWindow(getter_AddRefs(msgwin));
      if (msgwin) 
      {
        nsCOMPtr<nsIDocShell> docshell;
        msgwin->GetRootDocShell(getter_AddRefs(docshell));
        ir = do_QueryInterface(docshell);
      }
    }

    PRInt32 port = 0;
    nsXPIDLCString hostName;
    aURL->GetPort(&port);
    nsCOMPtr<nsIMsgIncomingServer> server = do_QueryInterface(m_pop3Server);
    if (server)
      server->GetRealHostName(getter_Copies(hostName));

    nsCOMPtr<nsIProxyInfo> proxyInfo;
    rv = NS_ExamineForProxy("pop", hostName.get(), port, getter_AddRefs(proxyInfo));
    if (NS_FAILED(rv)) proxyInfo = nsnull;

    const char *connectionType = nsnull;
    if (m_socketType == nsIMsgIncomingServer::useSSL)
      connectionType = "ssl";
    else if (m_socketType == nsIMsgIncomingServer::tryTLS ||
          m_socketType == nsIMsgIncomingServer::alwaysUseTLS)
        connectionType = "starttls";

    rv = OpenNetworkSocketWithInfo(hostName.get(), port, connectionType, proxyInfo, ir);
    if (NS_FAILED(rv) && m_socketType == nsIMsgIncomingServer::tryTLS)
    {
      m_socketType = nsIMsgIncomingServer::defaultSocket;
      rv = OpenNetworkSocketWithInfo(hostName.get(), port, nsnull, proxyInfo, ir);
    }

    if(NS_FAILED(rv))
      return rv;
  } // if we got a url...
  
  if (!POP3LOGMODULE)
      POP3LOGMODULE = PR_NewLogModule("POP3");

  m_lineStreamBuffer = new nsMsgLineStreamBuffer(OUTPUT_BUFFER_SIZE, PR_TRUE);
  if(!m_lineStreamBuffer)
    return NS_ERROR_OUT_OF_MEMORY;

  mStringService = do_GetService(NS_MSG_POPSTRINGSERVICE_CONTRACTID);
  return rv;
}

Here is the call graph for this function:

Here is the caller graph for this function:

nsresult nsPop3Protocol::LoadUrl ( nsIURI aURL,
nsISupports *  aConsumer = nsnull 
) [virtual]

Definition at line 810 of file nsPop3Protocol.cpp.

{
  nsresult rv = 0;
  
  if (aURL)
    m_url = do_QueryInterface(aURL);
  else
    return NS_ERROR_FAILURE;
  
  nsCOMPtr<nsIURL> url = do_QueryInterface(aURL, &rv);
  if (NS_FAILED(rv)) return rv;
  
  PRInt32 port;
  rv = url->GetPort(&port);
  if (NS_FAILED(rv))
    return rv;
  
  rv = NS_CheckPortSafety(port, "pop");
  if (NS_FAILED(rv))
    return rv;
  
  nsCAutoString queryPart;
  rv = url->GetQuery(queryPart);
  NS_ASSERTION(NS_SUCCEEDED(rv), "unable to get the url spect");
  
  m_pop3ConData->only_check_for_new_mail = (PL_strcasestr(queryPart.get(), "check") != nsnull);
  
  m_pop3ConData->get_url = (PL_strcasestr(queryPart.get(), "gurl") != nsnull);
  
  PRBool deleteByAgeFromServer = PR_FALSE;
  PRInt32 numDaysToLeaveOnServer = -1;
  if (!m_pop3ConData->only_check_for_new_mail)
  {
    // Pick up pref setting regarding leave messages on server, message
    // size limit
    
    m_pop3Server->GetLeaveMessagesOnServer(&m_pop3ConData->leave_on_server);
    m_pop3Server->GetHeadersOnly(&m_pop3ConData->headers_only);
    PRBool limitMessageSize = PR_FALSE;

    nsCOMPtr<nsIMsgIncomingServer> server = do_QueryInterface(m_pop3Server);
    if (server)
    {
      // size limits are superseded by headers_only mode
      if (!m_pop3ConData->headers_only)
      {
        server->GetLimitOfflineMessageSize(&limitMessageSize);
        if (limitMessageSize)
        {
          PRInt32 max_size = 0; // default size
          server->GetMaxMessageSize(&max_size);
          m_pop3ConData->size_limit = (max_size) ? max_size * 1024 : 50 * 1024;
       }
      }
      m_pop3Server->GetDeleteByAgeFromServer(&deleteByAgeFromServer);
      if (deleteByAgeFromServer)
        m_pop3Server->GetNumDaysToLeaveOnServer(&numDaysToLeaveOnServer);
    }
  }
  
  // UIDL stuff
  nsCOMPtr<nsIPop3URL> pop3Url = do_QueryInterface(m_url);
  if (pop3Url)
    pop3Url->GetPop3Sink(getter_AddRefs(m_nsIPop3Sink));
  
  nsCOMPtr<nsIFileSpec> mailDirectory;
  
  nsXPIDLCString hostName;
  nsXPIDLCString userName;
  
  nsCOMPtr<nsIMsgIncomingServer> server = do_QueryInterface(m_pop3Server);
  if (server)
  {
    rv = server->GetLocalPath(getter_AddRefs(mailDirectory));
    server->SetServerBusy(PR_TRUE); // the server is now busy
    server->GetHostName(getter_Copies(hostName));
    server->GetUsername(getter_Copies(userName));
  }
  
  m_pop3ConData->uidlinfo = net_pop3_load_state(hostName, userName, mailDirectory);
  m_pop3ConData->biffstate = nsIMsgFolder::nsMsgBiffState_NoMail;
  
  if (m_pop3ConData->uidlinfo && numDaysToLeaveOnServer > 0)
  {
    PRUint32 nowInSeconds = TimeInSecondsFromPRTime(PR_Now());
    PRUint32 cutOffDay = nowInSeconds - (60 * 60 * 24 * numDaysToLeaveOnServer);
  
    PL_HashTableEnumerateEntries(m_pop3ConData->uidlinfo->hash, net_pop3_delete_old_msgs_mapper, (void *) cutOffDay);
  }
  const char* uidl = PL_strcasestr(queryPart.get(), "uidl=");
  PR_FREEIF(m_pop3ConData->only_uidl);

  if (uidl)
  {
    uidl += 5;
    char *only_uidl = PL_strdup(uidl);
    m_pop3ConData->only_uidl = nsUnescape(only_uidl);
    mSuppressListenerNotifications = PR_TRUE; // suppress on start and on stop because this url won't have any content to display
  }
  
  m_pop3ConData->next_state = POP3_START_CONNECT;
  m_pop3ConData->next_state_after_response = POP3_FINISH_CONNECT;
  if (NS_SUCCEEDED(rv))
  {
    m_pop3Server->SetRunningProtocol(this);
    return nsMsgProtocol::LoadUrl(aURL);
  }
  else
    return rv;
}

Here is the call graph for this function:

Here is the caller graph for this function:

nsresult nsPop3Protocol::MarkMsgForHost ( const char *  hostName,
const char *  userName,
nsIFileSpec mailDirectory,
nsVoidArray UIDLArray 
) [static]

Definition at line 482 of file nsPop3Protocol.cpp.

{
  if (!hostName || !userName || !mailDirectory)
    return NS_ERROR_NULL_POINTER;

  Pop3UidlHost *uidlHost = net_pop3_load_state(hostName, userName, mailDirectory);
  if (!uidlHost)
    return NS_ERROR_OUT_OF_MEMORY;

  PRBool changed = PR_FALSE;

  PRUint32 count = UIDLArray.Count();
  for (PRUint32 i = 0; i < count; i++)
  {
    MarkMsgInHashTable(uidlHost->hash,
      NS_STATIC_CAST(Pop3UidlEntry*,UIDLArray[i]), &changed);
  }

  if (changed)
    net_pop3_write_state(uidlHost, mailDirectory);
  net_pop3_free_state(uidlHost);
  return NS_OK;
}

Here is the call graph for this function:

void nsPop3Protocol::MarkMsgInHashTable ( PLHashTable hashTable,
const Pop3UidlEntry uidl,
PRBool changed 
) [static]

Definition at line 464 of file nsPop3Protocol.cpp.

{
  if (uidlE->uidl)
  {
    Pop3UidlEntry *uidlEntry = (Pop3UidlEntry *) PL_HashTableLookup(hashTable, uidlE->uidl);
    if (uidlEntry)
    {
      if (uidlEntry->status != uidlE->status)
      {
        uidlEntry->status = uidlE->status;
        *changed = PR_TRUE;
      }
    }
  }
}

Here is the call graph for this function:

Here is the caller graph for this function:

NS_IMETHODIMP nsPop3Protocol::OnStopRequest ( nsIRequest request,
nsISupports *  aContext,
nsresult  aStatus 
)

Definition at line 773 of file nsPop3Protocol.cpp.

{
  nsresult rv = nsMsgProtocol::OnStopRequest(request, aContext, aStatus);
  // turn off the server busy flag on stop request - we know we're done, right?
  if (m_pop3Server)
  {
    nsCOMPtr<nsIMsgIncomingServer> server = do_QueryInterface(m_pop3Server);
    if (server)
      server->SetServerBusy(PR_FALSE); // the server is not busy
  }
  if(m_pop3ConData->list_done)
    CommitState(PR_TRUE);
  if (NS_FAILED(aStatus) && aStatus != NS_BINDING_ABORTED)
    Abort();
  return rv;
}

Here is the call graph for this function:

NS_IMETHODIMP nsPop3Protocol::OnTransportStatus ( nsITransport transport,
nsresult  status,
PRUint32  progress,
PRUint32  progressMax 
)

Definition at line 767 of file nsPop3Protocol.cpp.

{
  return nsMsgProtocol::OnTransportStatus(aTransport, aStatus, aProgress, aProgressMax);
}
nsresult nsPop3Protocol::ProcessProtocolState ( nsIURI url,
nsIInputStream inputStream,
PRUint32  sourceOffset,
PRUint32  length 
) [private, virtual]

Definition at line 3600 of file nsPop3Protocol.cpp.

{
  PRInt32 status = 0;
  nsCOMPtr<nsIMsgMailNewsUrl> mailnewsurl = do_QueryInterface(m_url);
  
  PR_LOG(POP3LOGMODULE, PR_LOG_ALWAYS, ("Entering NET_ProcessPop3 %d",
    aLength));
  
  m_pop3ConData->pause_for_read = PR_FALSE; /* already paused; reset */
  
  if(m_username.IsEmpty())
  {
    // net_pop3_block = PR_FALSE;
    return(Error(POP3_USERNAME_UNDEFINED));
  }
  
  while(!m_pop3ConData->pause_for_read)
  {
    PR_LOG(POP3LOGMODULE, PR_LOG_ALWAYS, 
      ("POP3: Entering state: %d", m_pop3ConData->next_state));
    
    switch(m_pop3ConData->next_state)
    {
    case POP3_READ_PASSWORD:
    /* This is a separate state so that we're waiting for the
    user to type in a password while we don't actually have
    a connection to the pop server open; this saves us from
    having to worry about the server timing out on us while
      we wait for user input. */
      {
      /* If we're just checking for new mail (biff) then don't
      prompt the user for a password; just tell him we don't
        know whether he has new mail. */
        nsXPIDLCString password;
        PRBool okayValue;
        GetPassword(getter_Copies(password), &okayValue);
        const char * pwd = (const char *) password;
        if (!password || m_username.IsEmpty())
        {
          status = MK_POP3_PASSWORD_UNDEFINED;
          m_pop3ConData->biffstate = nsIMsgFolder::nsMsgBiffState_Unknown;
          m_nsIPop3Sink->SetBiffStateAndUpdateFE(m_pop3ConData->biffstate, 0, PR_FALSE);   
          
          /* update old style biff */
          m_pop3ConData->next_state = POP3_FREE;
          m_pop3ConData->pause_for_read = PR_FALSE;
          break;
        }
        
        if (m_username.IsEmpty() || !pwd)
        {
          m_pop3ConData->next_state = POP3_ERROR_DONE;
          m_pop3ConData->pause_for_read = PR_FALSE;
        }
        else
        {
          // we are already connected so just go on and send the username
          PRBool prefBool = PR_FALSE; 
          m_pop3ConData->pause_for_read = PR_FALSE;
          m_pop3Server->GetAuthLogin(&prefBool);
          
          if (prefBool) 
          {
            if (TestCapFlag(POP3_AUTH_MECH_UNDEFINED))
              m_pop3ConData->next_state = POP3_SEND_AUTH;
            else
              m_pop3ConData->next_state = POP3_SEND_CAPA;
          }
          else
            m_pop3ConData->next_state = POP3_SEND_USERNAME;
        }
        break;
      }
      
      
    case POP3_START_CONNECT:
      {
        m_pop3ConData->next_state = POP3_FINISH_CONNECT;
        m_pop3ConData->pause_for_read = PR_FALSE;
        break;
      }
      
    case POP3_FINISH_CONNECT:
      {
        m_pop3ConData->pause_for_read = PR_FALSE;
        m_pop3ConData->next_state = POP3_WAIT_FOR_START_OF_CONNECTION_RESPONSE;
        break;
      }
      
    case POP3_WAIT_FOR_RESPONSE:
      status = WaitForResponse(aInputStream, aLength);
      break;
      
    case POP3_WAIT_FOR_START_OF_CONNECTION_RESPONSE:
      {
        status = WaitForStartOfConnectionResponse(aInputStream, aLength);
        
        if(status)
        {
          PRBool prefBool = PR_FALSE;
          m_pop3Server->GetAuthLogin(&prefBool);
          
          if (prefBool)
          {
            if (TestCapFlag(POP3_AUTH_MECH_UNDEFINED))
              m_pop3ConData->next_state = POP3_SEND_AUTH;
            else
              m_pop3ConData->next_state = POP3_SEND_CAPA;
          }
          else
            m_pop3ConData->next_state = POP3_SEND_USERNAME;
        }
        
        break;
      }
      
    case POP3_SEND_AUTH:
      status = SendAuth();
      break;
      
    case POP3_AUTH_RESPONSE:
      status = AuthResponse(aInputStream, aLength);
      break;
      
   case POP3_SEND_CAPA:
      status = SendCapa();
      break;
      
    case POP3_CAPA_RESPONSE:
      status = CapaResponse(aInputStream, aLength);
      break;
      
    case POP3_TLS_RESPONSE:
      status = SendTLSResponse();
      break;

    case POP3_PROCESS_AUTH:
      status = ProcessAuth();
      break;
      
    case POP3_AUTH_FALLBACK:
      status = AuthFallback();
      break;
      
    case POP3_AUTH_LOGIN:
      status = AuthLogin();
      break;
      
    case POP3_AUTH_LOGIN_RESPONSE:
      status = AuthLoginResponse();
      break;
      
    case POP3_AUTH_NTLM:
      status = AuthNtlm();
      break;
      
    case POP3_AUTH_NTLM_RESPONSE:
      status = AuthNtlmResponse();
      break;
      
    case POP3_AUTH_GSSAPI:
      status = AuthGSSAPI();
      break;

    case POP3_AUTH_GSSAPI_FIRST:
      UpdateStatus(POP3_CONNECT_HOST_CONTACTED_SENDING_LOGIN_INFORMATION);
      status = AuthGSSAPIResponse(true);
      break;
 
    case POP3_AUTH_GSSAPI_STEP:
      status = AuthGSSAPIResponse(false);
      break;

    case POP3_SEND_USERNAME:
      UpdateStatus(POP3_CONNECT_HOST_CONTACTED_SENDING_LOGIN_INFORMATION);
      status = SendUsername();
      break;
      
    case POP3_SEND_PASSWORD:
      status = SendPassword();
      break;
      
    case POP3_SEND_GURL:
      status = SendGurl();
      break;
      
    case POP3_GURL_RESPONSE:
      status = GurlResponse();
      break;
      
    case POP3_SEND_STAT:
      status = SendStat();
      break;
      
    case POP3_GET_STAT:
      status = GetStat();
      break;
      
    case POP3_SEND_LIST:
      status = SendList();
      break;
      
    case POP3_GET_LIST:
      status = GetList(aInputStream, aLength);
      break;
      
    case POP3_SEND_UIDL_LIST:
      status = SendUidlList();
      break;
      
    case POP3_GET_UIDL_LIST:
      status = GetUidlList(aInputStream, aLength);
      break;
      
    case POP3_SEND_XTND_XLST_MSGID:
      status = SendXtndXlstMsgid();
      break;
      
    case POP3_GET_XTND_XLST_MSGID:
      status = GetXtndXlstMsgid(aInputStream, aLength);
      break;
      
    case POP3_START_USE_TOP_FOR_FAKE_UIDL:
      status = StartUseTopForFakeUidl();
      break;
      
    case POP3_SEND_FAKE_UIDL_TOP:
      status = SendFakeUidlTop();
      break;
      
    case POP3_GET_FAKE_UIDL_TOP:
      status = GetFakeUidlTop(aInputStream, aLength);
      break;
      
    case POP3_GET_MSG:
      status = GetMsg();
      break;
      
    case POP3_SEND_TOP:
      status = SendTop();
      break;
      
    case POP3_TOP_RESPONSE:
      status = TopResponse(aInputStream, aLength);
      break;
      
    case POP3_SEND_XSENDER:
      status = SendXsender();
      break;
      
    case POP3_XSENDER_RESPONSE:
      status = XsenderResponse();
      break;
      
    case POP3_SEND_RETR:
      status = SendRetr();
      break;
      
    case POP3_RETR_RESPONSE:
      status = RetrResponse(aInputStream, aLength);
      break;
      
    case POP3_SEND_DELE:
      status = SendDele();
      break;
      
    case POP3_DELE_RESPONSE:
      status = DeleResponse();
      break;
      
    case POP3_SEND_QUIT:
    /* attempt to send a server quit command.  Since this means
    everything went well, this is a good time to update the
    status file and the FE's biff state.
      */
      if (!m_pop3ConData->only_uidl) 
      {
        /* update old style biff */
        if (!m_pop3ConData->only_check_for_new_mail)
        {
        /* We don't want to pop up a warning message any more (see
        bug 54116), so instead we put the "no new messages" or
        "retrieved x new messages" 
        in the status line.  Unfortunately, this tends to be running
        in a progress pane, so we try to get the real pane and
          show the message there. */
          
          if (m_totalDownloadSize <= 0) 
          {
            UpdateStatus(POP3_NO_MESSAGES);
            /* There are no new messages.  */
          }
          else 
          {
            PRUnichar * statusTemplate = nsnull;
            mStringService->GetStringByID(POP3_DOWNLOAD_COUNT, &statusTemplate);
            if (statusTemplate)
            {
              PRUnichar * statusString = nsTextFormatter::smprintf(statusTemplate, 
                m_pop3ConData->real_new_counter - 1,
                m_pop3ConData->really_new_messages);  
              UpdateStatusWithString(statusString);
              nsTextFormatter::smprintf_free(statusString);
              nsCRT::free(statusTemplate);
              
            }
          }
        }
      }
      
      status = SendData(mailnewsurl, "QUIT" CRLF);
      m_pop3ConData->next_state = POP3_WAIT_FOR_RESPONSE;
      m_pop3ConData->next_state_after_response = POP3_QUIT_RESPONSE;
      break;
      
    case POP3_QUIT_RESPONSE:
      if(m_pop3ConData->command_succeeded)
      {
      /*  the QUIT succeeded.  We can now flush the state in popstate.dat which
        keeps track of any uncommitted DELE's */
        
        /* here we need to clear the hash of all our 
        uncommitted deletes */
        /*
        if (m_pop3ConData->uidlinfo &&
        m_pop3ConData->uidlinfo->uncommitted_deletes) 
        XP_Clrhash (m_pop3ConData->uidlinfo->uncommitted_deletes);*/
        //delete the uidl because deletes are committed
        if (!m_pop3ConData->leave_on_server && m_pop3ConData->newuidl){  
          PL_HashTableEnumerateEntries(m_pop3ConData->newuidl, 
                                                        net_pop3_remove_messages_marked_delete,
                                                                (void *)m_pop3ConData);   
        }
        
        
        m_pop3ConData->next_state = POP3_DONE;
        
      }
      else
      {
        m_pop3ConData->next_state = POP3_ERROR_DONE;
      }
      break;
      
    case POP3_DONE:
      CommitState(PR_FALSE);
      
      if (mailnewsurl)
        mailnewsurl->SetUrlState(PR_FALSE, NS_OK);
      m_pop3ConData->next_state = POP3_FREE;
      break;
      
    case POP3_INTERRUPTED:
      SendData(mailnewsurl, "QUIT" CRLF);
      m_pop3ConData->pause_for_read = PR_FALSE;
      m_pop3ConData->next_state = POP3_ERROR_DONE;
      break;
      
    case POP3_ERROR_DONE:
      /*  write out the state */
      if(m_pop3ConData->list_done)
        CommitState(PR_TRUE);
      
      if(m_pop3ConData->msg_closure)
      {
        m_nsIPop3Sink->IncorporateAbort(m_pop3ConData->only_uidl != nsnull);
        m_pop3ConData->msg_closure = NULL;
        m_nsIPop3Sink->AbortMailDelivery(this);
      }
      
      if(m_pop3ConData->msg_del_started)
      {
        PRUnichar * statusTemplate = nsnull;
        mStringService->GetStringByID(POP3_DOWNLOAD_COUNT, &statusTemplate);
        if (statusTemplate)
        {
          PRUnichar * statusString = nsTextFormatter::smprintf(statusTemplate, 
            m_pop3ConData->real_new_counter - 1,
            m_pop3ConData->really_new_messages);  
          UpdateStatusWithString(statusString);
          nsTextFormatter::smprintf_free(statusString);
          nsCRT::free(statusTemplate);
        }
        
        NS_ASSERTION (!TestFlag(POP3_PASSWORD_FAILED), "POP3_PASSWORD_FAILED set when del_started");
        m_nsIPop3Sink->AbortMailDelivery(this);
      }
      
      if (TestFlag(POP3_PASSWORD_FAILED) && m_pop3ConData->logonFailureCount < 6)
      {
      /* We got here because the password was wrong, so go
        read a new one and re-open the connection. */
        m_pop3ConData->next_state = POP3_READ_PASSWORD;
        m_pop3ConData->command_succeeded = PR_TRUE;
        status = 0;
        break;
      }
      else
        /* Else we got a "real" error, so finish up. */
        m_pop3ConData->next_state = POP3_FREE;       
      
      if (mailnewsurl)
        mailnewsurl->SetUrlState(PR_FALSE, NS_ERROR_FAILURE);
      m_pop3ConData->pause_for_read = PR_FALSE;
      break;
      
    case POP3_FREE:
      UpdateProgressPercent(0,0); // clear out the progress meter
      NS_ASSERTION(m_nsIPop3Sink, "with no sink, can't clear busy flag");
      if (m_nsIPop3Sink)
      {
        nsCOMPtr<nsIMsgIncomingServer> server = do_QueryInterface(m_pop3Server);
        if (server)
          server->SetServerBusy(PR_FALSE); // the server is now not busy
      }
      m_pop3Server->SetRunningProtocol(nsnull);
      
      CloseSocket();
      return NS_OK;
      break;
      
    default:
      PR_ASSERT(0);
      
    }  /* end switch */
              
    if((status < 0) && m_pop3ConData->next_state != POP3_FREE)
    {
      m_pop3ConData->pause_for_read = PR_FALSE;
      m_pop3ConData->next_state = POP3_ERROR_DONE;
    }
    
  }  /* end while */
  
  return NS_OK;
          
}

Definition at line 1473 of file nsPop3Protocol.cpp.

Here is the caller graph for this function:

PRInt32 nsPop3Protocol::RetrResponse ( nsIInputStream inputStream,
PRUint32  length 
) [private]

Definition at line 3108 of file nsPop3Protocol.cpp.

{
    PRUint32 buffer_size;
    PRInt32 flags = 0;
    char *uidl = NULL;
    nsresult rv;
#if 0
    PRInt32 old_bytes_received = m_totalBytesReceived;
#endif
    PRUint32 status = 0;

    if(m_pop3ConData->cur_msg_size == -1)
    {
        /* this is the beginning of a message
         * get the response code and byte size
         */
        if(!m_pop3ConData->command_succeeded)
            return Error(POP3_RETR_FAILURE);
        
        /* a successful RETR response looks like: #num_bytes Junk
           from TOP we only get the +OK and data
           */
        if (m_pop3ConData->truncating_cur_msg)
        { /* TOP, truncated message */
            flags |= MSG_FLAG_PARTIAL;
        }
        else
        {
          char *newStr;
          char * oldStr = ToNewCString(m_commandResponse);
          char *num = nsCRT::strtok(oldStr, " ", &newStr);
          if (num)
            m_pop3ConData->cur_msg_size = atol(num);
          m_commandResponse = newStr;
          PR_Free(oldStr);
        }

        /* RETR complete message */
        if (!m_senderInfo.IsEmpty())
            flags |= MSG_FLAG_SENDER_AUTHED;
        
        if(m_pop3ConData->cur_msg_size <= 0)
        {
          if (m_pop3ConData->msg_info)
            m_pop3ConData->cur_msg_size = m_pop3ConData->msg_info[m_pop3ConData->last_accessed_msg].size;
          else
            m_pop3ConData->cur_msg_size = 0;
        }

        if (m_pop3ConData->msg_info && 
            m_pop3ConData->msg_info[m_pop3ConData->last_accessed_msg].uidl)
            uidl = m_pop3ConData->msg_info[m_pop3ConData->last_accessed_msg].uidl;

        m_pop3ConData->parsed_bytes = 0;
        m_pop3ConData->pop3_size = m_pop3ConData->cur_msg_size;
        m_pop3ConData->assumed_end = PR_FALSE;
        
        m_pop3Server->GetDotFix(&m_pop3ConData->dot_fix);

        PR_LOG(POP3LOGMODULE,PR_LOG_ALWAYS, 
               ("Opening message stream: MSG_IncorporateBegin"));

        /* open the message stream so we have someplace
         * to put the data
         */
        m_pop3ConData->real_new_counter++;
        /* (rb) count only real messages being downloaded */
        rv = m_nsIPop3Sink->IncorporateBegin(uidl, m_url, flags,
                                        &m_pop3ConData->msg_closure); 

        PR_LOG(POP3LOGMODULE, PR_LOG_ALWAYS, ("Done opening message stream!"));

        if(!m_pop3ConData->msg_closure || NS_FAILED(rv))
            return(Error(POP3_MESSAGE_WRITE_ERROR));
    }
    
    m_pop3ConData->pause_for_read = PR_TRUE;

    PRBool pauseForMoreData = PR_FALSE;
    char *line = m_lineStreamBuffer->ReadNextLine(inputStream, status, pauseForMoreData, &rv, PR_TRUE);
    if (NS_FAILED(rv))
      return -1;

    PR_LOG(POP3LOGMODULE, PR_LOG_ALWAYS,("RECV: %s", line));
    buffer_size = status;

    if (status == 0 && !line)  // no bytes read in...
      return (0);

    if (m_pop3ConData->msg_closure) /* not done yet */
    {
      // buffer the line we just read in, and buffer all remaining lines in the stream
      status = buffer_size;
      do
      {
        if (m_pop3ConData->msg_closure)
        {
          rv = HandleLine(line, buffer_size);
          if (NS_FAILED(rv))
            return (Error(POP3_MESSAGE_WRITE_ERROR));

          // buffer_size already includes MSG_LINEBREAK_LEN so
          // subtract and add CRLF
          // but not really sure we always had CRLF in input since
          // we also treat a single LF as line ending!
          m_pop3ConData->parsed_bytes += buffer_size - MSG_LINEBREAK_LEN + 2;
        }

        // now read in the next line
        PR_Free(line);
        line = m_lineStreamBuffer->ReadNextLine(inputStream, buffer_size,
                                                pauseForMoreData, &rv, PR_TRUE);
        PR_LOG(POP3LOGMODULE, PR_LOG_ALWAYS,("RECV: %s", line));
        // buffer_size already includes MSG_LINEBREAK_LEN so
        // subtract and add CRLF
        // but not really sure we always had CRLF in input since
        // we also treat a single LF as line ending!
        status += buffer_size - MSG_LINEBREAK_LEN + 2;
      } while (line);
    }

    buffer_size = status;  // status holds # bytes we've actually buffered so far...
  
    /* normal read. Yay! */
    if ((PRInt32) (m_bytesInMsgReceived + buffer_size) >
        m_pop3ConData->cur_msg_size) 
        buffer_size = m_pop3ConData->cur_msg_size -
            m_bytesInMsgReceived; 
    
    m_bytesInMsgReceived += buffer_size;
    m_totalBytesReceived += buffer_size;

    // *** jefft in case of the message size that server tells us is different
    // from the actual message size
    if (pauseForMoreData && m_pop3ConData->dot_fix &&
        m_pop3ConData->assumed_end && m_pop3ConData->msg_closure)
    {
        nsCOMPtr<nsIMsgMailNewsUrl> mailnewsUrl = do_QueryInterface(m_url, &rv);
        nsCOMPtr<nsIMsgWindow> msgWindow;
        if (NS_SUCCEEDED(rv))
          rv = mailnewsUrl->GetMsgWindow(getter_AddRefs(msgWindow));
        rv = m_nsIPop3Sink->IncorporateComplete(msgWindow,
          m_pop3ConData->truncating_cur_msg ? m_pop3ConData->cur_msg_size : 0);

        // The following was added to prevent the loss of Data when we try
        // and write to somewhere we dont have write access error to (See
        // bug 62480)
        // (Note: This is only a temp hack until the underlying XPCOM is
        // fixed to return errors)

        if (NS_FAILED(rv))
            return (Error((rv == NS_MSG_ERROR_COPYING_FROM_TMP_DOWNLOAD)
                           ? POP3_TMP_DOWNLOAD_FAILED 
                           : POP3_MESSAGE_WRITE_ERROR));

        m_pop3ConData->msg_closure = nsnull;
    }
    
    if (!m_pop3ConData->msg_closure)
        /* meaning _handle_line read ".\r\n" at end-of-msg */
    {
        m_pop3ConData->pause_for_read = PR_FALSE;

        if (m_pop3ConData->truncating_cur_msg ||
            m_pop3ConData->leave_on_server )
        {
            Pop3UidlEntry *uidlEntry = NULL;
            Pop3MsgInfo* info = m_pop3ConData->msg_info + m_pop3ConData->last_accessed_msg; 

            /* Check for filter actions - FETCH or DELETE */
            if ((m_pop3ConData->newuidl) && (info->uidl))
              uidlEntry = (Pop3UidlEntry *)PL_HashTableLookup(m_pop3ConData->newuidl, info->uidl);

            if (uidlEntry && uidlEntry->status == FETCH_BODY &&
                m_pop3ConData->truncating_cur_msg)
            {
            /* A filter decided to retrieve this full msg.
               Use GetMsg() so the popstate will update correctly,
               but don't let this msg get counted twice. */
               m_pop3ConData->next_state = POP3_GET_MSG;
               m_pop3ConData->real_new_counter--;
            /* Make sure we don't try to come through here again. */
               PL_HashTableRemove (m_pop3ConData->newuidl, (void*)info->uidl);
               put_hash(m_pop3ConData->uidlinfo->hash, info->uidl, FETCH_BODY, uidlEntry->dateReceived);

            } else if (uidlEntry && uidlEntry->status == DELETE_CHAR)
            {
            // A filter decided to delete this msg from the server
               m_pop3ConData->next_state = POP3_SEND_DELE;
            } else
            {
            /* We've retrieved all or part of this message, but we want to
               keep it on the server.  Go on to the next message. */
               m_pop3ConData->last_accessed_msg++;
               m_pop3ConData->next_state = POP3_GET_MSG;
            }
            if (m_pop3ConData->only_uidl)
            {
            /* GetMsg didn't update this field. Do it now */
               uidlEntry = (Pop3UidlEntry *)PL_HashTableLookup(m_pop3ConData->uidlinfo->hash, m_pop3ConData->only_uidl);
               NS_ASSERTION(uidlEntry, "uidl not found in uidlinfo");
               if (uidlEntry)
             put_hash(m_pop3ConData->uidlinfo->hash, m_pop3ConData->only_uidl, KEEP, uidlEntry->dateReceived);
            }
        } else
        {
            m_pop3ConData->next_state = POP3_SEND_DELE;
        }
        
        /* if we didn't get the whole message add the bytes that we didn't get
           to the bytes received part so that the progress percent stays sane.
           */
        if(m_bytesInMsgReceived < m_pop3ConData->cur_msg_size)
            m_totalBytesReceived += (m_pop3ConData->cur_msg_size -
                                   m_bytesInMsgReceived);
    }

    /* set percent done to portion of total bytes of all messages
       that we're going to download. */
    if (m_totalDownloadSize)
      UpdateProgressPercent(m_totalBytesReceived, m_totalDownloadSize);

    PR_Free(line);    
    return(0);
}

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 1143 of file nsPop3Protocol.cpp.

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 1236 of file nsPop3Protocol.cpp.

{
    if(!m_pop3ConData->command_succeeded)
        return(Error(POP3_SERVER_ERROR));

    // for use after mechs disabled fallbacks when login failed
    // should better live in AuthResponse(), but it would only
    // be called the first time then
    BackupAuthFlags();

    nsCAutoString command("CAPA" CRLF);

    m_pop3ConData->next_state_after_response = POP3_CAPA_RESPONSE;
    return SendData(m_url, command.get());
}

Here is the call graph for this function:

Here is the caller graph for this function:

PRInt32 nsPop3Protocol::SendData ( nsIURI aURL,
const char *  dataBuffer,
PRBool  aSuppressLogging = PR_FALSE 
) [private, virtual]

Definition at line 1114 of file nsPop3Protocol.cpp.

{
  // remove any leftover bytes in the line buffer
  // this can happen if the last message line doesn't end with a (CR)LF
  // or a server sent two reply lines
  m_lineStreamBuffer->ClearBuffer();

  PRInt32 result = nsMsgProtocol::SendData(aURL, dataBuffer);

  if (!aSuppressLogging) 
      PR_LOG(POP3LOGMODULE, PR_LOG_ALWAYS, ("SEND: %s", dataBuffer));        
  else 
      PR_LOG(POP3LOGMODULE, PR_LOG_ALWAYS, ("Logging suppressed for this command (it probably contained authentication information)"));

  if (result >= 0) // yeah this sucks...i need an error code....
  {
    m_pop3ConData->pause_for_read = PR_TRUE;
    m_pop3ConData->next_state = POP3_WAIT_FOR_RESPONSE;
  }
  else
    m_pop3ConData->next_state = POP3_ERROR_DONE;

  return 0;
}

Here is the caller graph for this function:

Definition at line 3451 of file nsPop3Protocol.cpp.

{
    /* increment the last accessed message since we have now read it
     */
    char * cmd = PR_smprintf("DELE %ld" CRLF, m_pop3ConData->msg_info[m_pop3ConData->last_accessed_msg].msgnum);
    m_pop3ConData->last_accessed_msg++;
       PRInt32 status = -1;
       if (cmd)
       {
              m_pop3ConData->next_state_after_response = POP3_DELE_RESPONSE;
              status = SendData(m_url, cmd);
       }
       PR_Free(cmd);
       return status;
}

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 2178 of file nsPop3Protocol.cpp.

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 2053 of file nsPop3Protocol.cpp.

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 2084 of file nsPop3Protocol.cpp.

{
    // check for server returning number of messages that will cause the calculation
    // of the size of the block for msg_info to
    // overflow a 32 bit int, in turn causing us to allocate a block of memory much
    // smaller than we think we're allocating, and
    // potentially allowing the server to make us overwrite memory outside our heap
    // block.

    if (m_pop3ConData->number_of_messages > (0xFFFFF000 / sizeof(Pop3MsgInfo)))
        return MK_OUT_OF_MEMORY; 


    m_pop3ConData->msg_info = (Pop3MsgInfo *) 
      PR_CALLOC(sizeof(Pop3MsgInfo) * m_pop3ConData->number_of_messages);
    if (!m_pop3ConData->msg_info)
        return(MK_OUT_OF_MEMORY);
    m_pop3ConData->next_state_after_response = POP3_GET_LIST;
    m_listpos = 0;
    return SendData(m_url, "LIST"CRLF);
}

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 1792 of file nsPop3Protocol.cpp.

{
    if (m_username.IsEmpty())
        return(Error(POP3_USERNAME_UNDEFINED));

    nsXPIDLCString password;
    PRBool okayValue = PR_TRUE;
    nsresult rv = GetPassword(getter_Copies(password), &okayValue);
    if (NS_SUCCEEDED(rv) && !okayValue)
    {
        // user has canceled the password prompt
        m_pop3ConData->next_state = POP3_ERROR_DONE;
        return NS_ERROR_ABORT;
    }
    else if (NS_FAILED(rv) || !password)
    {
      return Error(POP3_PASSWORD_UNDEFINED);
    }

    nsCAutoString cmd;
    if (m_useSecAuth)
    {
        if (TestCapFlag(POP3_HAS_AUTH_CRAM_MD5))
        {
            char buffer[512];
            unsigned char digest[DIGEST_LENGTH];

            char *decodedChallenge = PL_Base64Decode(m_commandResponse.get(), 
            m_commandResponse.Length(), nsnull);

            if (decodedChallenge)
                rv = MSGCramMD5(decodedChallenge, strlen(decodedChallenge), password.get(), password.Length(), digest);
            else
                rv = NS_ERROR_FAILURE;

            if (NS_SUCCEEDED(rv) && digest)
            {
                nsCAutoString encodedDigest;
                char hexVal[8];

                for (PRUint32 j=0; j<16; j++) 
                {
                    PR_snprintf (hexVal,8, "%.2x", 0x0ff & (unsigned short)digest[j]);
                    encodedDigest.Append(hexVal); 
                }

                PR_snprintf(buffer, sizeof(buffer), "%s %s", m_username.get(), encodedDigest.get());
                char *base64Str = PL_Base64Encode(buffer, strlen(buffer), nsnull);
                cmd = base64Str;
                PR_Free(base64Str);
            }

            if (NS_FAILED(rv))
                cmd = "*";
        }
        else if (TestCapFlag(POP3_HAS_AUTH_NTLM))
            rv = DoNtlmStep2(m_commandResponse, cmd);
        else if (TestCapFlag(POP3_HAS_AUTH_APOP))
        {
            char buffer[512];
            unsigned char digest[DIGEST_LENGTH];

            rv = MSGApopMD5(m_ApopTimestamp.get(), m_ApopTimestamp.Length(), password.get(), password.Length(), digest);

            if (NS_SUCCEEDED(rv) && digest)
            {
                nsCAutoString encodedDigest;
                char hexVal[8];

                for (PRUint32 j=0; j<16; j++) 
                {
                    PR_snprintf (hexVal,8, "%.2x", 0x0ff & (unsigned short)digest[j]);
                    encodedDigest.Append(hexVal); 
                }

                PR_snprintf(buffer, sizeof(buffer), "APOP %s %s", m_username.get(), encodedDigest.get());
                cmd = buffer;
            }

            if (NS_FAILED(rv))
                cmd = "*";
        }
    }
    else
    {
        if (TestCapFlag(POP3_HAS_AUTH_PLAIN))
        {
            // workaround for IPswitch's IMail server software
            // this server goes into LOGIN mode even if we send "AUTH PLAIN"
            // "VXNlc" is the begin of the base64 encoded prompt for LOGIN
            if (m_commandResponse.Compare("VXNlc", PR_FALSE, 5) == 0)
            {
                // disable PLAIN and enable LOGIN (in case it's not already enabled)
                ClearCapFlag(POP3_HAS_AUTH_PLAIN);
                SetCapFlag(POP3_HAS_AUTH_LOGIN);
                m_pop3Server->SetPop3CapabilityFlags(m_pop3ConData->capability_flags);

                // reenter authentication again at LOGIN response handler
                m_pop3ConData->next_state = POP3_AUTH_LOGIN_RESPONSE;
                m_pop3ConData->pause_for_read = PR_FALSE;
                return 0;
            }

            char plain_string[512];
            int len = 1; /* first <NUL> char */

            memset(plain_string, 0, 512);
            PR_snprintf(&plain_string[1], 510, "%s", m_username.get());
            len += m_username.Length();
            len++; /* second <NUL> char */
            PR_snprintf(&plain_string[len], 511-len, "%s", password.get());
            len += password.Length();

            char *base64Str = PL_Base64Encode(plain_string, len, nsnull);
            cmd = base64Str;
            PR_Free(base64Str);
        }
        else if (TestCapFlag(POP3_HAS_AUTH_LOGIN)) 
        {
            char * base64Str = 
                PL_Base64Encode(password, PL_strlen(password), nsnull);
            cmd = base64Str;
            PR_Free(base64Str);
        }
        else
        {
            cmd = "PASS ";
            cmd += password;    
        }
    }
    cmd += CRLF;

    m_pop3Server->SetPop3CapabilityFlags(m_pop3ConData->capability_flags);

    m_pop3ConData->next_state_after_response = POP3_AUTH_FALLBACK;

    m_pop3ConData->pause_for_read = PR_TRUE;

    m_password_already_sent = PR_TRUE;
    m_lastPasswordSent = password;
    return SendData(m_url, cmd.get(), PR_TRUE);
}

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 3044 of file nsPop3Protocol.cpp.

{
  
  char * cmd = PR_smprintf("RETR %ld" CRLF, m_pop3ConData->msg_info[m_pop3ConData->last_accessed_msg].msgnum);
  PRInt32 status = -1;
  if (cmd)
  {
    m_pop3ConData->next_state_after_response = POP3_RETR_RESPONSE;    
    m_pop3ConData->cur_msg_size = -1;
    
    
    /* zero the bytes received in message in preparation for
    * the next
    */
    m_bytesInMsgReceived = 0;
    
    if (m_pop3ConData->only_uidl)
    {
      /* Display bytes if we're only downloading one message. */
      PR_ASSERT(!m_pop3ConData->graph_progress_bytes_p);
      UpdateProgressPercent(0, m_totalDownloadSize);
      m_pop3ConData->graph_progress_bytes_p = PR_TRUE;
    }
    else
    {
      nsresult rv;
      
      nsAutoString realNewString;
      realNewString.AppendInt(m_pop3ConData->real_new_counter);
      
      nsAutoString reallyNewMessages;
      reallyNewMessages.AppendInt(m_pop3ConData->really_new_messages);
      
      nsCOMPtr<nsIStringBundle> bundle;
      rv = mStringService->GetBundle(getter_AddRefs(bundle));
      NS_ASSERTION(NS_SUCCEEDED(rv), "couldn't get bundle");
      
      if (bundle)
      {
        const PRUnichar *formatStrings[] = {
          realNewString.get(),
            reallyNewMessages.get(),
        };
        
        nsXPIDLString finalString;
        rv = bundle->FormatStringFromID(LOCAL_STATUS_RECEIVING_MESSAGE_OF,
          formatStrings, 2,
          getter_Copies(finalString));
        NS_ASSERTION(NS_SUCCEEDED(rv), "couldn't format string");
        
        if (m_statusFeedback)
          m_statusFeedback->ShowStatusString(finalString);
      }
    }
    
    status = SendData(m_url, cmd);
  } // if cmd
  PR_Free(cmd);
  return status;
}

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 1953 of file nsPop3Protocol.cpp.

{
  return SendStatOrGurl(PR_TRUE);
}

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 1935 of file nsPop3Protocol.cpp.

{
  nsCAutoString cmd;
  if (sendStat) 
  {
    cmd  = "STAT" CRLF;
    m_pop3ConData->next_state_after_response = POP3_GET_STAT;
  }
  else 
  {
    cmd = "GURL" CRLF;
    m_pop3ConData->next_state_after_response = POP3_GURL_RESPONSE;
  }
  return SendData(m_url, cmd.get());
}

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 1361 of file nsPop3Protocol.cpp.

{
  // only tear down our existing connection and open a new one if we received
  // a +OK response from the pop server after we issued the STLS command
  nsresult rv = NS_OK;
  if (m_pop3ConData->command_succeeded) 
  {
      nsCOMPtr<nsISupports> secInfo;
      nsCOMPtr<nsISocketTransport> strans = do_QueryInterface(m_transport, &rv);
      if (NS_FAILED(rv)) return rv;

      rv = strans->GetSecurityInfo(getter_AddRefs(secInfo));

      if (NS_SUCCEEDED(rv) && secInfo)
      {
          nsCOMPtr<nsISSLSocketControl> sslControl = do_QueryInterface(secInfo, &rv);

          if (NS_SUCCEEDED(rv) && sslControl)
              rv = sslControl->StartTLS();
      }

    if (NS_SUCCEEDED(rv))
    {
      m_pop3ConData->next_state = POP3_SEND_AUTH;
      m_tlsEnabled = PR_TRUE;

      // certain capabilities like POP3_HAS_AUTH_APOP should be 
      // preserved across the connections.
      PRUint32 preservedCapFlags = m_pop3ConData->capability_flags & POP3_HAS_AUTH_APOP;
      m_pop3ConData->capability_flags =     // resetting the flags
        POP3_AUTH_MECH_UNDEFINED |
        POP3_HAS_AUTH_USER |                // should be always there
        POP3_GURL_UNDEFINED |
        POP3_UIDL_UNDEFINED |
        POP3_TOP_UNDEFINED |
        POP3_XTND_XLST_UNDEFINED | 
        preservedCapFlags;
      m_pop3Server->SetPop3CapabilityFlags(m_pop3ConData->capability_flags);
      return rv;
    }
  }

  ClearFlag(POP3_HAS_STLS);
  m_pop3ConData->next_state = POP3_PROCESS_AUTH;

  return rv;
}

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 2984 of file nsPop3Protocol.cpp.

{
   char * cmd = PR_smprintf( "TOP %ld %d" CRLF,
     m_pop3ConData->msg_info[m_pop3ConData->last_accessed_msg].msgnum,
     m_pop3ConData->headers_only ? 0 : 20);
   PRInt32 status = -1;
   if (cmd)
   {
     m_pop3ConData->next_state_after_response = POP3_TOP_RESPONSE;    
     m_pop3ConData->cur_msg_size = -1;
     
     /* zero the bytes received in message in preparation for
     * the next
     */
     m_bytesInMsgReceived = 0;
     status = SendData(m_url,cmd);
   }
   PR_Free(cmd);
   return status;
}

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 2558 of file nsPop3Protocol.cpp.

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 1739 of file nsPop3Protocol.cpp.

{
    if(m_username.IsEmpty())
        return(Error(POP3_USERNAME_UNDEFINED));

    nsXPIDLCString password;
    PRBool okayValue = PR_TRUE;
    nsresult rv = GetPassword(getter_Copies(password), &okayValue);
    if (NS_SUCCEEDED(rv) && !okayValue)
    {
        // user has canceled the password prompt
        m_pop3ConData->next_state = POP3_ERROR_DONE;
        return NS_ERROR_ABORT;
    }
    else if (NS_FAILED(rv) || !password)
    {
      return Error(POP3_PASSWORD_UNDEFINED);
    }

    nsCAutoString cmd;

    if (m_useSecAuth)
    {
        if (TestCapFlag(POP3_HAS_AUTH_CRAM_MD5))
            cmd = "AUTH CRAM-MD5";
        else if (TestCapFlag(POP3_HAS_AUTH_NTLM))
            rv = DoNtlmStep1(m_username.get(), password.get(), cmd);
    }
    else
    {
        if (TestCapFlag(POP3_HAS_AUTH_PLAIN))
            cmd = "AUTH PLAIN";
        else if (TestCapFlag(POP3_HAS_AUTH_LOGIN))
        {
            char *base64Str = PL_Base64Encode(m_username.get(), m_username.Length(), nsnull);
            cmd = base64Str;
            PR_Free(base64Str);
        }
        else
        {
            cmd = "USER ";
            cmd += m_username;
        }
    }
    cmd += CRLF;

    m_pop3ConData->next_state_after_response = POP3_AUTH_FALLBACK;

    m_pop3ConData->pause_for_read = PR_TRUE;

    return SendData(m_url, cmd.get());
}

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 3007 of file nsPop3Protocol.cpp.

{
  char * cmd = PR_smprintf("XSENDER %ld" CRLF, m_pop3ConData->msg_info[m_pop3ConData->last_accessed_msg].msgnum);
  PRInt32 status = -1;
  if (cmd)
  {  
    m_pop3ConData->next_state_after_response = POP3_XSENDER_RESPONSE;
    status = SendData(m_url, cmd);
    PR_Free(cmd);
  }
  return status;
}

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 2431 of file nsPop3Protocol.cpp.

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 641 of file nsPop3Protocol.cpp.

Here is the caller graph for this function:

Definition at line 686 of file nsPop3Protocol.cpp.

{
  NS_ASSERTION(name, "no name specified!");
    if (name) 
      m_username = name;
}

Here is the caller graph for this function:

Definition at line 2194 of file nsPop3Protocol.cpp.

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 651 of file nsPop3Protocol.cpp.

Here is the caller graph for this function:

PRInt32 nsPop3Protocol::TopResponse ( nsIInputStream inputStream,
PRUint32  length 
) [private]

Definition at line 3337 of file nsPop3Protocol.cpp.

{
  if (TestCapFlag(POP3_TOP_UNDEFINED))
  {
    ClearCapFlag(POP3_TOP_UNDEFINED);
    if (m_pop3ConData->command_succeeded)
      SetCapFlag(POP3_HAS_TOP);
    else
      ClearCapFlag(POP3_HAS_TOP);
    m_pop3Server->SetPop3CapabilityFlags(m_pop3ConData->capability_flags);
  }
  
  if(m_pop3ConData->cur_msg_size == -1 &&  /* first line after TOP command sent */
    !m_pop3ConData->command_succeeded)    /* and TOP command failed */
  {
  /* TOP doesn't work so we can't retrieve the first part of this msg.
  So just go download the whole thing, and warn the user.
  
    Note that the progress bar will not be accurate in this case.
    Oops. #### */
    PRBool prefBool = PR_FALSE;
    m_pop3ConData->truncating_cur_msg = PR_FALSE;
    
    PRUnichar * statusTemplate = nsnull;
    mStringService->GetStringByID(POP3_SERVER_DOES_NOT_SUPPORT_THE_TOP_COMMAND, &statusTemplate);
    if (statusTemplate)
    {
      nsCAutoString hostName;
      PRUnichar * statusString = nsnull;
      m_url->GetHost(hostName);
      
      statusString = nsTextFormatter::smprintf(statusTemplate, hostName.get());
      UpdateStatusWithString(statusString);
      nsTextFormatter::smprintf_free(statusString);
      nsCRT::free(statusTemplate);
    }
    
    m_pop3Server->GetAuthLogin(&prefBool);
    
    if (prefBool && 
      (TestCapFlag(POP3_HAS_XSENDER)))
      m_pop3ConData->next_state = POP3_SEND_XSENDER;
    else
      m_pop3ConData->next_state = POP3_SEND_RETR;
    return(0);
  }
  
  /* If TOP works, we handle it in the same way as RETR. */
  return RetrResponse(inputStream, length);
}

Here is the call graph for this function:

Here is the caller graph for this function:

void nsPop3Protocol::UpdateProgressPercent ( PRUint32  totalDone,
PRUint32  total 
) [private]

Definition at line 677 of file nsPop3Protocol.cpp.

{
  // XXX 64-bit
  if (mProgressEventSink)
    mProgressEventSink->OnProgress(this, m_channelContext, nsUint64(totalDone), nsUint64(total)); 
}

Here is the caller graph for this function:

void nsPop3Protocol::UpdateStatus ( PRInt32  aStatusID) [private]

Definition at line 656 of file nsPop3Protocol.cpp.

{
  if (m_statusFeedback)
  {
    PRUnichar * statusString = nsnull;
    mStringService->GetStringByID(aStatusID, &statusString);
    UpdateStatusWithString(statusString);
    nsCRT::free(statusString);
  }
}

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 667 of file nsPop3Protocol.cpp.

{
    nsresult rv;
    if (mProgressEventSink) 
    {
        rv = mProgressEventSink->OnStatus(this, m_channelContext, NS_OK, aStatusString);      // XXX i18n message
        NS_ASSERTION(NS_SUCCEEDED(rv), "dropping error result");
    }
}

Here is the caller graph for this function:

PRInt32 nsPop3Protocol::WaitForResponse ( nsIInputStream inputStream,
PRUint32  length 
) [private]

Definition at line 992 of file nsPop3Protocol.cpp.

{
  char * line;
  PRUint32 ln = 0;
  PRBool pauseForMoreData = PR_FALSE;
  nsresult rv;
  line = m_lineStreamBuffer->ReadNextLine(inputStream, ln, pauseForMoreData, &rv);
  if (NS_FAILED(rv))
    return -1;
  
  if(pauseForMoreData || !line)
  {
    m_pop3ConData->pause_for_read = PR_TRUE; /* pause */

    PR_Free(line);
    return(ln);
  }

  PR_LOG(POP3LOGMODULE, PR_LOG_ALWAYS,("RECV: %s", line));

  if(*line == '+')
  {
    m_pop3ConData->command_succeeded = PR_TRUE;
    if(PL_strlen(line) > 4)
    {
      if(!PL_strncasecmp(line, "+OK", 3))
        m_commandResponse = line + 4;
      else  // challenge answer to AUTH CRAM-MD5 and LOGIN username/password
        m_commandResponse = line + 2;
    }
    else
      m_commandResponse = line;
  }
  else
  {
    m_pop3ConData->command_succeeded = PR_FALSE;
    if(PL_strlen(line) > 5)
      m_commandResponse = line + 5;
    else
      m_commandResponse  = line;

    // search for the response codes (RFC 2449, chapter 8 and RFC 3206)
    if(TestCapFlag(POP3_HAS_RESP_CODES | POP3_HAS_AUTH_RESP_CODE))
    {
        // code for authentication failure due to the user's credentials
        if(m_commandResponse.Find("[AUTH", PR_TRUE) >= 0)
          SetFlag(POP3_AUTH_FAILURE);

        // codes for failures due to other reasons
        if(m_commandResponse.Find("[LOGIN-DELAY", PR_TRUE) >= 0 ||
           m_commandResponse.Find("[IN-USE", PR_TRUE) >= 0 ||
           m_commandResponse.Find("[SYS", PR_TRUE) >= 0)
      SetFlag(POP3_STOPLOGIN);

      // remove the codes from the response string presented to the user
      PRInt32 i = m_commandResponse.FindChar(']');
      if(i >= 0)
        m_commandResponse.Cut(0, i + 2);
    }
  }
  
  m_pop3ConData->next_state = m_pop3ConData->next_state_after_response;
  m_pop3ConData->pause_for_read = PR_FALSE; /* don't pause */
  
  PR_Free(line);
  return(1);  /* everything ok */
}

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 939 of file nsPop3Protocol.cpp.

{
  char * line = nsnull;
  PRUint32 line_length = 0;
  PRBool pauseForMoreData = PR_FALSE;
  nsresult rv;
  line = m_lineStreamBuffer->ReadNextLine(aInputStream, line_length, pauseForMoreData, &rv);
  if (NS_FAILED(rv))
    return -1;

  PR_LOG(POP3LOGMODULE, PR_LOG_ALWAYS,("RECV: %s", line));

  if(pauseForMoreData || !line)
  {
    m_pop3ConData->pause_for_read = PR_TRUE; /* pause */
    PR_Free(line);
    return(line_length);
  }

  if(*line == '+')
  {
    m_pop3ConData->command_succeeded = PR_TRUE;
    if(PL_strlen(line) > 4)
      m_commandResponse = line + 4;
    else
      m_commandResponse = line;

    if (m_useSecAuth)
    {
        nsresult rv;
        nsCOMPtr<nsISignatureVerifier> verifier = do_GetService(SIGNATURE_VERIFIER_CONTRACTID, &rv);
        // this checks if psm is installed...
        if (NS_SUCCEEDED(rv))
        {
          if (NS_SUCCEEDED(GetApopTimestamp()))
            SetCapFlag(POP3_HAS_AUTH_APOP);
        }
    }
    else
      ClearCapFlag(POP3_HAS_AUTH_APOP);

    m_pop3Server->SetPop3CapabilityFlags(m_pop3ConData->capability_flags);

    m_pop3ConData->next_state = POP3_PROCESS_AUTH;
    m_pop3ConData->pause_for_read = PR_FALSE; /* don't pause */
  }

  PR_Free(line);
  return(1);  /* everything ok */
}

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 3020 of file nsPop3Protocol.cpp.

Here is the call graph for this function:

Here is the caller graph for this function:


Member Data Documentation

Definition at line 320 of file nsPop3Protocol.h.

Definition at line 334 of file nsPop3Protocol.h.

Definition at line 325 of file nsPop3Protocol.h.

Definition at line 327 of file nsPop3Protocol.h.

nsMsgLineStreamBuffer* nsPop3Protocol::m_lineStreamBuffer [private]

Definition at line 350 of file nsPop3Protocol.h.

Definition at line 369 of file nsPop3Protocol.h.

Definition at line 347 of file nsPop3Protocol.h.

Definition at line 368 of file nsPop3Protocol.h.

Definition at line 355 of file nsPop3Protocol.h.

Definition at line 360 of file nsPop3Protocol.h.

Definition at line 351 of file nsPop3Protocol.h.

Definition at line 348 of file nsPop3Protocol.h.

Definition at line 324 of file nsPop3Protocol.h.

Definition at line 358 of file nsPop3Protocol.h.

Definition at line 326 of file nsPop3Protocol.h.

Definition at line 357 of file nsPop3Protocol.h.

Definition at line 339 of file nsPop3Protocol.h.

Definition at line 336 of file nsPop3Protocol.h.

Definition at line 335 of file nsPop3Protocol.h.

Definition at line 346 of file nsPop3Protocol.h.

Definition at line 323 of file nsPop3Protocol.h.

Definition at line 359 of file nsPop3Protocol.h.

Definition at line 321 of file nsPop3Protocol.h.


The documentation for this class was generated from the following files: