示例#1
0
nsMsgCompFields::nsMsgCompFields()
{
  PRInt16 i;
  for (i = 0; i < MSG_MAX_HEADERS; i ++)
    m_headers[i] = nsnull;

  m_body.Truncate();

  m_attachVCard = false;
  m_forcePlainText = false;
  m_useMultipartAlternative = false;
  m_returnReceipt = false;
  m_receiptHeaderType = nsIMsgMdnGenerator::eDntType;
  m_DSN = false;
  m_bodyIsAsciiOnly = false;
  m_forceMsgEncoding = false;
  m_needToCheckCharset = true;

  // Get the default charset from pref, use this as a mail charset.
  nsString charset;
  NS_GetLocalizedUnicharPreferenceWithDefault(nsnull, "mailnews.send_default_charset", 
                                              NS_LITERAL_STRING("ISO-8859-1"), charset);

  LossyCopyUTF16toASCII(charset, m_DefaultCharacterSet); // Charsets better be ASCII
  SetCharacterSet(m_DefaultCharacterSet.get());
}
static int MimeInlineText_initializeCharset(MimeObject *obj)
{
  MimeInlineText  *text = (MimeInlineText *) obj;

  text->inputAutodetect = false;
  text->charsetOverridable = false;
  
  /* Figure out an appropriate charset for this object.
  */
  if (!text->charset && obj->headers)
  {
    if (obj->options && obj->options->override_charset)
    {
      text->charset = strdup(obj->options->default_charset);
    }
    else
    {
      char *ct = MimeHeaders_get (obj->headers, HEADER_CONTENT_TYPE,
                                  false, false);
      if (ct)
      {
        text->charset = MimeHeaders_get_parameter (ct, "charset", NULL, NULL);
        PR_Free(ct);
      }
    
      if (!text->charset)
      {
        /* If we didn't find "Content-Type: ...; charset=XX" then look
           for "X-Sun-Charset: XX" instead.  (Maybe this should be done
           in MimeSunAttachmentClass, but it's harder there than here.)
         */
        text->charset = MimeHeaders_get (obj->headers,
                                          HEADER_X_SUN_CHARSET,
                                          false, false);
      }

      /* iMIP entities without an explicit charset parameter default to
       US-ASCII (RFC 2447, section 2.4). However, Microsoft Outlook generates
       UTF-8 but omits the charset parameter.
       When no charset is defined by the container (e.g. iMIP), iCalendar
       files default to UTF-8 (RFC 2445, section 4.1.4).
       */
      if (!text->charset &&
          obj->content_type &&
          !PL_strcasecmp(obj->content_type, TEXT_CALENDAR))
        text->charset = strdup("UTF-8");

      if (!text->charset)
      {
        nsresult res;
        
        text->charsetOverridable = true;

        nsCOMPtr<nsIPrefBranch> prefBranch(do_GetService(NS_PREFSERVICE_CONTRACTID, &res)); 
        if (NS_SUCCEEDED(res))
        {
          nsCOMPtr<nsIPrefLocalizedString> str;
          if (NS_SUCCEEDED(prefBranch->GetComplexValue("intl.charset.detector", NS_GET_IID(nsIPrefLocalizedString), getter_AddRefs(str)))) {
            //only if we can get autodetector name correctly, do we set this to true
            text->inputAutodetect = true;
          }
        }
        
        if (obj->options && obj->options->default_charset)
          text->charset = strdup(obj->options->default_charset);
        else
        {
          if (NS_SUCCEEDED(res))
          {
            nsString value;
            NS_GetLocalizedUnicharPreferenceWithDefault(prefBranch, "mailnews.view_default_charset", EmptyString(), value);
            text->charset = ToNewUTF8String(value);
          }
          else
            text->charset = strdup("");
        }
      } 
    }
  }
  
  if (text->inputAutodetect)
  {
    //we need to prepare lineDam for charset detection
    text->lineDamBuffer = (char*)PR_Malloc(DAM_MAX_BUFFER_SIZE);
    text->lineDamPtrs = (char**)PR_Malloc(DAM_MAX_LINES*sizeof(char*));
    text->curDamOffset = 0;
    text->lastLineInDam = 0;
    if (!text->lineDamBuffer || !text->lineDamPtrs)
    {
      text->inputAutodetect = false;
      PR_FREEIF(text->lineDamBuffer);
      PR_FREEIF(text->lineDamPtrs);
    }
  }

  text->initializeCharset = true;

  return 0;
}
// Test a message send????
nsresult nsEudoraCompose::SendTheMessage(nsIFile *pMailImportLocation, nsIFile **pMsg)
{
  nsresult rv = CreateComponents();
  if (NS_SUCCEEDED( rv))
    rv = CreateIdentity();
  if (NS_FAILED( rv))
    return( rv);

  // IMPORT_LOG0( "Outlook Compose created necessary components\n");

  nsString bodyType;
  nsString charSet;
  nsString headerVal;
  GetHeaderValue( m_pHeaders, m_headerLen, "From:", headerVal);
  if (!headerVal.IsEmpty())
    m_pMsgFields->SetFrom( headerVal);
  GetHeaderValue( m_pHeaders, m_headerLen, "To:", headerVal);
  if (!headerVal.IsEmpty())
    m_pMsgFields->SetTo( headerVal);
  GetHeaderValue( m_pHeaders, m_headerLen, "Subject:", headerVal);
  if (!headerVal.IsEmpty())
    m_pMsgFields->SetSubject( headerVal);
  GetHeaderValue( m_pHeaders, m_headerLen, "Content-type:", headerVal);
  bodyType = headerVal;
  ExtractType( bodyType);
  ExtractCharset( headerVal);
  // Use platform charset as default if the msg doesn't specify one
  // (ie, no 'charset' param in the Content-Type: header). As the last
  // resort we'll use the mail default charset.
  // (ie, no 'charset' param in the Content-Type: header) or if the
  // charset parameter fails a length sanity check.
  // As the last resort we'll use the mail default charset.
  if ( headerVal.IsEmpty() || (headerVal.Length() > kContentTypeLengthSanityCheck) )
  {
    CopyASCIItoUTF16(nsMsgI18NFileSystemCharset(), headerVal);
    if (headerVal.IsEmpty())
    { // last resort
      if (m_defCharset.IsEmpty())
      {
        nsString defaultCharset;
        NS_GetLocalizedUnicharPreferenceWithDefault(nsnull, "mailnews.view_default_charset",
                                                    NS_LITERAL_STRING("ISO-8859-1"), defaultCharset);
        m_defCharset = defaultCharset;
      }
      headerVal = m_defCharset;
    }
  }
  m_pMsgFields->SetCharacterSet( NS_LossyConvertUTF16toASCII(headerVal).get() );
  charSet = headerVal;
  GetHeaderValue( m_pHeaders, m_headerLen, "CC:", headerVal);
  if (!headerVal.IsEmpty())
    m_pMsgFields->SetCc( headerVal);
  GetHeaderValue( m_pHeaders, m_headerLen, "Message-ID:", headerVal);
  if (!headerVal.IsEmpty())
    m_pMsgFields->SetMessageId( NS_LossyConvertUTF16toASCII(headerVal).get() );
  GetHeaderValue( m_pHeaders, m_headerLen, "Reply-To:", headerVal);
  if (!headerVal.IsEmpty())
    m_pMsgFields->SetReplyTo( headerVal);

  // what about all of the other headers?!?!?!?!?!?!
  char *pMimeType;
  if (!bodyType.IsEmpty())
    pMimeType = ToNewCString(bodyType);
  else
    pMimeType = ToNewCString(m_bodyType);

  // IMPORT_LOG0( "Outlook compose calling CreateAndSendMessage\n");
  nsMsgAttachedFile *pAttach = GetLocalAttachments();


  /*
    l10n - I have the body of the message in the system charset,
    I need to "encode" it to be the charset for the message
    *UNLESS* of course, I don't know what the charset of the message
    should be?  How do I determine what the charset should
    be if it doesn't exist?

  */

  nsString uniBody;
  NS_CopyNativeToUnicode( nsDependentCString(m_pBody), uniBody);

  nsCString body;

  rv = nsMsgI18NConvertFromUnicode( NS_LossyConvertUTF16toASCII(charSet).get(),
                                    uniBody, body);
  if (NS_FAILED( rv)) {
    // in this case, if we did not use the default compose
    // charset, then try that.
    if (!charSet.Equals( m_defCharset)) {
      body.Truncate();
      rv = nsMsgI18NConvertFromUnicode( NS_LossyConvertUTF16toASCII(charSet).get(),
                                        uniBody, body);
    }
  }
  uniBody.Truncate();


  // See if it's a draft msg (ie, no From: or no To: AND no Cc: AND no Bcc:).
  // Eudora saves sent and draft msgs in Out folder (ie, mixed) and it does
  // store Bcc: header in the msg itself.
  nsMsgDeliverMode mode = nsIMsgSend::nsMsgDeliverNow;
  nsAutoString from, to, cc, bcc;
  rv = m_pMsgFields->GetFrom(from);
  rv = m_pMsgFields->GetTo(to);
  rv = m_pMsgFields->GetCc(cc);
  rv = m_pMsgFields->GetBcc(bcc);
  if ( from.IsEmpty() || to.IsEmpty() && cc.IsEmpty() && bcc.IsEmpty() )
    mode = nsIMsgSend::nsMsgSaveAsDraft;

  // We only get the editor interface when there's embedded content.
  // Otherwise pEditor remains NULL. That way we only import with the pseudo
  // editor when it helps.
  nsRefPtr<nsEudoraEditor>  pEudoraEditor = new nsEudoraEditor(m_pBody, pMailImportLocation);
  nsCOMPtr<nsIEditor>       pEditor;

  if (pEudoraEditor->HasEmbeddedContent())
    // There's embedded content that we need to import, so query for the editor interface
    pEudoraEditor->QueryInterface( NS_GET_IID(nsIEditor), getter_AddRefs(pEditor) );

  if (NS_FAILED( rv)) {

    rv = m_pSendProxy->CreateAndSendMessage(
                          pEditor.get(),                // pseudo editor shell when there's embedded content
                          s_pIdentity,                  // dummy identity
                          nsnull,                       // account key
                          m_pMsgFields,                 // message fields
                          PR_FALSE,                     // digest = NO
                          PR_TRUE,                      // dont_deliver = YES, make a file
                          mode,                         // mode
                          nsnull,                       // no message to replace
                          pMimeType,                    // body type
                          m_pBody,                      // body pointer
                          m_bodyLen,                    // body length
                          nsnull,                       // remote attachment data
                          pAttach,                      // local attachments
                          nsnull,                       // related part
                          nsnull,                       // parent window
                          nsnull,                       // progress listener
                          m_pListener,                  // listener
                          nsnull,                       // password
                          EmptyCString(),               // originalMsgURI
                          nsnull);                      // message compose type

  }
  else {
    rv = m_pSendProxy->CreateAndSendMessage(
                          pEditor.get(),                // pseudo editor shell when there's embedded content
                          s_pIdentity,                  // dummy identity
                          nsnull,                       // account key
                          m_pMsgFields,                 // message fields
                          PR_FALSE,                     // digest = NO
                          PR_TRUE,                      // dont_deliver = YES, make a file
                          mode,                         // mode
                          nsnull,                       // no message to replace
                          pMimeType,                    // body type
                          body.get(),                   // body pointer
                          body.Length(),                // body length
                          nsnull,                       // remote attachment data
                          pAttach,                      // local attachments
                          nsnull,                       // related part
                          nsnull,                       // parent window
                          nsnull,                       // progress listener
                          m_pListener,                  // listener
                          nsnull,                       // password
                          EmptyCString(),               // originalMsgURI
                          nsnull);                      // message compose type

  }

  // IMPORT_LOG0( "Returned from CreateAndSendMessage\n");

  if (pAttach)
    delete [] pAttach;

  EudoraSendListener *pListen = (EudoraSendListener *)m_pListener;
  if (NS_FAILED( rv)) {
    IMPORT_LOG1( "*** Error, CreateAndSendMessage FAILED: 0x%lx\n", rv);
    // IMPORT_LOG1( "Headers: %80s\n", m_pHeaders);
  }
  else {
    // wait for the listener to get done!
    PRInt32 abortCnt = 0;
    PRInt32 cnt = 0;
    PRInt32 sleepCnt = 1;
    while (!pListen->m_done && (abortCnt < kHungAbortCount)) {
      PR_Sleep( sleepCnt);
      cnt++;
      if (cnt > kHungCount) {
        abortCnt++;
        sleepCnt *= 2;
        cnt = 0;
      }
    }

    if (abortCnt >= kHungAbortCount) {
      IMPORT_LOG0( "**** Create and send message hung\n");
      IMPORT_LOG1( "Headers: %s\n", m_pHeaders);
      IMPORT_LOG1( "Body: %s\n", m_pBody);
      rv = NS_ERROR_FAILURE;
    }

  }

  if (pMimeType)
    NS_Free( pMimeType);

  if (pListen->m_location) {
    pListen->m_location->Clone(pMsg);
    rv = NS_OK;
  }
  else {
    rv = NS_ERROR_FAILURE;
    IMPORT_LOG0( "*** Error, Outlook compose unsuccessful\n");
  }

  pListen->Reset();

  return( rv);
}
示例#4
0
// Test a message send????
nsresult nsEudoraCompose::SendTheMessage(nsIFile *pMailImportLocation, nsIFile **pMsg)
{
  nsresult rv = CreateComponents();
  if (NS_FAILED(rv))
    return rv;

  // IMPORT_LOG0("Outlook Compose created necessary components\n");

  nsString bodyType;
  nsString charSet;
  nsString headerVal;
  GetHeaderValue(m_pHeaders, m_headerLen, "From:", headerVal);
  if (!headerVal.IsEmpty())
    m_pMsgFields->SetFrom(headerVal);
  GetHeaderValue(m_pHeaders, m_headerLen, "To:", headerVal);
  if (!headerVal.IsEmpty())
    m_pMsgFields->SetTo(headerVal);
  GetHeaderValue(m_pHeaders, m_headerLen, "Subject:", headerVal);
  if (!headerVal.IsEmpty())
    m_pMsgFields->SetSubject(headerVal);
  GetHeaderValue(m_pHeaders, m_headerLen, "Content-type:", headerVal);
  bodyType = headerVal;
  ExtractType(bodyType);
  ExtractCharset(headerVal);
  // Use platform charset as default if the msg doesn't specify one
  // (ie, no 'charset' param in the Content-Type: header). As the last
  // resort we'll use the mail default charset.
  // (ie, no 'charset' param in the Content-Type: header) or if the
  // charset parameter fails a length sanity check.
  // As the last resort we'll use the mail default charset.
  if (headerVal.IsEmpty() || (headerVal.Length() > kContentTypeLengthSanityCheck))
  {
    headerVal.AssignASCII(nsMsgI18NFileSystemCharset());
    if (headerVal.IsEmpty())
    { // last resort
      if (m_defCharset.IsEmpty())
      {
        nsString defaultCharset;
        NS_GetLocalizedUnicharPreferenceWithDefault(nullptr, "mailnews.view_default_charset",
                                                    NS_LITERAL_STRING("ISO-8859-1"), defaultCharset);
        m_defCharset = defaultCharset;
      }
      headerVal = m_defCharset;
    }
  }
  m_pMsgFields->SetCharacterSet(NS_LossyConvertUTF16toASCII(headerVal).get());
  charSet = headerVal;
  GetHeaderValue(m_pHeaders, m_headerLen, "CC:", headerVal);
  if (!headerVal.IsEmpty())
    m_pMsgFields->SetCc(headerVal);
  GetHeaderValue(m_pHeaders, m_headerLen, "Message-ID:", headerVal);
  if (!headerVal.IsEmpty())
    m_pMsgFields->SetMessageId(NS_LossyConvertUTF16toASCII(headerVal).get());
  GetHeaderValue(m_pHeaders, m_headerLen, "Reply-To:", headerVal);
  if (!headerVal.IsEmpty())
    m_pMsgFields->SetReplyTo(headerVal);

  // what about all of the other headers?!?!?!?!?!?!
  char *pMimeType;
  if (!bodyType.IsEmpty())
    pMimeType = ToNewCString(NS_LossyConvertUTF16toASCII(bodyType));
  else
    pMimeType = ToNewCString(m_bodyType);

  nsCOMPtr<nsIArray> pAttach;
  GetLocalAttachments(getter_AddRefs(pAttach));
  nsEudoraEditor eudoraEditor(m_pBody, pMailImportLocation);
  nsCOMPtr<nsIArray> embeddedObjects;
  if (eudoraEditor.HasEmbeddedContent())
    eudoraEditor.GetEmbeddedObjects(getter_AddRefs(embeddedObjects));

  nsString uniBody;
  NS_CopyNativeToUnicode(nsDependentCString(m_pBody), uniBody);

  /*
    l10n - I have the body of the message in the system charset,
    I need to "encode" it to be the charset for the message
    *UNLESS* of course, I don't know what the charset of the message
    should be?  How do I determine what the charset should
    be if it doesn't exist?

  */

  nsCString body;

  rv = nsMsgI18NConvertFromUnicode(NS_LossyConvertUTF16toASCII(charSet).get(),
                                    uniBody, body);
  if (NS_FAILED(rv) && !charSet.Equals(m_defCharset)) {
    // in this case, if we did not use the default compose
    // charset, then try that.
    body.Truncate();
    rv = nsMsgI18NConvertFromUnicode(NS_LossyConvertUTF16toASCII(charSet).get(),
                                     uniBody, body);
  }
  uniBody.Truncate();


  // See if it's a draft msg (ie, no From: or no To: AND no Cc: AND no Bcc:).
  // Eudora saves sent and draft msgs in Out folder (ie, mixed) and it does
  // store Bcc: header in the msg itself.
  nsAutoString from, to, cc, bcc;
  rv = m_pMsgFields->GetFrom(from);
  rv = m_pMsgFields->GetTo(to);
  rv = m_pMsgFields->GetCc(cc);
  rv = m_pMsgFields->GetBcc(bcc);
  bool createAsDraft = from.IsEmpty() || (to.IsEmpty() && cc.IsEmpty() && bcc.IsEmpty());

  nsCOMPtr<nsIImportService> impService(do_GetService(NS_IMPORTSERVICE_CONTRACTID, &rv));
  NS_ENSURE_SUCCESS(rv, rv);

  rv = impService->CreateRFC822Message(
                        s_pIdentity,                  // dummy identity
                        m_pMsgFields,                 // message fields
                        pMimeType,                    // body type
                        body,                         // body pointer
                        createAsDraft,
                        pAttach,                      // local attachments
                        embeddedObjects,
                        m_pListener);                 // listener

  EudoraSendListener *pListen = (EudoraSendListener *)m_pListener;
  if (NS_FAILED(rv)) {
    IMPORT_LOG1("*** Error, CreateAndSendMessage FAILED: 0x%lx\n", rv);
    // IMPORT_LOG1("Headers: %80s\n", m_pHeaders);
  }
  else {
    // wait for the listener to get done!
    int32_t abortCnt = 0;
    int32_t cnt = 0;
    int32_t sleepCnt = 1;
    while (!pListen->m_done && (abortCnt < kHungAbortCount)) {
      PR_Sleep(sleepCnt);
      cnt++;
      if (cnt > kHungCount) {
        abortCnt++;
        sleepCnt *= 2;
        cnt = 0;
      }
    }

    if (abortCnt >= kHungAbortCount) {
      IMPORT_LOG0("**** Create and send message hung\n");
      IMPORT_LOG1("Headers: %s\n", m_pHeaders);
      IMPORT_LOG1("Body: %s\n", m_pBody);
      rv = NS_ERROR_FAILURE;
    }

  }

  if (pMimeType)
    NS_Free(pMimeType);

  if (pListen->m_location) {
    pListen->m_location->Clone(pMsg);
    rv = NS_OK;
  }
  else {
    rv = NS_ERROR_FAILURE;
    IMPORT_LOG0("*** Error, Outlook compose unsuccessful\n");
  }

  pListen->Reset();

  return rv;
}