void OESettings::SetIdentities(nsIMsgAccountManager *pMgr, nsIMsgAccount *pAcc, HKEY hKey, char *pIncomgUserName, PRInt32 authMethodIncoming, bool isNNTP) { // Get the relevant information for an identity char *pSmtpServer = (char *)nsOERegUtil::GetValueBytes(hKey, "SMTP Server"); char *pName = (char *)nsOERegUtil::GetValueBytes(hKey, isNNTP ? "NNTP Display Name" : "SMTP Display Name"); char *pEmail = (char *)nsOERegUtil::GetValueBytes(hKey, isNNTP ? "NNTP Email Address" : "SMTP Email Address"); char *pReply = (char *)nsOERegUtil::GetValueBytes(hKey, isNNTP ? "NNTP Reply To Email Address" : "SMTP Reply To Email Address"); char *pOrgName = (char *)nsOERegUtil::GetValueBytes(hKey, isNNTP ? "NNTP Organization Name" : "SMTP Organization Name"); nsresult rv; nsCOMPtr<nsIMsgIdentity> id; rv = pMgr->CreateIdentity(getter_AddRefs(id)); if (id) { nsAutoString fullName, organization; rv = nsMsgI18NConvertToUnicode(nsMsgI18NFileSystemCharset(), nsCString(pName), fullName); if (NS_SUCCEEDED(rv)) id->SetFullName(fullName); // BUG 470587. Don't set this: id->SetIdentityName(fullName); rv = nsMsgI18NConvertToUnicode(nsMsgI18NFileSystemCharset(), nsCString(pOrgName), organization); if (NS_SUCCEEDED(rv)) id->SetOrganization(organization); id->SetEmail(nsCString(pEmail)); if (pReply) id->SetReplyTo(nsCString(pReply)); // Outlook Express users are used to top style quoting. id->SetReplyOnTop(isNNTP ? 0 : 1); pAcc->AddIdentity(id); IMPORT_LOG0("Created identity and added to the account\n"); IMPORT_LOG1("\tname: %s\n", pName); IMPORT_LOG1("\temail: %s\n", pEmail); } if (!isNNTP) // NNTP does not use SMTP in OE or TB SetSmtpServer(pSmtpServer, hKey, id, pIncomgUserName, authMethodIncoming); nsOERegUtil::FreeValueBytes((BYTE *)pName); nsOERegUtil::FreeValueBytes((BYTE *)pSmtpServer); nsOERegUtil::FreeValueBytes((BYTE *)pEmail); nsOERegUtil::FreeValueBytes((BYTE *)pReply); }
void nsOutlookMail::BuildAttachments( CMapiMessage& msg, int count) { EmptyAttachments(); if (count) { nsresult rv; nsCOMPtr <nsILocalFile> pFile; for (int i = 0; i < count; i++) { if (!msg.GetAttachmentInfo( i)) { IMPORT_LOG1( "*** Error getting attachment info for #%d\n", i); } pFile = do_CreateInstance(NS_LOCAL_FILE_CONTRACTID, &rv); if (NS_FAILED( rv) || !pFile) { IMPORT_LOG0( "*** Error creating file spec for attachment\n"); } else { if (msg.GetAttachFileLoc( pFile)) { PRBool isFile = PR_FALSE; PRBool exists = PR_FALSE; pFile->Exists( &exists); pFile->IsFile( &isFile); if (!exists || !isFile) { IMPORT_LOG0( "Attachment file does not exist\n"); } else { // We have a file spec, now get the other info OutlookAttachment *a = new OutlookAttachment; a->mimeType = strdup( msg.GetMimeType()); // Init description here so that we cacn tell // if defaul tattacchment is needed later. a->description = nsnull; const char *fileName = msg.GetFileName(); if (fileName && fileName[0]) { // Convert description to unicode. nsAutoString description; rv = nsMsgI18NConvertToUnicode(nsMsgI18NFileSystemCharset(), nsDependentCString(fileName), description); NS_ASSERTION(NS_SUCCEEDED(rv), "failed to convert system string to unicode"); if (NS_SUCCEEDED(rv)) a->description = ToNewUTF8String(description); } // If no description use "Attachment i" format. if (!a->description) { nsCAutoString str("Attachment "); str.AppendInt( (PRInt32) i); a->description = ToNewCString( str); } a->pAttachment = pFile; m_attachments.AppendElement( a); } } } } } }
nsresult OESettings::GetAccountName(HKEY hKey, char *defaultName, nsString &acctName) { BYTE *pAccName = nsOERegUtil::GetValueBytes(hKey, "Account Name"); nsresult rv = NS_OK; if (pAccName) { rv = nsMsgI18NConvertToUnicode(nsMsgI18NFileSystemCharset(), nsDependentCString((const char *)pAccName), acctName); nsOERegUtil::FreeValueBytes(pAccName); } else acctName.AssignASCII(defaultName); return rv; }
nsresult nsTextAddress::GetUnicharLineStreamForFile( nsIFile *aFile, nsIInputStream *aInputStream, nsIUnicharLineInputStream **aStream) { nsAutoCString charset; nsresult rv = MsgDetectCharsetFromFile(aFile, charset); if (NS_FAILED(rv)) { charset = nsMsgI18NFileSystemCharset(); } nsCOMPtr<nsIConverterInputStream> converterStream = do_CreateInstance("@mozilla.org/intl/converter-input-stream;1", &rv); if (NS_SUCCEEDED(rv)) { rv = converterStream->Init( aInputStream, charset.get(), 8192, nsIConverterInputStream::DEFAULT_REPLACEMENT_CHARACTER); } return CallQueryInterface(converterStream, aStream); }
// this is used to convert non Unicode data and then populate comp fields nsresult nsMapiHook::PopulateCompFieldsWithConversion(lpnsMapiMessage aMessage, nsIMsgCompFields * aCompFields) { nsresult rv = NS_OK; if (aMessage->lpOriginator) { nsAutoString From; From.Append(NS_ConvertASCIItoUTF16((char *) aMessage->lpOriginator->lpszAddress)); aCompFields->SetFrom (From); } nsAutoString To; nsAutoString Cc; nsAutoString Bcc; NS_NAMED_LITERAL_STRING(Comma, ","); if (aMessage->lpRecips) { for (int i=0 ; i < (int) aMessage->nRecipCount ; i++) { if (aMessage->lpRecips[i].lpszAddress || aMessage->lpRecips[i].lpszName) { const char *addressWithoutType = (aMessage->lpRecips[i].lpszAddress) ? aMessage->lpRecips[i].lpszAddress : aMessage->lpRecips[i].lpszName; if (!PL_strncasecmp(addressWithoutType, "SMTP:", 5)) addressWithoutType += 5; switch (aMessage->lpRecips[i].ulRecipClass) { case MAPI_TO : if (!To.IsEmpty()) To += Comma ; To.Append(NS_ConvertASCIItoUTF16(addressWithoutType)); break ; case MAPI_CC : if (!Cc.IsEmpty()) Cc += Comma ; Cc.Append(NS_ConvertASCIItoUTF16(addressWithoutType)); break ; case MAPI_BCC : if (!Bcc.IsEmpty()) Bcc += Comma ; Bcc.Append(NS_ConvertASCIItoUTF16(addressWithoutType)); break ; } } } } // set To, Cc, Bcc aCompFields->SetTo (To) ; aCompFields->SetCc (Cc) ; aCompFields->SetBcc (Bcc) ; PR_LOG(MAPI, PR_LOG_DEBUG, ("to: %s cc: %s bcc: %s \n", NS_ConvertUTF16toUTF8(To).get(), NS_ConvertUTF16toUTF8(Cc).get(), NS_ConvertUTF16toUTF8(Bcc).get())); nsCAutoString platformCharSet; // set subject if (aMessage->lpszSubject) { nsAutoString Subject ; if (platformCharSet.IsEmpty()) platformCharSet.Assign(nsMsgI18NFileSystemCharset()); rv = ConvertToUnicode(platformCharSet.get(), (char *) aMessage->lpszSubject, Subject); if (NS_FAILED(rv)) return rv; aCompFields->SetSubject(Subject); } // handle attachments as File URL rv = HandleAttachments (aCompFields, aMessage->nFileCount, aMessage->lpFiles, PR_FALSE) ; if (NS_FAILED(rv)) return rv ; // set body if (aMessage->lpszNoteText) { nsAutoString Body ; if (platformCharSet.IsEmpty()) platformCharSet.Assign(nsMsgI18NFileSystemCharset()); rv = ConvertToUnicode(platformCharSet.get(), (char *) aMessage->lpszNoteText, Body); if (NS_FAILED(rv)) return rv ; if (Body.Last() != '\n') Body.AppendLiteral(CRLF); if (Body.Find("<html>") == kNotFound) aCompFields->SetForcePlainText(PR_TRUE); rv = aCompFields->SetBody(Body) ; } #ifdef RAJIV_DEBUG // testing what all was set in CompFields printf ("To : %S \n", To.get()) ; printf ("CC : %S \n", Cc.get() ) ; printf ("BCC : %S \n", Bcc.get() ) ; #endif return rv ; }
nsresult nsMapiHook::HandleAttachments (nsIMsgCompFields * aCompFields, PRInt32 aFileCount, lpnsMapiFileDesc aFiles, BOOL aIsUnicode) { nsresult rv = NS_OK ; nsCAutoString Attachments ; nsCAutoString TempFiles ; nsCOMPtr <nsILocalFile> pFile = do_CreateInstance (NS_LOCAL_FILE_CONTRACTID, &rv) ; if (NS_FAILED(rv) || (!pFile) ) return rv ; nsCOMPtr <nsILocalFile> pTempDir = do_CreateInstance (NS_LOCAL_FILE_CONTRACTID, &rv) ; if (NS_FAILED(rv) || (!pTempDir) ) return rv ; for (int i=0 ; i < aFileCount ; i++) { PRBool bTempFile = PR_FALSE ; if (aFiles[i].lpszPathName) { // check if attachment exists if (aIsUnicode) pFile->InitWithPath (nsDependentString(aFiles[i].lpszPathName)); else pFile->InitWithNativePath (nsDependentCString((const char*)aFiles[i].lpszPathName)); PRBool bExist ; rv = pFile->Exists(&bExist) ; PR_LOG(MAPI, PR_LOG_DEBUG, ("nsMapiHook::HandleAttachments: filename: %s path: %s exists = %s \n", (const char*)aFiles[i].lpszFileName, (const char*)aFiles[i].lpszPathName, bExist ? "true" : "false")); if (NS_FAILED(rv) || (!bExist) ) return NS_ERROR_FILE_TARGET_DOES_NOT_EXIST ; //Temp Directory nsCOMPtr <nsIFile> pTempFileDir; NS_GetSpecialDirectory(NS_OS_TEMP_DIR, getter_AddRefs(pTempFileDir)); nsCOMPtr <nsILocalFile> pTempDir = do_QueryInterface(pTempFileDir); // create a new sub directory called moz_mapi underneath the temp directory pTempDir->AppendRelativePath(NS_LITERAL_STRING("moz_mapi")); pTempDir->Exists (&bExist) ; if (!bExist) { rv = pTempDir->Create(nsIFile::DIRECTORY_TYPE, 777) ; if (NS_FAILED(rv)) return rv ; } // rename or copy the existing temp file with the real file name nsAutoString leafName ; // convert to Unicode using Platform charset // leafName already contains a unicode leafName from lpszPathName. If we were given // a value for lpszFileName, use it. Otherwise stick with leafName if (aFiles[i].lpszFileName) { nsAutoString wholeFileName; if (aIsUnicode) wholeFileName.Assign(aFiles[i].lpszFileName); else ConvertToUnicode(nsMsgI18NFileSystemCharset(), (char *) aFiles[i].lpszFileName, wholeFileName); // need to find the last '\' and find the leafname from that. PRInt32 lastSlash = wholeFileName.RFindChar(PRUnichar('\\')); if (lastSlash != kNotFound) wholeFileName.Right(leafName, wholeFileName.Length() - lastSlash - 1); else leafName.Assign(wholeFileName); } else pFile->GetLeafName (leafName); nsCOMPtr <nsIFile> pTempFile; rv = pTempDir->Clone(getter_AddRefs(pTempFile)); if (NS_FAILED(rv) || (!pTempFile) ) return rv; pTempFile->Append(leafName); pTempFile->Exists(&bExist); if (bExist) { rv = pTempFile->CreateUnique(nsIFile::NORMAL_FILE_TYPE, 0777); NS_ENSURE_SUCCESS(rv, rv); pTempFile->Remove(PR_FALSE); // remove so we can copy over it. } // copy the file to its new location and file name pFile->CopyTo(pTempDir, leafName); // point pFile to the new location of the attachment pFile->InitWithFile(pTempDir); pFile->Append(leafName); // create MsgCompose attachment object nsCOMPtr<nsIMsgAttachment> attachment = do_CreateInstance(NS_MSGATTACHMENT_CONTRACTID, &rv); NS_ENSURE_SUCCESS(rv, rv); attachment->SetTemporary(PR_TRUE); // this one is a temp file so set the flag for MsgCompose // now set the attachment object nsCAutoString pURL ; NS_GetURLSpecFromFile(pFile, pURL); attachment->SetUrl(pURL.get()) ; // add the attachment rv = aCompFields->AddAttachment (attachment); if (NS_FAILED(rv)) PR_LOG(MAPI, PR_LOG_DEBUG, ("nsMapiHook::HandleAttachments: AddAttachment rv = %lx\n", rv)); } } return rv ; }
NS_IMETHODIMP ImportAddressImpl::GetSampleData(PRInt32 index, bool *pFound, PRUnichar **pStr) { NS_PRECONDITION(pFound != nsnull, "null ptr"); NS_PRECONDITION(pStr != nsnull, "null ptr"); if (!pFound || !pStr) return NS_ERROR_NULL_POINTER; if (!m_fileLoc) { IMPORT_LOG0("*** Error, called GetSampleData before SetSampleLocation\n"); return NS_ERROR_FAILURE; } nsresult rv; *pStr = nsnull; PRUnichar term = 0; if (!m_haveDelim) { rv = m_text.DetermineDelim(m_fileLoc); NS_ENSURE_SUCCESS(rv, rv); m_haveDelim = true; m_delim = m_text.GetDelim(); } bool fileExists; rv = m_fileLoc->Exists(&fileExists); NS_ENSURE_SUCCESS(rv, rv); if (!fileExists) { *pFound = false; *pStr = NS_strdup(&term); return NS_OK; } nsCString line; rv = nsTextAddress::ReadRecordNumber(m_fileLoc, line, index); if (NS_SUCCEEDED(rv)) { nsString str; nsCString field; nsString uField; PRInt32 fNum = 0; while (nsTextAddress::GetField(line.get(), line.Length(), fNum, field, m_delim)) { if (fNum) str.Append(PRUnichar('\n')); SanitizeSampleData(field); rv = nsMsgI18NConvertToUnicode(nsMsgI18NFileSystemCharset(), field, uField); str.Append(uField); fNum++; field.Truncate(); } *pStr = ToNewUnicode(str); *pFound = true; /* IMPORT_LOG1("Sample data: %S\n", str.get()); */ } else { *pFound = false; *pStr = NS_strdup(&term); } return NS_OK; }
void OutlookSettings::SetIdentities(nsIMsgAccountManager *pMgr, nsIMsgAccount *pAcc, HKEY hKey) { // Get the relevant information for an identity char *pName = (char *)nsOutlookRegUtil::GetValueBytes(hKey, "SMTP Display Name"); char *pServer = (char *)nsOutlookRegUtil::GetValueBytes(hKey, "SMTP Server"); char *pEmail = (char *)nsOutlookRegUtil::GetValueBytes(hKey, "SMTP Email Address"); char *pReply = (char *)nsOutlookRegUtil::GetValueBytes(hKey, "SMTP Reply To Email Address"); nsCString userName; userName.Adopt((char *)nsOutlookRegUtil::GetValueBytes(hKey, "SMTP User Name")); char *pOrgName = (char *)nsOutlookRegUtil::GetValueBytes(hKey, "SMTP Organization Name"); nsresult rv; if (pEmail && pName && pServer) { // The default identity, nor any other identities matched, // create a new one and add it to the account. nsCOMPtr<nsIMsgIdentity> id; rv = pMgr->CreateIdentity(getter_AddRefs(id)); if (id) { nsAutoString name, organization; rv = nsMsgI18NConvertToUnicode(nsMsgI18NFileSystemCharset(), nsDependentCString(pName), name); if (NS_SUCCEEDED(rv)) { id->SetFullName(name); id->SetIdentityName(name); } if (pOrgName) { rv = nsMsgI18NConvertToUnicode(nsMsgI18NFileSystemCharset(), nsDependentCString(pOrgName), organization); if (NS_SUCCEEDED(rv)) id->SetOrganization(organization); } id->SetEmail(nsDependentCString(pEmail)); if (pReply) id->SetReplyTo(nsDependentCString(pReply)); pAcc->AddIdentity(id); IMPORT_LOG0("Created identity and added to the account\n"); IMPORT_LOG1("\tname: %s\n", pName); IMPORT_LOG1("\temail: %s\n", pEmail); } } if (userName.IsEmpty()) { nsCOMPtr <nsIMsgIncomingServer> incomingServer; rv = pAcc->GetIncomingServer(getter_AddRefs(incomingServer)); if (NS_SUCCEEDED(rv) && incomingServer) rv = incomingServer->GetUsername(userName); NS_ASSERTION(NS_SUCCEEDED(rv), "Unable to get UserName from incomingServer"); } SetSmtpServer(pMgr, pAcc, pServer, userName); nsOutlookRegUtil::FreeValueBytes((BYTE *)pName); nsOutlookRegUtil::FreeValueBytes((BYTE *)pServer); nsOutlookRegUtil::FreeValueBytes((BYTE *)pEmail); nsOutlookRegUtil::FreeValueBytes((BYTE *)pReply); }
nsresult nsAbManager::ExportDirectoryToDelimitedText(nsIAbDirectory *aDirectory, const char *aDelim, PRUint32 aDelimLen, nsILocalFile *aLocalFile) { nsCOMPtr <nsISimpleEnumerator> cardsEnumerator; nsCOMPtr <nsIAbCard> card; nsresult rv; nsCOMPtr <nsIOutputStream> outputStream; rv = MsgNewBufferedFileOutputStream(getter_AddRefs(outputStream), aLocalFile, PR_CREATE_FILE | PR_WRONLY | PR_TRUNCATE, 0664); // the desired file may be read only if (NS_FAILED(rv)) return rv; PRUint32 i; PRUint32 writeCount; PRUint32 length; nsCOMPtr<nsIStringBundleService> bundleService = do_GetService(NS_STRINGBUNDLE_CONTRACTID, &rv); NS_ENSURE_SUCCESS(rv, rv); nsCOMPtr<nsIStringBundle> bundle; rv = bundleService->CreateBundle("chrome://messenger/locale/importMsgs.properties", getter_AddRefs(bundle)); NS_ENSURE_SUCCESS(rv, rv); nsCString revisedName; nsString columnName; for (i = 0; i < NS_ARRAY_LENGTH(EXPORT_ATTRIBUTES_TABLE); i++) { if (EXPORT_ATTRIBUTES_TABLE[i].plainTextStringID != 0) { // We don't need to truncate the string here as getter_Copies will // do that for us. if (NS_FAILED(bundle->GetStringFromID(EXPORT_ATTRIBUTES_TABLE[i].plainTextStringID, getter_Copies(columnName)))) columnName.AppendInt(EXPORT_ATTRIBUTES_TABLE[i].plainTextStringID); rv = nsMsgI18NConvertFromUnicode(nsMsgI18NFileSystemCharset(), columnName, revisedName); NS_ENSURE_SUCCESS(rv,rv); rv = outputStream->Write(revisedName.get(), revisedName.Length(), &writeCount); NS_ENSURE_SUCCESS(rv,rv); if (revisedName.Length() != writeCount) return NS_ERROR_FAILURE; if (i < NS_ARRAY_LENGTH(EXPORT_ATTRIBUTES_TABLE) - 1) { rv = outputStream->Write(aDelim, aDelimLen, &writeCount); NS_ENSURE_SUCCESS(rv,rv); if (aDelimLen != writeCount) return NS_ERROR_FAILURE; } } } rv = outputStream->Write(MSG_LINEBREAK, MSG_LINEBREAK_LEN, &writeCount); NS_ENSURE_SUCCESS(rv,rv); if (MSG_LINEBREAK_LEN != writeCount) return NS_ERROR_FAILURE; rv = aDirectory->GetChildCards(getter_AddRefs(cardsEnumerator)); if (NS_SUCCEEDED(rv) && cardsEnumerator) { nsCOMPtr<nsISupports> item; bool more; while (NS_SUCCEEDED(cardsEnumerator->HasMoreElements(&more)) && more) { rv = cardsEnumerator->GetNext(getter_AddRefs(item)); if (NS_SUCCEEDED(rv)) { nsCOMPtr <nsIAbCard> card = do_QueryInterface(item, &rv); NS_ENSURE_SUCCESS(rv,rv); bool isMailList; rv = card->GetIsMailList(&isMailList); NS_ENSURE_SUCCESS(rv,rv); if (isMailList) { // .tab, .txt and .csv aren't able to export mailing lists // use LDIF for that. } else { nsString value; nsCString valueCStr; for (i = 0; i < NS_ARRAY_LENGTH(EXPORT_ATTRIBUTES_TABLE); i++) { if (EXPORT_ATTRIBUTES_TABLE[i].plainTextStringID != 0) { rv = card->GetPropertyAsAString(EXPORT_ATTRIBUTES_TABLE[i].abPropertyName, value); if (NS_FAILED(rv)) value.Truncate(); // If a string contains at least one comma, tab or double quote then // we need to quote the entire string. Also if double quote is part // of the string we need to quote the double quote(s) as well. nsAutoString newValue(value); bool needsQuotes = false; if(newValue.FindChar('"') != -1) { needsQuotes = PR_TRUE; PRInt32 match = 0; PRUint32 offset = 0; nsString oldSubstr = NS_LITERAL_STRING("\""); nsString newSubstr = NS_LITERAL_STRING("\"\""); while (offset < newValue.Length()) { match = newValue.Find(oldSubstr, offset); if (match == -1) break; newValue.Replace(offset + match, oldSubstr.Length(), newSubstr); offset += (match + newSubstr.Length()); } } if (!needsQuotes && (newValue.FindChar(',') != -1 || newValue.FindChar('\x09') != -1)) needsQuotes = PR_TRUE; // Make sure we quote if containing CR/LF. if (newValue.FindChar('\r') != -1 || newValue.FindChar('\n') != -1) needsQuotes = PR_TRUE; if (needsQuotes) { newValue.Insert(NS_LITERAL_STRING("\""), 0); newValue.AppendLiteral("\""); } rv = nsMsgI18NConvertFromUnicode(nsMsgI18NFileSystemCharset(), newValue, valueCStr); NS_ENSURE_SUCCESS(rv,rv); if (NS_FAILED(rv)) { NS_ERROR("failed to convert string to system charset. use LDIF"); valueCStr = "?"; } length = valueCStr.Length(); if (length) { rv = outputStream->Write(valueCStr.get(), length, &writeCount); NS_ENSURE_SUCCESS(rv,rv); if (length != writeCount) return NS_ERROR_FAILURE; } valueCStr = ""; } else { // something we don't support for the current export // for example, .tab doesn't export preferred html format continue; // go to next field } if (i < NS_ARRAY_LENGTH(EXPORT_ATTRIBUTES_TABLE) - 1) { rv = outputStream->Write(aDelim, aDelimLen, &writeCount); NS_ENSURE_SUCCESS(rv,rv); if (aDelimLen != writeCount) return NS_ERROR_FAILURE; } } // write out the linebreak that separates the cards rv = outputStream->Write(MSG_LINEBREAK, MSG_LINEBREAK_LEN, &writeCount); NS_ENSURE_SUCCESS(rv,rv); if (MSG_LINEBREAK_LEN != writeCount) return NS_ERROR_FAILURE; } } } } rv = outputStream->Flush(); NS_ENSURE_SUCCESS(rv,rv); rv = outputStream->Close(); NS_ENSURE_SUCCESS(rv,rv); return NS_OK; }
// 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); }
nsresult nsMsgFilterList::LoadTextFilters(nsIInputStream *aStream) { nsresult err = NS_OK; uint64_t bytesAvailable; nsCOMPtr<nsIInputStream> bufStream; err = NS_NewBufferedInputStream(getter_AddRefs(bufStream), aStream, 10240); NS_ENSURE_SUCCESS(err, err); nsMsgFilterFileAttribValue attrib; nsCOMPtr<nsIMsgRuleAction> currentFilterAction; // We'd really like to move lot's of these into the objects that they refer to. do { nsAutoCString value; nsresult intToStringResult; char curChar; curChar = LoadAttrib(attrib, bufStream); if (curChar == (char) -1) //reached eof break; err = LoadValue(value, bufStream); if (NS_FAILED(err)) break; switch(attrib) { case nsIMsgFilterList::attribNone: if (m_curFilter) m_curFilter->SetUnparseable(true); break; case nsIMsgFilterList::attribVersion: m_fileVersion = value.ToInteger(&intToStringResult); if (NS_FAILED(intToStringResult)) { attrib = nsIMsgFilterList::attribNone; NS_ASSERTION(false, "error parsing filter file version"); } break; case nsIMsgFilterList::attribLogging: m_loggingEnabled = StrToBool(value); m_unparsedFilterBuffer.Truncate(); //we are going to buffer each filter as we read them, make sure no garbage is there m_startWritingToBuffer = true; //filters begin now break; case nsIMsgFilterList::attribName: //every filter starts w/ a name { if (m_curFilter) { int32_t nextFilterStartPos = m_unparsedFilterBuffer.RFind("name"); nsAutoCString nextFilterPart; nextFilterPart = Substring(m_unparsedFilterBuffer, nextFilterStartPos, m_unparsedFilterBuffer.Length()); m_unparsedFilterBuffer.SetLength(nextFilterStartPos); bool unparseableFilter; m_curFilter->GetUnparseable(&unparseableFilter); if (unparseableFilter) { m_curFilter->SetUnparsedBuffer(m_unparsedFilterBuffer); m_curFilter->SetEnabled(false); //disable the filter because we don't know how to apply it } m_unparsedFilterBuffer = nextFilterPart; } nsMsgFilter *filter = new nsMsgFilter; if (filter == nullptr) { err = NS_ERROR_OUT_OF_MEMORY; break; } filter->SetFilterList(static_cast<nsIMsgFilterList*>(this)); if (m_fileVersion == k45Version) { nsAutoString unicodeStr; err = nsMsgI18NConvertToUnicode(nsMsgI18NFileSystemCharset(), value, unicodeStr); if (NS_FAILED(err)) break; filter->SetFilterName(unicodeStr); } else { // ### fix me - this is silly. PRUnichar *unicodeString = nsTextFormatter::smprintf(unicodeFormatter, value.get()); filter->SetFilterName(nsDependentString(unicodeString)); nsTextFormatter::smprintf_free(unicodeString); } m_curFilter = filter; m_filters.AppendElement(filter); } break; case nsIMsgFilterList::attribEnabled: if (m_curFilter) m_curFilter->SetEnabled(StrToBool(value)); break; case nsIMsgFilterList::attribDescription: if (m_curFilter) m_curFilter->SetFilterDesc(value); break; case nsIMsgFilterList::attribType: if (m_curFilter) { // Older versions of filters didn't have the ability to turn on/off the // manual filter context, so default manual to be on in that case int32_t filterType = value.ToInteger(&intToStringResult); if (m_fileVersion < kManualContextVersion) filterType |= nsMsgFilterType::Manual; m_curFilter->SetType((nsMsgFilterTypeType) filterType); } break; case nsIMsgFilterList::attribScriptFile: if (m_curFilter) m_curFilter->SetFilterScript(&value); break; case nsIMsgFilterList::attribAction: if (m_curFilter) { nsMsgRuleActionType actionType = nsMsgFilter::GetActionForFilingStr(value); if (actionType == nsMsgFilterAction::None) m_curFilter->SetUnparseable(true); else { err = m_curFilter->CreateAction(getter_AddRefs(currentFilterAction)); NS_ENSURE_SUCCESS(err, err); currentFilterAction->SetType(actionType); m_curFilter->AppendAction(currentFilterAction); } } break; case nsIMsgFilterList::attribActionValue: if (m_curFilter && currentFilterAction) { nsMsgRuleActionType type; currentFilterAction->GetType(&type); if (type == nsMsgFilterAction::MoveToFolder || type == nsMsgFilterAction::CopyToFolder) err = m_curFilter->ConvertMoveOrCopyToFolderValue(currentFilterAction, value); else if (type == nsMsgFilterAction::ChangePriority) { nsMsgPriorityValue outPriority; nsresult res = NS_MsgGetPriorityFromString(value.get(), outPriority); if (NS_SUCCEEDED(res)) currentFilterAction->SetPriority(outPriority); else NS_ASSERTION(false, "invalid priority in filter file"); } else if (type == nsMsgFilterAction::Label) { // upgrade label to corresponding tag/keyword nsresult res; int32_t labelInt = value.ToInteger(&res); if (NS_SUCCEEDED(res)) { nsAutoCString keyword("$label"); keyword.Append('0' + labelInt); currentFilterAction->SetType(nsMsgFilterAction::AddTag); currentFilterAction->SetStrValue(keyword); } } else if (type == nsMsgFilterAction::JunkScore) { nsresult res; int32_t junkScore = value.ToInteger(&res); if (NS_SUCCEEDED(res)) currentFilterAction->SetJunkScore(junkScore); } else if (type == nsMsgFilterAction::Forward || type == nsMsgFilterAction::Reply || type == nsMsgFilterAction::AddTag || type == nsMsgFilterAction::Custom) { currentFilterAction->SetStrValue(value); } } break; case nsIMsgFilterList::attribCondition: if (m_curFilter) { if (m_fileVersion == k45Version) { nsAutoString unicodeStr; err = nsMsgI18NConvertToUnicode(nsMsgI18NFileSystemCharset(), value, unicodeStr); if (NS_FAILED(err)) break; char *utf8 = ToNewUTF8String(unicodeStr); value.Assign(utf8); nsMemory::Free(utf8); } err = ParseCondition(m_curFilter, value.get()); if (err == NS_ERROR_INVALID_ARG) err = m_curFilter->SetUnparseable(true); NS_ENSURE_SUCCESS(err, err); } break; case nsIMsgFilterList::attribCustomId: if (m_curFilter && currentFilterAction) { err = currentFilterAction->SetCustomId(value); NS_ENSURE_SUCCESS(err, err); } break; } } while (NS_SUCCEEDED(bufStream->Available(&bytesAvailable))); if (m_curFilter) { bool unparseableFilter; m_curFilter->GetUnparseable(&unparseableFilter); if (unparseableFilter) { m_curFilter->SetUnparsedBuffer(m_unparsedFilterBuffer); m_curFilter->SetEnabled(false); //disable the filter because we don't know how to apply it } } return err; }
// 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; }
bool CMapiMessage::FetchBody(void) { m_bodyIsHtml = false; m_body.Truncate(); // Get the Outlook codepage info; if unsuccessful then it defaults to 0 (CP_ACP) -> system default // Maybe we can use this info later? unsigned int codepage=0; LPSPropValue pVal = CMapiApi::GetMapiProperty(m_lpMsg, PR_INTERNET_CPID); if (pVal) { if (PROP_TYPE(pVal->ulPropTag) == PT_LONG) codepage = pVal->Value.l; CMapiApi::MAPIFreeBuffer(pVal); } unsigned long nativeBodyType = 0; if (CMapiApi::GetRTFPropertyDecodedAsUTF16(m_lpMsg, m_body, nativeBodyType, codepage)) { m_bodyIsHtml = nativeBodyType == MAPI_NATIVE_BODY_TYPE_HTML; } else { // Cannot get RTF version // Is it html? pVal = CMapiApi::GetMapiProperty(m_lpMsg, PR_BODY_HTML_W); if (pVal) { if (CMapiApi::IsLargeProperty(pVal)) CMapiApi::GetLargeStringProperty(m_lpMsg, PR_BODY_HTML_W, m_body); else if ((PROP_TYPE(pVal->ulPropTag) == PT_UNICODE) && (pVal->Value.lpszW) && (*(pVal->Value.lpszW))) m_body.Assign(pVal->Value.lpszW); CMapiApi::MAPIFreeBuffer(pVal); } // Kind-hearted Outlook will give us html even for a plain text message. // But it will include a comment saying it did the conversion. // We'll use this as a hack to really use the plain text part. // // Sadly there are cases where this string is returned despite the fact // that the message is indeed HTML. // // To detect the "true" plain text messages, we look for our string // immediately following the <BODY> tag. if (!m_body.IsEmpty() && m_body.Find("<BODY>\r\n<!-- Converted from text/plain format -->") == kNotFound) { m_bodyIsHtml = true; } else { pVal = CMapiApi::GetMapiProperty(m_lpMsg, PR_BODY_W); if (pVal) { if (CMapiApi::IsLargeProperty(pVal)) CMapiApi::GetLargeStringProperty(m_lpMsg, PR_BODY_W, m_body); else if ((PROP_TYPE(pVal->ulPropTag) == PT_UNICODE) && (pVal->Value.lpszW) && (*(pVal->Value.lpszW))) m_body.Assign(pVal->Value.lpszW); CMapiApi::MAPIFreeBuffer(pVal); } } } // OK, now let's restore the original encoding! // 1. We may have a header defining the charset (we already called the FetchHeaders(), and there ProcessHeaders(); // in this case, the m_mimeCharset is set. See nsOutlookMail::ImportMailbox()) // 2. We may have the codepage walue provided by Outlook ("codepage" at the very beginning of this function) // 3. We may have an HTML charset header. bool bFoundCharset = false; if (!m_mimeCharset.IsEmpty()) // The top-level header data bFoundCharset = CheckBodyInCharsetRange(m_mimeCharset.get()); // No valid charset in the message header - try the HTML header. // arguably may be useless if (!bFoundCharset && m_bodyIsHtml) { ExtractMetaCharset(m_body.get(), m_body.Length(), m_mimeCharset); if (!m_mimeCharset.IsEmpty()) bFoundCharset = CheckBodyInCharsetRange(m_mimeCharset.get()); } // Get from Outlook (seems like it keeps the MIME part header encoding info) if (!bFoundCharset && codepage) { const char* charset = CpToCharset(codepage); if (charset) { bFoundCharset = CheckBodyInCharsetRange(charset); if (bFoundCharset) m_mimeCharset.Assign(charset); } } if (!bFoundCharset) { // Use system default const char* charset = nsMsgI18NFileSystemCharset(); if (charset) { bFoundCharset = CheckBodyInCharsetRange(charset); if (bFoundCharset) m_mimeCharset.Assign(charset); } } if (!bFoundCharset) // Everything else failed, let's use the lossless utf-8... m_mimeCharset.Assign("utf-8"); MAPI_DUMP_STRING(m_body.get()); MAPI_TRACE0("\r\n"); return true; }
nsresult nsOutlookMail::ImportMailbox( PRUint32 *pDoneSoFar, PRBool *pAbort, PRInt32 index, const PRUnichar *pName, nsIFile *pDest, PRInt32 *pMsgCount) { if ((index < 0) || (index >= m_folderList.GetSize())) { IMPORT_LOG0( "*** Bad mailbox identifier, unable to import\n"); *pAbort = PR_TRUE; return( NS_ERROR_FAILURE); } PRInt32 dummyMsgCount = 0; if (pMsgCount) *pMsgCount = 0; else pMsgCount = &dummyMsgCount; CMapiFolder *pFolder = m_folderList.GetItem( index); OpenMessageStore( pFolder); if (!m_lpMdb) { IMPORT_LOG1( "*** Unable to obtain mapi message store for mailbox: %S\n", pName); return( NS_ERROR_FAILURE); } if (pFolder->IsStore()) return( NS_OK); nsresult rv; nsOutlookCompose compose; SimpleBufferTonyRCopiedTwice copy; copy.Allocate( kCopyBufferSize); // now what? CMapiFolderContents contents( m_lpMdb, pFolder->GetCBEntryID(), pFolder->GetEntryID()); BOOL done = FALSE; ULONG cbEid; LPENTRYID lpEid; ULONG oType; LPMESSAGE lpMsg = nsnull; int attachCount; ULONG totalCount; PRFloat64 doneCalc; nsCString fromLine; int fromLen; PRBool lostAttach = PR_FALSE; nsCOMPtr<nsIOutputStream> destOutputStream; rv = NS_NewLocalFileOutputStream(getter_AddRefs(destOutputStream), pDest, -1, 0600); NS_ENSURE_SUCCESS(rv, rv); while (!done) { if (!contents.GetNext( &cbEid, &lpEid, &oType, &done)) { IMPORT_LOG1( "*** Error iterating mailbox: %S\n", pName); return( NS_ERROR_FAILURE); } totalCount = contents.GetCount(); doneCalc = *pMsgCount; doneCalc /= totalCount; doneCalc *= 1000; if (pDoneSoFar) { *pDoneSoFar = (PRUint32) doneCalc; if (*pDoneSoFar > 1000) *pDoneSoFar = 1000; } if (!done && (oType == MAPI_MESSAGE)) { if (!m_mapi.OpenMdbEntry( m_lpMdb, cbEid, lpEid, (LPUNKNOWN *) &lpMsg)) { IMPORT_LOG1( "*** Error opening messages in mailbox: %S\n", pName); return( NS_ERROR_FAILURE); } CMapiMessage msg( lpMsg); BOOL bResult = msg.FetchHeaders(); if (bResult) bResult = msg.FetchBody(); if (bResult) fromLine = msg.GetFromLine( fromLen); attachCount = msg.CountAttachments(); BuildAttachments( msg, attachCount); if (!bResult) { IMPORT_LOG1( "*** Error reading message from mailbox: %S\n", pName); return( NS_ERROR_FAILURE); } // -------------------------------------------------------------- compose.SetBody( msg.GetBody()); // Need to convert all headers to unicode (for i18n). // Init header here since 'composes' is used for all msgs. compose.SetHeaders(""); nsAutoString newheader; nsCAutoString tempCStr(msg.GetHeaders(), msg.GetHeaderLen()); rv = nsMsgI18NConvertToUnicode(nsMsgI18NFileSystemCharset(), tempCStr, newheader); NS_ASSERTION(NS_SUCCEEDED(rv), "failed to convert headers to utf8"); if (NS_SUCCEEDED(rv)) compose.SetHeaders(NS_ConvertUTF16toUTF8(newheader).get()); compose.SetAttachments( &m_attachments); // See if it's a drafts folder. Outlook doesn't allow drafts // folder to be configured so it's ok to hard code it here. nsAutoString folderName(pName); nsMsgDeliverMode mode = nsIMsgSend::nsMsgDeliverNow; mode = nsIMsgSend::nsMsgSaveAsDraft; if ( folderName.LowerCaseEqualsLiteral("drafts") ) mode = nsIMsgSend::nsMsgSaveAsDraft; /* If I can't get no headers, I can't get no satisfaction */ if (msg.GetHeaderLen()) { nsCAutoString cType; SetDefaultContentType(msg, cType); nsCOMPtr<nsIFile> compositionFile; rv = compose.SendTheMessage(mode, cType, getter_AddRefs(compositionFile)); if (NS_SUCCEEDED( rv)) { rv = compose.CopyComposedMessage( fromLine, compositionFile, destOutputStream, copy); DeleteFile( compositionFile); if (NS_FAILED( rv)) { IMPORT_LOG0( "*** Error copying composed message to destination mailbox\n"); return( rv); } (*pMsgCount)++; } } else rv = NS_OK; // The following code to write msg to folder when compose.SendTheMessage() fails is commented // out for now because the code doesn't handle attachments and users will complain anyway so // until we fix the code to handle all kinds of msgs correctly we should not even make users // think that all msgs are imported ok. This will also help users to identify which msgs are // not imported and help to debug the problem. #if 0 if (NS_FAILED( rv)) { /* NS_PRECONDITION( FALSE, "Manual breakpoint"); */ IMPORT_LOG1( "Message #%d failed.\n", (int) (*pMsgCount)); DumpAttachments(); // -------------------------------------------------------------- // This is the OLD way of writing out the message which uses // all kinds of crufty old crap for attachments. // Since we now use Compose to send attachments, // this is only fallback error stuff. // Attachments get lost. if (attachCount) { lostAttach = PR_TRUE; attachCount = 0; } BOOL needsTerminate = FALSE; if (!WriteMessage( destOutputStream, &msg, attachCount, &needsTerminate)) { IMPORT_LOG0( "*** Error writing message\n"); *pAbort = PR_TRUE; return( NS_ERROR_FAILURE); } if (needsTerminate) { if (!WriteMimeBoundary( destOutputStream, &msg, TRUE)) { IMPORT_LOG0( "*** Error writing message mime boundary\n"); *pAbort = PR_TRUE; return( NS_ERROR_FAILURE); } } } #endif // Just for YUCKS, let's try an extra endline WriteData( destOutputStream, "\x0D\x0A", 2); } } return( NS_OK); }