Back to index

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

#include <nsMsgMdnGenerator.h>

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

List of all members.

Public Member Functions

NS_DECL_ISUPPORTS
NS_DECL_NSIMSGMDNGENERATOR
NS_DECL_NSIURLLISTENER 
nsMsgMdnGenerator ()
virtual ~nsMsgMdnGenerator ()
void process (in EDisposeType eType, in nsIMsgWindow aWindow, in nsIMsgFolder folder, in nsMsgKey key, in nsIMimeHeaders headers, in boolean autoAction)
void OnStartRunningUrl (in nsIURI url)
void OnStopRunningUrl (in nsIURI url, in nsresult aExitCode)

Public Attributes

const EDisposeType eDisplayed = 0
const EDisposeType eDispatched = 1
const EDisposeType eProcessed = 2
const EDisposeType eDeleted = 3
const EDisposeType eDenied = 4
const EDisposeType eFailed = 5
const ReceiptHdrType eDntType = 0
const ReceiptHdrType eRrtType = 1
const ReceiptHdrType eDntRrtType = 2
const MDNIncorporateType eIncorporateInbox = 0
const MDNIncorporateType eIncorporateSent = 1

Private Member Functions

PRBool ProcessSendMode ()
PRBool ValidateReturnPath ()
PRBool NotInToOrCc ()
PRBool MailAddrMatch (const char *addr1, const char *addr2)
nsresult StoreMDNSentFlag (nsIMsgFolder *folder, nsMsgKey key)
nsresult CreateMdnMsg ()
nsresult CreateFirstPart ()
nsresult CreateSecondPart ()
nsresult CreateThirdPart ()
nsresult SendMdnMsg ()
nsresult GetStringFromName (const PRUnichar *aName, PRUnichar **aResultString)
nsresult FormatStringFromName (const PRUnichar *aName, const PRUnichar *aString, PRUnichar **aResultString)
nsresult InitAndProcess ()
nsresult OutputAllHeaders ()
nsresult WriteString (const char *str)

Private Attributes

EDisposeType m_disposeType
nsCOMPtr< nsIMsgWindowm_window
nsCOMPtr< nsIOutputStreamm_outputStream
nsCOMPtr< nsIFileSpecm_fileSpec
nsCOMPtr< nsIMsgIdentitym_identity
nsXPIDLCString m_charset
nsXPIDLCString m_email
nsXPIDLCString m_mimeSeparator
nsXPIDLCString m_messageId
nsCOMPtr< nsIMsgFolderm_folder
nsCOMPtr< nsIMsgIncomingServerm_server
nsCOMPtr< nsIMimeHeadersm_headers
nsXPIDLCString m_dntRrt
PRInt32 m_notInToCcOp
PRInt32 m_outsideDomainOp
PRInt32 m_otherOp
PRPackedBool m_reallySendMdn
PRPackedBool m_autoSend
PRPackedBool m_autoAction
PRPackedBool m_mdnEnabled

Detailed Description

Definition at line 60 of file nsMsgMdnGenerator.h.


Constructor & Destructor Documentation

Definition at line 125 of file nsMsgMdnGenerator.cpp.

{
}

Member Function Documentation

Definition at line 451 of file nsMsgMdnGenerator.cpp.

{
    DEBUG_MDN("nsMsgMdnGenerator::CreateFirstPart");
    char *convbuf = nsnull, *tmpBuffer = nsnull;
    char *parm = nsnull;
    nsXPIDLString firstPart1;
    nsXPIDLString firstPart2;
    nsresult rv = NS_OK;
    nsCOMPtr <nsIMsgCompUtils> compUtils;
    
    if (!m_mimeSeparator)
    {
      compUtils = do_GetService(NS_MSGCOMPUTILS_CONTRACTID, &rv);
      NS_ENSURE_SUCCESS(rv, rv);
      rv = compUtils->MimeMakeSeparator("mdn", getter_Copies(m_mimeSeparator));
      NS_ENSURE_SUCCESS(rv, rv);
    }
    if (!m_mimeSeparator)
        return NS_ERROR_OUT_OF_MEMORY;

    tmpBuffer = (char *) PR_CALLOC(256);

    if (!tmpBuffer)
        return NS_ERROR_OUT_OF_MEMORY;

    PRExplodedTime now;
    PR_ExplodeTime(PR_Now(), PR_LocalTimeParameters, &now);
    
    int gmtoffset = (now.tm_params.tp_gmt_offset + now.tm_params.tp_dst_offset)
        / 60;
  /* Use PR_FormatTimeUSEnglish() to format the date in US English format,
     then figure out what our local GMT offset is, and append it (since
     PR_FormatTimeUSEnglish() can't do that.) Generate four digit years as
     per RFC 1123 (superceding RFC 822.)
  */
    PR_FormatTimeUSEnglish(tmpBuffer, 100,
                           "Date: %a, %d %b %Y %H:%M:%S ",
                           &now);

    PR_snprintf(tmpBuffer + strlen(tmpBuffer), 100,
                "%c%02d%02d" CRLF,
                (gmtoffset >= 0 ? '+' : '-'),
                ((gmtoffset >= 0 ? gmtoffset : -gmtoffset) / 60),
                ((gmtoffset >= 0 ? gmtoffset : -gmtoffset) % 60));

    rv = WriteString(tmpBuffer);
    PR_Free(tmpBuffer);
    if (NS_FAILED(rv)) 
        return rv;
    
    PRBool conformToStandard = PR_FALSE;
    if (compUtils)
      compUtils->GetMsgMimeConformToStandard(&conformToStandard);

    convbuf = nsMsgI18NEncodeMimePartIIStr(
        m_email.get(), PR_TRUE, m_charset.get(), 0,
        conformToStandard);
    parm = PR_smprintf("From: %s" CRLF, convbuf ? convbuf : m_email.get());

    rv = FormatStringFromName(NS_LITERAL_STRING("MsgMdnMsgSentTo").get(), NS_ConvertASCIItoUCS2(m_email).get(),
                            getter_Copies(firstPart1));
    if (NS_FAILED(rv)) 
        return rv;

    PUSH_N_FREE_STRING (parm);
    
    PR_Free(convbuf);
    
    if (compUtils)
    {
      nsXPIDLCString msgId;
      rv = compUtils->MsgGenerateMessageId(m_identity, getter_Copies(msgId));
      tmpBuffer = PR_smprintf("Message-ID: %s" CRLF, msgId.get());
      PUSH_N_FREE_STRING(tmpBuffer);
    }

    nsXPIDLString receipt_string;
    switch (m_disposeType)
    {
    case nsIMsgMdnGenerator::eDisplayed:
        rv = GetStringFromName(
            NS_LITERAL_STRING("MdnDisplayedReceipt").get(),
            getter_Copies(receipt_string));
        break;
    case nsIMsgMdnGenerator::eDispatched:
        rv = GetStringFromName(
            NS_LITERAL_STRING("MdnDispatchedReceipt").get(),
            getter_Copies(receipt_string));
        break;
    case nsIMsgMdnGenerator::eProcessed:
        rv = GetStringFromName(
            NS_LITERAL_STRING("MdnProcessedReceipt").get(),
            getter_Copies(receipt_string));
        break;
    case nsIMsgMdnGenerator::eDeleted:
        rv = GetStringFromName(
            NS_LITERAL_STRING("MdnDeletedReceipt").get(),
            getter_Copies(receipt_string));
        break;
    case nsIMsgMdnGenerator::eDenied:
        rv = GetStringFromName(
            NS_LITERAL_STRING("MdnDeniedReceipt").get(),
            getter_Copies(receipt_string));
        break;
    case nsIMsgMdnGenerator::eFailed:
        rv = GetStringFromName(
            NS_LITERAL_STRING("MdnFailedReceipt").get(),
            getter_Copies(receipt_string));
        break;
    default:
        rv = NS_ERROR_INVALID_ARG;
        break;
    }

    if (NS_FAILED(rv)) 
        return rv;
    
    receipt_string.Append(NS_LITERAL_STRING(" - "));
        
    char * encodedReceiptString = nsMsgI18NEncodeMimePartIIStr(NS_ConvertUCS2toUTF8(receipt_string).get(), PR_FALSE, 
                                                               "UTF-8", 0, conformToStandard);
   
    nsXPIDLCString subject;
    m_headers->ExtractHeader(HEADER_SUBJECT, PR_FALSE, getter_Copies(subject));
    convbuf = nsMsgI18NEncodeMimePartIIStr(subject.Length() ? subject.get() : "[no subject]", 
                                           PR_FALSE, m_charset.get(), 0, conformToStandard);
    tmpBuffer = PR_smprintf("Subject: %s%s" CRLF, 
                             encodedReceiptString,
                            (convbuf ? convbuf : (subject.Length() ? subject.get() : 
                              "[no subject]")));

    PUSH_N_FREE_STRING(tmpBuffer);
    PR_Free(convbuf);
    PR_Free(encodedReceiptString);

    convbuf = nsMsgI18NEncodeMimePartIIStr(m_dntRrt, PR_TRUE, m_charset.get(), 0, conformToStandard);
    tmpBuffer = PR_smprintf("To: %s" CRLF, convbuf ? convbuf :
                            m_dntRrt.get());
    PUSH_N_FREE_STRING(tmpBuffer);

    PR_Free(convbuf);

  // *** This is not in the spec. I am adding this so we could do
  // threading
    m_headers->ExtractHeader(HEADER_MESSAGE_ID, PR_FALSE,
                             getter_Copies(m_messageId));
    
    if (!m_messageId.IsEmpty())
    {
      if (*m_messageId.get() == '<')
          tmpBuffer = PR_smprintf("References: %s" CRLF, m_messageId.get());
      else
          tmpBuffer = PR_smprintf("References: <%s>" CRLF, m_messageId.get());
      PUSH_N_FREE_STRING(tmpBuffer);
    }
    tmpBuffer = PR_smprintf("%s" CRLF, "MIME-Version: 1.0");
    PUSH_N_FREE_STRING(tmpBuffer);

    tmpBuffer = PR_smprintf("Content-Type: multipart/report; \
report-type=disposition-notification;\r\n\tboundary=\"%s\"" CRLF CRLF,
                            m_mimeSeparator.get()); 
    PUSH_N_FREE_STRING(tmpBuffer);
    
    tmpBuffer = PR_smprintf("--%s" CRLF, m_mimeSeparator.get());
    PUSH_N_FREE_STRING(tmpBuffer);

    tmpBuffer = PR_smprintf("Content-Type: text/plain; charset=UTF-8" CRLF);
    PUSH_N_FREE_STRING(tmpBuffer);

    tmpBuffer = PR_smprintf("Content-Transfer-Encoding: %s" CRLF CRLF,
                            ENCODING_8BIT);
    PUSH_N_FREE_STRING(tmpBuffer);
  
    if (!firstPart1.IsEmpty())
    {
        tmpBuffer = PR_smprintf("%s" CRLF CRLF, NS_ConvertUCS2toUTF8(firstPart1).get());
        PUSH_N_FREE_STRING(tmpBuffer);
    }

    switch (m_disposeType)
    {
    case nsIMsgMdnGenerator::eDisplayed:
        rv = GetStringFromName(
            NS_LITERAL_STRING("MsgMdnDisplayed").get(),
            getter_Copies(firstPart2));
        break;
    case nsIMsgMdnGenerator::eDispatched:
        rv = GetStringFromName(
            NS_LITERAL_STRING("MsgMdnDisptched").get(),
            getter_Copies(firstPart2));
        break;
    case nsIMsgMdnGenerator::eProcessed:
        rv = GetStringFromName(
            NS_LITERAL_STRING("MsgMdnProcessed").get(),
            getter_Copies(firstPart2));
        break;
    case nsIMsgMdnGenerator::eDeleted:
        rv = GetStringFromName(
            NS_LITERAL_STRING("MsgMdnDeleted").get(),
            getter_Copies(firstPart2));
        break;
    case nsIMsgMdnGenerator::eDenied:
        rv = GetStringFromName(
            NS_LITERAL_STRING("MsgMdnDenied").get(),
            getter_Copies(firstPart2));
        break;
    case nsIMsgMdnGenerator::eFailed:
        rv = GetStringFromName(
            NS_LITERAL_STRING("MsgMdnFailed").get(),
            getter_Copies(firstPart2));
        break;
    default:
        rv = NS_ERROR_INVALID_ARG;
        break;
    }
    
    if (NS_FAILED(rv)) 
        return rv;
    
    if (!firstPart2.IsEmpty())
    {
        tmpBuffer = 
            PR_smprintf("%s" CRLF CRLF, 
                        NS_ConvertUCS2toUTF8(firstPart2).get()); 
        PUSH_N_FREE_STRING(tmpBuffer);
    }
    
    return rv;
}

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 386 of file nsMsgMdnGenerator.cpp.

{
    DEBUG_MDN("nsMsgMdnGenerator::CreateMdnMsg");
    nsresult rv;
    if (!m_autoSend)
    {
        nsCOMPtr<nsIPrompt> dialog;
        rv = m_window->GetPromptDialog(getter_AddRefs(dialog));
        if (NS_SUCCEEDED(rv))
        {
            nsXPIDLString wishToSend;
            rv = GetStringFromName(
                NS_LITERAL_STRING("MsgMdnWishToSend").get(),
                getter_Copies(wishToSend));
            if (NS_SUCCEEDED(rv))
            {
                PRBool bVal = PR_FALSE;
                rv = dialog->Confirm(nsnull, wishToSend, &bVal);
                if (NS_SUCCEEDED(rv))
                    m_reallySendMdn = bVal;
            }
        }
    }
    if (!m_reallySendMdn)
        return NS_OK;

    nsSpecialSystemDirectory
        tmpFile(nsSpecialSystemDirectory::OS_TemporaryDirectory); 
    tmpFile += "mdnmsg";
    tmpFile.MakeUnique();

    rv = NS_NewFileSpecWithSpec(tmpFile, getter_AddRefs(m_fileSpec));

    NS_ASSERTION(NS_SUCCEEDED(rv),"creating mdn: failed to create");
    if (NS_FAILED(rv)) 
        return NS_OK;

    rv = m_fileSpec->GetOutputStream(getter_AddRefs(m_outputStream));
    NS_ASSERTION(NS_SUCCEEDED(rv),"creating mdn: failed to output stream");
    if (NS_FAILED(rv)) 
        return NS_OK;

    rv = CreateFirstPart();
    if (NS_SUCCEEDED(rv))
    {
        rv = CreateSecondPart();
        if (NS_SUCCEEDED(rv))
            rv = CreateThirdPart();
    }

    if (m_outputStream)
    {
        m_outputStream->Flush();
        m_outputStream->Close();
    }
    if (m_fileSpec)
        m_fileSpec->CloseStream();
    if (NS_FAILED(rv))
        m_fileSpec->Delete(PR_FALSE);
    else
        rv = SendMdnMsg();

    return NS_OK;
}

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 681 of file nsMsgMdnGenerator.cpp.

{
    DEBUG_MDN("nsMsgMdnGenerator::CreateSecondPart");
    char *tmpBuffer = nsnull;
    char *convbuf = nsnull;
    nsresult rv = NS_OK;
    nsCOMPtr <nsIMsgCompUtils> compUtils;
    PRBool conformToStandard = PR_FALSE;
    
    tmpBuffer = PR_smprintf("--%s" CRLF, m_mimeSeparator.get());
    PUSH_N_FREE_STRING(tmpBuffer);
    
    tmpBuffer = PR_smprintf("%s" CRLF, "Content-Type: message/disposition-notification; name=\042MDNPart2.txt\042");
    PUSH_N_FREE_STRING(tmpBuffer);
    
    tmpBuffer = PR_smprintf("%s" CRLF, "Content-Disposition: inline");
    PUSH_N_FREE_STRING(tmpBuffer);
    
    tmpBuffer = PR_smprintf("Content-Transfer-Encoding: %s" CRLF CRLF,
                            ENCODING_7BIT);
    PUSH_N_FREE_STRING(tmpBuffer);
    
    nsCOMPtr<nsIHttpProtocolHandler> pHTTPHandler = 
        do_GetService(NS_NETWORK_PROTOCOL_CONTRACTID_PREFIX "http", &rv); 
    if (NS_SUCCEEDED(rv) && pHTTPHandler)
    {
        nsCAutoString userAgentString;
        pHTTPHandler->GetUserAgent(userAgentString);

        if (!userAgentString.IsEmpty())
        {
            tmpBuffer = PR_smprintf("Reporting-UA: %s" CRLF,
                                    userAgentString.get());
            PUSH_N_FREE_STRING(tmpBuffer);
        }
    }

    nsXPIDLCString originalRecipient;
    m_headers->ExtractHeader(HEADER_ORIGINAL_RECIPIENT, PR_FALSE,
                             getter_Copies(originalRecipient));
    
    if (originalRecipient && *originalRecipient)
    {
        tmpBuffer = PR_smprintf("Original-Recipient: %s" CRLF,
                                originalRecipient.get());
        PUSH_N_FREE_STRING(tmpBuffer);
    }

    compUtils = do_GetService(NS_MSGCOMPUTILS_CONTRACTID, &rv);
    if (compUtils)
      compUtils->GetMsgMimeConformToStandard(&conformToStandard);

    convbuf = nsMsgI18NEncodeMimePartIIStr(
        m_email.get(), PR_TRUE, m_charset.get(), 0,
        conformToStandard);
    tmpBuffer = PR_smprintf("Final-Recipient: rfc822;%s" CRLF, convbuf ?
                            convbuf : m_email.get()); 
    PUSH_N_FREE_STRING(tmpBuffer);

    PR_Free (convbuf);

    if (!m_messageId.IsEmpty())
    {
      if (*m_messageId.get() == '<')
          tmpBuffer = PR_smprintf("Original-Message-ID: %s" CRLF, m_messageId.get());
      else
          tmpBuffer = PR_smprintf("Original-Message-ID: <%s>" CRLF, m_messageId.get());
      PUSH_N_FREE_STRING(tmpBuffer);
    }
    
    tmpBuffer = PR_smprintf("Disposition: %s/%s; %s" CRLF CRLF,
                            (m_autoAction ? "automatic-action" :
                             "manual-action"),
                            (m_autoSend ? "MDN-sent-automatically" :
                             "MDN-sent-manually"), 
                            DispositionTypes[(int) m_disposeType]);
    PUSH_N_FREE_STRING(tmpBuffer);
  
    return rv;
}

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 762 of file nsMsgMdnGenerator.cpp.

{
    DEBUG_MDN("nsMsgMdnGenerator::CreateThirdPart");
    char *tmpBuffer = nsnull;
    nsresult rv = NS_OK;

    tmpBuffer = PR_smprintf("--%s" CRLF, m_mimeSeparator.get());
    PUSH_N_FREE_STRING(tmpBuffer);

    tmpBuffer = PR_smprintf("%s" CRLF, "Content-Type: text/rfc822-headers; name=\042MDNPart3.txt\042");
    PUSH_N_FREE_STRING(tmpBuffer);

    tmpBuffer = PR_smprintf("%s" CRLF, "Content-Transfer-Encoding: 7bit");
    PUSH_N_FREE_STRING(tmpBuffer);

    tmpBuffer = PR_smprintf("%s" CRLF CRLF, "Content-Disposition: inline");
    PUSH_N_FREE_STRING(tmpBuffer);
   
    rv = OutputAllHeaders();

    if (NS_FAILED(rv)) 
        return rv;

    rv = WriteString(CRLF);
    if (NS_FAILED(rv)) 
        return rv;

    tmpBuffer = PR_smprintf("--%s--" CRLF, m_mimeSeparator.get());
    PUSH_N_FREE_STRING(tmpBuffer);

    return rv;
}

Here is the call graph for this function:

Here is the caller graph for this function:

nsresult nsMsgMdnGenerator::FormatStringFromName ( const PRUnichar aName,
const PRUnichar aString,
PRUnichar **  aResultString 
) [private]

Definition at line 129 of file nsMsgMdnGenerator.cpp.

{
    DEBUG_MDN("nsMsgMdnGenerator::FormatStringFromName");
    nsresult rv;

    nsCOMPtr<nsIStringBundleService>
        bundleService(do_GetService(NS_STRINGBUNDLE_CONTRACTID, &rv));
    NS_ENSURE_SUCCESS(rv,rv);

    nsCOMPtr <nsIStringBundle> bundle;
    rv = bundleService->CreateBundle(MDN_STRINGBUNDLE_URL, 
                                     getter_AddRefs(bundle));
    NS_ENSURE_SUCCESS(rv,rv);

    const PRUnichar *formatStrings[1] = { aString };
    rv = bundle->FormatStringFromName(aName,
                    formatStrings, 1, aResultString);
    NS_ENSURE_SUCCESS(rv,rv);
    return rv;
}

Here is the call graph for this function:

Here is the caller graph for this function:

nsresult nsMsgMdnGenerator::GetStringFromName ( const PRUnichar aName,
PRUnichar **  aResultString 
) [private]

Definition at line 152 of file nsMsgMdnGenerator.cpp.

{
    DEBUG_MDN("nsMsgMdnGenerator::GetStringFromName");
    nsresult rv;

    nsCOMPtr<nsIStringBundleService>
        bundleService(do_GetService(NS_STRINGBUNDLE_CONTRACTID, &rv));
    NS_ENSURE_SUCCESS(rv,rv);

    nsCOMPtr <nsIStringBundle> bundle;
    rv = bundleService->CreateBundle(MDN_STRINGBUNDLE_URL, 
                                     getter_AddRefs(bundle));
    NS_ENSURE_SUCCESS(rv,rv);

    rv = bundle->GetStringFromName(aName, aResultString);
    NS_ENSURE_SUCCESS(rv,rv);
    return rv;
}

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 903 of file nsMsgMdnGenerator.cpp.

{
    DEBUG_MDN("nsMsgMdnGenerator::InitAndProcess");
    nsresult rv = m_folder->GetServer(getter_AddRefs(m_server));
    nsCOMPtr<nsIMsgAccountManager> accountManager = 
        do_GetService(NS_MSGACCOUNTMANAGER_CONTRACTID, &rv);
    if (accountManager && m_server)
    {
        if (!m_identity)
        {
          // check if this is a message delivered to the global inbox,
          // in which case we find the originating account's identity.
          nsXPIDLCString accountKey;
          m_headers->ExtractHeader(HEADER_X_MOZILLA_ACCOUNT_KEY, PR_FALSE,
                               getter_Copies(accountKey));
          nsCOMPtr <nsIMsgAccount> account;
          if (!accountKey.IsEmpty())
            accountManager->GetAccount(accountKey, getter_AddRefs(account));
          if (account)
            account->GetIncomingServer(getter_AddRefs(m_server));

          if (m_server)
          {
            // Find the correct identity based on the "To:" and "Cc:" header
            nsXPIDLCString mailTo;
            nsXPIDLCString mailCC;
            m_headers->ExtractHeader(HEADER_TO, PR_TRUE, getter_Copies(mailTo));
            m_headers->ExtractHeader(HEADER_CC, PR_TRUE, getter_Copies(mailCC));
            nsCOMPtr<nsISupportsArray> servIdentities;
            accountManager->GetIdentitiesForServer(m_server, getter_AddRefs(servIdentities));
            if (servIdentities)
            {
              nsCOMPtr<nsIMsgIdentity> ident;
              nsXPIDLCString identEmail;
              PRUint32 count = 0;
              servIdentities->Count(&count);
              // First check in the "To:" header
              for (PRUint32 i = 0; i < count; i++)
              {
                rv = servIdentities->QueryElementAt(i, NS_GET_IID(nsIMsgIdentity),getter_AddRefs(ident));
                if (NS_FAILED(rv))
                  continue;
                ident->GetEmail(getter_Copies(identEmail));
                if (!mailTo.IsEmpty() && !identEmail.IsEmpty() && mailTo.Find(identEmail, PR_TRUE) != kNotFound)
                {
                  m_identity = ident;
                  break;
                }
              }
              // If no match, check the "Cc:" header
              if (!m_identity)
              {
                for (PRUint32 i = 0; i < count; i++)
                {
                  rv = servIdentities->QueryElementAt(i, NS_GET_IID(nsIMsgIdentity),getter_AddRefs(ident));
                  if (NS_FAILED(rv))
                    continue;
                  ident->GetEmail(getter_Copies(identEmail));
                  if (!mailCC.IsEmpty() && !identEmail.IsEmpty() && mailCC.Find(identEmail, PR_TRUE) != kNotFound)
                  {
                    m_identity = ident;
                    break;
                  }
                }
              }
            }

            // If no match again, use the first identity
            if (!m_identity)
              rv = accountManager->GetFirstIdentityForServer(m_server, getter_AddRefs(m_identity));
          }
        }
        NS_ENSURE_SUCCESS(rv,rv);

        if (m_identity)
        {
            PRBool useCustomPrefs = PR_FALSE;
            m_identity->GetBoolAttribute("use_custom_prefs", &useCustomPrefs);
            if (useCustomPrefs)
            {
                PRBool bVal = PR_FALSE;
                m_server->GetBoolValue("mdn_report_enabled", &bVal);
                m_mdnEnabled = bVal;
                m_server->GetIntValue("mdn_not_in_to_cc", &m_notInToCcOp);
                m_server->GetIntValue("mdn_outside_domain",
                                      &m_outsideDomainOp);
                m_server->GetIntValue("mdn_other", &m_otherOp);
            }
            else
            {
                PRBool bVal = PR_FALSE;

                nsCOMPtr<nsIPrefBranch> prefBranch(do_GetService(NS_PREFSERVICE_CONTRACTID, &rv));
                if (NS_FAILED(rv))
                    return rv;

                if(prefBranch)
                {
                    prefBranch->GetBoolPref("mail.mdn.report.enabled",
                                           &bVal);
                    m_mdnEnabled = bVal;
                    prefBranch->GetIntPref("mail.mdn.report.not_in_to_cc",
                                           &m_notInToCcOp);
                    prefBranch->GetIntPref("mail.mdn.report.outside_domain",
                                           &m_outsideDomainOp);
                    prefBranch->GetIntPref("mail.mdn.report.other",
                                           &m_otherOp);
                }
            }
        }
    }

    rv = m_folder->GetCharset(getter_Copies(m_charset));

    if (m_mdnEnabled)
    {
        m_headers->ExtractHeader(HEADER_DISPOSITION_NOTIFICATION_TO, PR_FALSE,
                                 getter_Copies(m_dntRrt));
        if (!m_dntRrt)
            m_headers->ExtractHeader(HEADER_RETURN_RECEIPT_TO, PR_FALSE,
                                     getter_Copies(m_dntRrt));
        if (m_dntRrt && ProcessSendMode() && ValidateReturnPath())
            rv = CreateMdnMsg();
    }
    return NS_OK;
}

Here is the call graph for this function:

PRBool nsMsgMdnGenerator::MailAddrMatch ( const char *  addr1,
const char *  addr2 
) [private]

Definition at line 303 of file nsMsgMdnGenerator.cpp.

{
    // Comparing two email addresses returns true if matched; local/account
    // part comparison is case sensitive; domain part comparison is case
    // insensitive 
    DEBUG_MDN("nsMsgMdnGenerator::MailAddrMatch");
    PRBool isMatched = PR_TRUE;
    const char *atSign1 = nsnull, *atSign2 = nsnull;
    const char *lt = nsnull, *local1 = nsnull, *local2 = nsnull;
    const char *end1 = nsnull, *end2 = nsnull;

    if (!addr1 || !addr2)
        return PR_FALSE;
    
    lt = strchr(addr1, '<');
    local1 = !lt ? addr1 : lt+1;
    lt = strchr(addr2, '<');
    local2 = !lt ? addr2 : lt+1;
    end1 = strchr(local1, '>');
    if (!end1)
        end1 = addr1 + strlen(addr1);
    end2 = strchr(local2, '>');
    if (!end2)
        end2 = addr2 + strlen(addr2);
    atSign1 = strchr(local1, '@');
    atSign2 = strchr(local2, '@');
    if (!atSign1 || !atSign2 // ill formed addr spec
        || (atSign1 - local1) != (atSign2 - local2))
        isMatched = PR_FALSE;
    else if (strncmp(local1, local2, (atSign1-local1))) // case sensitive
        // compare for local part
        isMatched = PR_FALSE;
    else if ((end1 - atSign1) != (end2 - atSign2) ||
             PL_strncasecmp(atSign1, atSign2, (end1-atSign1))) // case
        // insensitive compare for domain part
        isMatched = PR_FALSE;
    return isMatched;
}

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 342 of file nsMsgMdnGenerator.cpp.

{
    DEBUG_MDN("nsMsgMdnGenerator::NotInToOrCc");
    nsXPIDLCString reply_to;
    nsXPIDLCString to;
    nsXPIDLCString cc;

    m_identity->GetReplyTo(getter_Copies(reply_to));
    m_headers->ExtractHeader(HEADER_TO, PR_TRUE, getter_Copies(to));
    m_headers->ExtractHeader(HEADER_CC, PR_TRUE, getter_Copies(cc));
  
  // start with a simple check
  if ((to.Length() && PL_strcasestr(to.get(), m_email.get())) || 
      (cc.Length() && PL_strcasestr(cc.get(), m_email.get()))) {
      return PR_FALSE;
  }

  if ((reply_to.Length() && to.Length() && PL_strcasestr(to.get(), reply_to.get())) ||
      (reply_to.Length() && cc.Length() && PL_strcasestr(cc.get(), reply_to.get()))) {
      return PR_FALSE;
  }
  return PR_TRUE;
}

Here is the call graph for this function:

Here is the caller graph for this function:

Here is the caller graph for this function:

void nsIUrlListener::OnStopRunningUrl ( in nsIURI  url,
in nsresult  aExitCode 
) [inherited]

Here is the caller graph for this function:

Definition at line 796 of file nsMsgMdnGenerator.cpp.

{ 
    DEBUG_MDN("nsMsgMdnGenerator::OutputAllHeaders");
    nsXPIDLCString all_headers;
    PRInt32 all_headers_size = 0;
    nsresult rv = NS_OK;
    
    rv = m_headers->GetAllHeaders(getter_Copies(all_headers));
    if (NS_FAILED(rv)) 
        return rv;
    all_headers_size = all_headers.Length();
    char *buf = (char *) all_headers.get(), 
        *buf_end = (char *) all_headers.get()+all_headers_size;
    char *start = buf, *end = buf;
    PRInt32 count = 0;
  
    while (buf < buf_end)
    {
        switch (*buf)
        {
        case 0:
            if (*(buf+1) == nsCRT::LF)
            {
                // *buf = nsCRT::CR;
                end = buf;
            }
            else if (*(buf+1) == 0)
            {
                // the case of message id
                *buf = '>';
            }
            break;
        case nsCRT::CR:
            end = buf;
            *buf = 0;
            break;
        case nsCRT::LF:
            if (buf > start && *(buf-1) == 0)
            {
                start = buf + 1;
                end = start;
            }
            else
            {
                end = buf;
            }
            *buf = 0;
            break;
        default:
            break;
        }
        buf++;
    
        if (end > start && *end == 0)
        {
            // strip out private X-Mozilla-Status header & X-Mozilla-Draft-Info && envelope header
            if (!PL_strncasecmp(start, X_MOZILLA_STATUS, X_MOZILLA_STATUS_LEN)
                || !PL_strncasecmp(start, X_MOZILLA_DRAFT_INFO, X_MOZILLA_DRAFT_INFO_LEN)
                || !PL_strncasecmp(start, "From ", 5))
            {
                while ( end < buf_end && 
                        (*end == nsCRT::LF || *end == nsCRT::CR || *end == 0))
                    end++;
                start = end;
            }
            else
            {
                NS_ASSERTION (*end == 0, "content of end should be null");
                rv = WriteString(start);
                if (NS_FAILED(rv)) 
                    return rv;
                rv = WriteString(CRLF);
                while ( end < buf_end && 
                        (*end == nsCRT::LF || *end == nsCRT::CR || *end == 0))
                    end++;
                start = end;
            }
            buf = start;
        }
    }
    return count;
}

Here is the call graph for this function:

Here is the caller graph for this function:

void nsIMsgMdnGenerator::process ( in EDisposeType  eType,
in nsIMsgWindow  aWindow,
in nsIMsgFolder  folder,
in nsMsgKey  key,
in nsIMimeHeaders  headers,
in boolean  autoAction 
) [inherited]

Definition at line 189 of file nsMsgMdnGenerator.cpp.

{
    DEBUG_MDN("nsMsgMdnGenerator::ProcessSendMode");
    PRInt32 miscState = 0;
    
    if (m_identity)
    {
        m_identity->GetEmail(getter_Copies(m_email));
        if (!m_email)
            return m_reallySendMdn;

        const char *accountDomain = strchr(m_email.get(), '@');
        if (!accountDomain)
            return m_reallySendMdn;

        if (MailAddrMatch(m_email.get(), m_dntRrt.get())) // return address is self, don't send
          return PR_FALSE;

        // *** fix me see Bug 132504 for more information
        // *** what if the message has been filtered to different account
        if (!PL_strcasestr(m_dntRrt, accountDomain))
            miscState |= MDN_OUTSIDE_DOMAIN;
        if (NotInToOrCc())
            miscState |= MDN_NOT_IN_TO_CC;
        m_reallySendMdn = PR_TRUE;
        // *********
        // How are we gona deal with the auto forwarding issues? Some server
        // didn't bother to add addition header or modify existing header to
        // thev message when forwarding. They simply copy the exact same
        // message to another user's mailbox. Some change To: to
        // Apparently-To: 
        // Unfortunately, there is nothing we can do. It's out of our control.
        // *********
        // starting from lowest denominator to highest
        if (!miscState)
        {   // under normal situation: recipent is in to and cc list,
            // and the sender is from the same domain
            switch (m_otherOp) 
            {
            default:
            case eNeverSendOp:
                m_reallySendMdn = PR_FALSE;
                break;
            case eAutoSendOp:
                m_autoSend = PR_TRUE;
                break;
            case eAskMeOp:
                m_autoSend = PR_FALSE;
                break;
            case eDeniedOp:
                m_autoSend = PR_TRUE;
                m_disposeType = eDenied;
                break;
            }
        }
        else if (miscState == (MDN_OUTSIDE_DOMAIN | MDN_NOT_IN_TO_CC))
        {
            if (m_outsideDomainOp != m_notInToCcOp)
            {
                m_autoSend = PR_FALSE; // ambiguous; always ask user
            }
            else
            {
                switch (m_outsideDomainOp) 
                {
                default:
                case eNeverSendOp:
                    m_reallySendMdn = PR_FALSE;
                    break;
                case eAutoSendOp:
                    m_autoSend = PR_TRUE;
                    break;
                case eAskMeOp:
                    m_autoSend = PR_FALSE;
                    break;
                }
            }
        }
        else if (miscState & MDN_OUTSIDE_DOMAIN)
        {
            switch (m_outsideDomainOp) 
            {
            default:
            case eNeverSendOp:
                m_reallySendMdn = PR_FALSE;
                break;
            case eAutoSendOp:
                m_autoSend = PR_TRUE;
                break;
            case eAskMeOp:
                m_autoSend = PR_FALSE;
                break;
            }
        }
        else if (miscState & MDN_NOT_IN_TO_CC)
        {
            switch (m_notInToCcOp) 
            {
            default:
            case eNeverSendOp:
                m_reallySendMdn = PR_FALSE;
                break;
            case eAutoSendOp:
                m_autoSend = PR_TRUE;
                break;
            case eAskMeOp:
                m_autoSend = PR_FALSE;
                break;
            }
        }
    }
    return m_reallySendMdn;
}

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 879 of file nsMsgMdnGenerator.cpp.

{
    DEBUG_MDN("nsMsgMdnGenerator::SendMdnMsg");
    nsresult rv;
    nsCOMPtr<nsISmtpService> smtpService = do_GetService(NS_SMTPSERVICE_CONTRACTID, &rv);
    NS_ENSURE_SUCCESS(rv,rv);

    nsCOMPtr<nsIRequest> aRequest;
    smtpService->SendMailMessage(m_fileSpec, m_dntRrt, m_identity,
                                     nsnull, this, nsnull, nsnull, nsnull,
                                     getter_AddRefs(aRequest));
    
    return NS_OK;
}

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 172 of file nsMsgMdnGenerator.cpp.

{
    DEBUG_MDN("nsMsgMdnGenerator::StoreMDNSentFlag");
    
    // Store the $MDNSent flag if the folder is an Imap Mail Folder
    // otherwise, do nothing.
    nsCOMPtr<nsIMsgImapMailFolder> imapFolder = do_QueryInterface(folder);
    if (!imapFolder)
      return NS_OK;

    nsMsgKeyArray keyArray;
    keyArray.Add(key);
    return imapFolder->StoreImapFlags(kImapMsgMDNSentFlag, PR_TRUE,
                               keyArray.GetArray(), keyArray.GetSize(), nsnull);
}

Here is the call graph for this function:

Definition at line 366 of file nsMsgMdnGenerator.cpp.

{
    DEBUG_MDN("nsMsgMdnGenerator::ValidateReturnPath");
    // ValidateReturnPath applies to Automatic Send Mode only. If we were not
    // in auto send mode we simply by passing the check
    if (!m_autoSend)
        return m_reallySendMdn;
    
    nsXPIDLCString returnPath;
    m_headers->ExtractHeader(HEADER_RETURN_PATH, PR_FALSE,
                             getter_Copies(returnPath));
    if (!returnPath || !*returnPath)
    {
        m_autoSend = PR_FALSE;
        return m_reallySendMdn;
    }
    m_autoSend = MailAddrMatch(returnPath, m_dntRrt);
    return m_reallySendMdn;
}

Here is the call graph for this function:

Here is the caller graph for this function:

nsresult nsMsgMdnGenerator::WriteString ( const char *  str) [private]

Definition at line 894 of file nsMsgMdnGenerator.cpp.

{
  NS_ENSURE_ARG (str);
  PRUint32 len = strlen(str);
  PRUint32 wLen = 0;
  
  return m_outputStream->Write(str, len, &wLen);
}

Here is the caller graph for this function:


Member Data Documentation

Definition at line 66 of file nsIMsgMdnGenerator.idl.

Definition at line 67 of file nsIMsgMdnGenerator.idl.

Definition at line 64 of file nsIMsgMdnGenerator.idl.

Definition at line 63 of file nsIMsgMdnGenerator.idl.

Definition at line 72 of file nsIMsgMdnGenerator.idl.

Definition at line 70 of file nsIMsgMdnGenerator.idl.

Definition at line 68 of file nsIMsgMdnGenerator.idl.

Definition at line 74 of file nsIMsgMdnGenerator.idl.

Definition at line 75 of file nsIMsgMdnGenerator.idl.

Definition at line 65 of file nsIMsgMdnGenerator.idl.

Definition at line 71 of file nsIMsgMdnGenerator.idl.

Definition at line 115 of file nsMsgMdnGenerator.h.

Definition at line 114 of file nsMsgMdnGenerator.h.

Definition at line 102 of file nsMsgMdnGenerator.h.

Definition at line 97 of file nsMsgMdnGenerator.h.

Definition at line 109 of file nsMsgMdnGenerator.h.

Definition at line 103 of file nsMsgMdnGenerator.h.

Definition at line 100 of file nsMsgMdnGenerator.h.

Definition at line 106 of file nsMsgMdnGenerator.h.

Definition at line 108 of file nsMsgMdnGenerator.h.

Definition at line 101 of file nsMsgMdnGenerator.h.

Definition at line 116 of file nsMsgMdnGenerator.h.

Definition at line 105 of file nsMsgMdnGenerator.h.

Definition at line 104 of file nsMsgMdnGenerator.h.

Definition at line 110 of file nsMsgMdnGenerator.h.

Definition at line 112 of file nsMsgMdnGenerator.h.

Definition at line 99 of file nsMsgMdnGenerator.h.

Definition at line 111 of file nsMsgMdnGenerator.h.

Definition at line 113 of file nsMsgMdnGenerator.h.

Definition at line 107 of file nsMsgMdnGenerator.h.

Definition at line 98 of file nsMsgMdnGenerator.h.


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