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; }
void CMapiMessageHeaders::CHeaderField::GetUnfoldedString(nsString& dest, const char* fallbackCharset) const { dest.Truncate(); if (!m_fbody) return; nsCString unfolded; const char* pos = m_fbody; while (*pos) { if ((*pos == nsCRT::CR) && (*(pos+1) == nsCRT::LF) && IsWSP(*(pos+2))) pos += 2; // Skip CRLF if it is followed by SPACE or TAB else unfolded.Append(*(pos++)); } if (m_fbody_utf8) CopyUTF8toUTF16(unfolded, dest); else nsMsgI18NConvertToUnicode(fallbackCharset, unfolded, dest); }
static int MimeInlineTextPlainFlowed_parse_line (const char *aLine, PRInt32 length, MimeObject *obj) { int status; PRBool quoting = ( obj->options && ( obj->options->format_out == nsMimeOutput::nsMimeMessageQuoting || obj->options->format_out == nsMimeOutput::nsMimeMessageBodyQuoting ) ); // see above PRBool plainHTML = quoting || (obj->options && obj->options->format_out == nsMimeOutput::nsMimeMessageSaveAs); // see above struct MimeInlineTextPlainFlowedExData *exdata; exdata = MimeInlineTextPlainFlowedExDataList; while(exdata && (exdata->ownerobj != obj)) { exdata = exdata->next; } NS_ASSERTION(exdata, "The extra data has disappeared!"); NS_ASSERTION(length > 0, "zero length"); if (length <= 0) return 0; uint32 linequotelevel = 0; nsCAutoString real_line(aLine, length); char *line = real_line.BeginWriting(); const char *linep = real_line.BeginReading(); // Space stuffed? if(' ' == *linep) { linep++; } else { // count '>':s before the first non-'>' while('>' == *linep) { linep++; linequotelevel++; } // Space stuffed? if(' ' == *linep) { linep++; } } // Look if the last character (after stripping ending end // of lines and quoting stuff) is a SPACE. If it is, we are looking at a // flowed line. Normally we assume that the last two chars // are CR and LF as said in RFC822, but that doesn't seem to // be the case always. PRBool flowed = PR_FALSE; PRBool sigSeparator = PR_FALSE; PRInt32 index = length-1; while(index >= 0 && ('\r' == line[index] || '\n' == line[index])) { index--; } if (index > linep - line && ' ' == line[index]) /* Ignore space stuffing, i.e. lines with just (quote marks and) a space count as empty */ { flowed = PR_TRUE; sigSeparator = (index - (linep - line) + 1 == 3) && !strncmp(linep, "-- ", 3); if (((MimeInlineTextPlainFlowed *) obj)->delSp && ! sigSeparator) /* If line is flowed and DelSp=yes, logically delete trailing space. Line consisting of dash dash space ("-- "), commonly used as signature separator, gets special handling (RFC 3676) */ { length--; line[index] = '\0'; } } mozITXTToHTMLConv *conv = GetTextConverter(obj->options); PRBool skipConversion = !conv || (obj->options && obj->options->force_user_charset); nsAutoString lineSource; nsString lineResult; char *mailCharset = NULL; nsresult rv; if (!skipConversion) { // Convert only if the source string is not empty if (length - (linep - line) > 0) { PRBool whattodo = obj->options->whattodo; if (plainHTML) { if (quoting) whattodo = 0; else whattodo = whattodo & ~mozITXTToHTMLConv::kGlyphSubstitution; /* Do recognition for the case, the result is viewed in Mozilla, but not GlyphSubstitution, because other UAs might not be able to display the glyphs. */ } const nsDependentCSubstring& inputStr = Substring(linep, linep + (length - (linep - line))); // For 'SaveAs', |line| is in |mailCharset|. // convert |line| to UTF-16 before 'html'izing (calling ScanTXT()) if (obj->options->format_out == nsMimeOutput::nsMimeMessageSaveAs) { // Get the mail charset of this message. MimeInlineText *inlinetext = (MimeInlineText *) obj; if (!inlinetext->initializeCharset) ((MimeInlineTextClass*)&mimeInlineTextClass)->initialize_charset(obj); mailCharset = inlinetext->charset; if (mailCharset && *mailCharset) { rv = nsMsgI18NConvertToUnicode(mailCharset, PromiseFlatCString(inputStr), lineSource); NS_ENSURE_SUCCESS(rv, -1); } else // this probably never happens... CopyUTF8toUTF16(inputStr, lineSource); } else // line is in UTF-8 CopyUTF8toUTF16(inputStr, lineSource); // This is the main TXT to HTML conversion: // escaping (very important), eventually recognizing etc. rv = conv->ScanTXT(lineSource.get(), whattodo, getter_Copies(lineResult)); NS_ENSURE_SUCCESS(rv, -1); } } else { CopyUTF8toUTF16(nsDependentCString(line, length), lineResult); status = NS_OK; } nsCAutoString preface; /* Correct number of blockquotes */ int32 quoteleveldiff=linequotelevel - exdata->quotelevel; if((quoteleveldiff != 0) && flowed && exdata->inflow) { // From RFC 2646 4.5 // The receiver SHOULD handle this error by using the 'quote-depth-wins' rule, // which is to ignore the flowed indicator and treat the line as fixed. That // is, the change in quote depth ends the paragraph. // We get that behaviour by just going on. } while(quoteleveldiff>0) { quoteleveldiff--; preface += "<blockquote type=cite"; // This is to have us observe the user pref settings for citations MimeInlineTextPlainFlowed *tObj = (MimeInlineTextPlainFlowed *) obj; nsCAutoString style; MimeTextBuildPrefixCSS(tObj->mQuotedSizeSetting, tObj->mQuotedStyleSetting, tObj->mCitationColor, style); if (!plainHTML && !style.IsEmpty()) { preface += " style=\""; preface += style; preface += '"'; } preface += '>'; } while(quoteleveldiff<0) { quoteleveldiff++; preface += "</blockquote>"; } exdata->quotelevel = linequotelevel; nsAutoString lineResult2; if(flowed) { // Check RFC 2646 "4.3. Usenet Signature Convention": "-- "+CRLF is // not a flowed line if (sigSeparator) { if (linequotelevel > 0 || exdata->isSig) { preface += "-- <br>"; } else { exdata->isSig = PR_TRUE; preface += "<div class=\"moz-txt-sig\"><span class=\"moz-txt-tag\">" "-- <br></span>"; } } else { Line_convert_whitespace(lineResult, PR_FALSE /* Allow wraps */, lineResult2); } exdata->inflow=PR_TRUE; } else { // Fixed paragraph. Line_convert_whitespace(lineResult, !plainHTML && !obj->options->wrap_long_lines_p /* If wrap, convert all spaces but the last in a row into nbsp, otherwise all. */, lineResult2); lineResult2.AppendLiteral("<br>"); exdata->inflow = PR_FALSE; } // End Fixed line if (!(exdata->isSig && quoting)) { status = MimeObject_write(obj, preface.get(), preface.Length(), PR_TRUE); if (status < 0) return status; nsCAutoString outString; if (obj->options->format_out != nsMimeOutput::nsMimeMessageSaveAs || !mailCharset || !*mailCharset) CopyUTF16toUTF8(lineResult2, outString); else { // convert back to mailCharset before writing. rv = nsMsgI18NConvertFromUnicode(mailCharset, lineResult2, outString); NS_ENSURE_SUCCESS(rv, -1); } status = MimeObject_write(obj, outString.get(), outString.Length(), PR_TRUE); return status; } else return NS_OK; }
static int MimeInlineTextPlain_parse_line (char *line, PRInt32 length, MimeObject *obj) { int status; PRBool quoting = ( obj->options && ( obj->options->format_out == nsMimeOutput::nsMimeMessageQuoting || obj->options->format_out == nsMimeOutput::nsMimeMessageBodyQuoting ) ); // see above PRBool plainHTML = quoting || (obj->options && obj->options->format_out == nsMimeOutput::nsMimeMessageSaveAs); // see above PRBool rawPlainText = obj->options && (obj->options->format_out == nsMimeOutput::nsMimeMessageFilterSniffer || obj->options->format_out == nsMimeOutput::nsMimeMessageAttach); // this routine gets called for every line of data that comes through the // mime converter. It's important to make sure we are efficient with // how we allocate memory in this routine. be careful if you go to add // more to this routine. NS_ASSERTION(length > 0, "zero length"); if (length <= 0) return 0; mozITXTToHTMLConv *conv = GetTextConverter(obj->options); MimeInlineTextPlain *text = (MimeInlineTextPlain *) obj; PRBool skipConversion = !conv || rawPlainText || (obj->options && obj->options->force_user_charset); char *mailCharset = NULL; nsresult rv; // if this part has a name and it's not a message/rfc822, don't quote if (quoting && obj->headers && MimeHeaders_get_name(obj->headers, obj->options) && PL_strcasecmp(obj->content_type, MESSAGE_RFC822)) return 0; if (!skipConversion) { nsDependentCString inputStr(line, length); nsAutoString lineSourceStr; // For 'SaveAs', |line| is in |mailCharset|. // convert |line| to UTF-16 before 'html'izing (calling ScanTXT()) if (obj->options->format_out == nsMimeOutput::nsMimeMessageSaveAs) { // Get the mail charset of this message. MimeInlineText *inlinetext = (MimeInlineText *) obj; if (!inlinetext->initializeCharset) ((MimeInlineTextClass*)&mimeInlineTextClass)->initialize_charset(obj); mailCharset = inlinetext->charset; if (mailCharset && *mailCharset) { rv = nsMsgI18NConvertToUnicode(mailCharset, inputStr, lineSourceStr); NS_ENSURE_SUCCESS(rv, -1); } else // this probably never happens ... CopyUTF8toUTF16(inputStr, lineSourceStr); } else // line is in UTF-8 CopyUTF8toUTF16(inputStr, lineSourceStr); nsCAutoString prefaceResultStr; // Quoting stuff before the real text // Recognize quotes PRUint32 oldCiteLevel = text->mCiteLevel; PRUint32 logicalLineStart = 0; rv = conv->CiteLevelTXT(lineSourceStr.get(), &logicalLineStart, &(text->mCiteLevel)); NS_ENSURE_SUCCESS(rv, -1); // Find out, which recognitions to do PRBool whattodo = obj->options->whattodo; if (plainHTML) { if (quoting) whattodo = 0; // This is done on Send. Don't do it twice. else whattodo = whattodo & ~mozITXTToHTMLConv::kGlyphSubstitution; /* Do recognition for the case, the result is viewed in Mozilla, but not GlyphSubstitution, because other UAs might not be able to display the glyphs. */ if (!text->mBlockquoting) text->mCiteLevel = 0; } // Write blockquote if (text->mCiteLevel > oldCiteLevel) { prefaceResultStr += "</pre>"; for (PRUint32 i = 0; i < text->mCiteLevel - oldCiteLevel; i++) { nsCAutoString style; MimeTextBuildPrefixCSS(text->mQuotedSizeSetting, text->mQuotedStyleSetting, text->mCitationColor, style); if (!plainHTML && !style.IsEmpty()) { prefaceResultStr += "<blockquote type=cite style=\""; prefaceResultStr += style; prefaceResultStr += "\">"; } else prefaceResultStr += "<blockquote type=cite>"; } prefaceResultStr += "<pre wrap>"; } else if (text->mCiteLevel < oldCiteLevel) { prefaceResultStr += "</pre>"; for (PRUint32 i = 0; i < oldCiteLevel - text->mCiteLevel; i++) prefaceResultStr += "</blockquote>"; prefaceResultStr += "<pre wrap>"; if (text->mCiteLevel == 0) prefaceResultStr += "<!---->"; /* Make sure, NGLayout puts out a linebreak */ } // Write plain text quoting tags if (logicalLineStart != 0 && !(plainHTML && text->mBlockquoting)) { if (!plainHTML) prefaceResultStr += "<span class=\"moz-txt-citetags\">"; nsAutoString citeTagsSource; lineSourceStr.Mid(citeTagsSource, 0, logicalLineStart); // Convert to HTML nsXPIDLString citeTagsResultUnichar; rv = conv->ScanTXT(citeTagsSource.get(), 0 /* no recognition */, getter_Copies(citeTagsResultUnichar)); if (NS_FAILED(rv)) return -1; AppendUTF16toUTF8(citeTagsResultUnichar, prefaceResultStr); if (!plainHTML) prefaceResultStr += "</span>"; } // recognize signature if ((lineSourceStr.Length() >= 4) && lineSourceStr.First() == '-' && Substring(lineSourceStr, 0, 3).EqualsLiteral("-- ") && (lineSourceStr[3] == '\r' || lineSourceStr[3] == '\n') ) { text->mIsSig = PR_TRUE; if (!quoting) prefaceResultStr += "<div class=\"moz-txt-sig\">"; } /* This is the main TXT to HTML conversion: escaping (very important), eventually recognizing etc. */ nsXPIDLString lineResultUnichar; rv = conv->ScanTXT(lineSourceStr.get() + logicalLineStart, whattodo, getter_Copies(lineResultUnichar)); NS_ENSURE_SUCCESS(rv, -1); if (!(text->mIsSig && quoting)) { status = MimeObject_write(obj, prefaceResultStr.get(), prefaceResultStr.Length(), PR_TRUE); if (status < 0) return status; nsCAutoString outString; if (obj->options->format_out != nsMimeOutput::nsMimeMessageSaveAs || !mailCharset || !*mailCharset) CopyUTF16toUTF8(lineResultUnichar, outString); else { // convert back to mailCharset before writing. rv = nsMsgI18NConvertFromUnicode(mailCharset, lineResultUnichar, outString); NS_ENSURE_SUCCESS(rv, -1); } status = MimeObject_write(obj, outString.get(), outString.Length(), PR_TRUE); } else { status = NS_OK; } } else { status = MimeObject_write(obj, line, length, PR_TRUE); } return status; }
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 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; }
static int MimeMessage_close_headers (MimeObject *obj) { MimeMessage *msg = (MimeMessage *) obj; int status = 0; char *ct = 0; /* Content-Type header */ MimeObject *body; // Do a proper decoding of the munged subject. if (obj->headers && msg->hdrs && msg->grabSubject && obj->headers->munged_subject) { // nsMsgI18NConvertToUnicode wants nsAStrings... nsDependentCString orig(obj->headers->munged_subject); nsAutoString dest; // First, get the Content-Type, then extract the charset="whatever" part of // it. nsCString charset; nsCString contentType; contentType.Adopt(MimeHeaders_get(msg->hdrs, HEADER_CONTENT_TYPE, false, false)); if (!contentType.IsEmpty()) charset.Adopt(MimeHeaders_get_parameter(contentType.get(), "charset", nullptr, nullptr)); // If we've got a charset, use nsMsgI18NConvertToUnicode to magically decode // the munged subject. if (!charset.IsEmpty()) { nsresult rv = nsMsgI18NConvertToUnicode(charset.get(), orig, dest); // If we managed to convert the string, replace munged_subject with the // UTF8 version of it, otherwise, just forget about it (maybe there was an // improperly encoded string in there). PR_Free(obj->headers->munged_subject); if (NS_SUCCEEDED(rv)) obj->headers->munged_subject = ToNewUTF8String(dest); else obj->headers->munged_subject = nullptr; } else { PR_Free(obj->headers->munged_subject); obj->headers->munged_subject = nullptr; } } if (msg->hdrs) { bool outer_p = !obj->headers; /* is this the outermost message? */ #ifdef MIME_DRAFTS if (outer_p && obj->options && (obj->options->decompose_file_p || obj->options->caller_need_root_headers) && obj->options->decompose_headers_info_fn) { #ifdef ENABLE_SMIME if (obj->options->decrypt_p && !mime_crypto_object_p (msg->hdrs, false)) obj->options->decrypt_p = false; #endif /* ENABLE_SMIME */ if (!obj->options->caller_need_root_headers || (obj == obj->options->state->root)) status = obj->options->decompose_headers_info_fn ( obj->options->stream_closure, msg->hdrs ); } #endif /* MIME_DRAFTS */ /* If this is the outermost message, we need to run the `generate_header' callback. This happens here instead of in `parse_begin', because it's only now that we've parsed our headers. However, since this is the outermost message, we have yet to write any HTML, so that's fine. */ if (outer_p && obj->output_p && obj->options && obj->options->write_html_p && obj->options->generate_header_html_fn) { int lstatus = 0; char *html = 0; /* The generate_header_html_fn might return HTML, so it's important that the output stream be set up with the proper type before we make the MimeObject_write() call below. */ if (!obj->options->state->first_data_written_p) { lstatus = MimeObject_output_init (obj, TEXT_HTML); if (lstatus < 0) return lstatus; PR_ASSERT(obj->options->state->first_data_written_p); } html = obj->options->generate_header_html_fn(NULL, obj->options->html_closure, msg->hdrs); if (html) { lstatus = MimeObject_write(obj, html, strlen(html), false); PR_Free(html); if (lstatus < 0) return lstatus; } } /* Find the content-type of the body of this message. */ { bool ok = true; char *mv = MimeHeaders_get (msg->hdrs, HEADER_MIME_VERSION, true, false); #ifdef REQUIRE_MIME_VERSION_HEADER /* If this is the outermost message, it must have a MIME-Version header with the value 1.0 for us to believe what might be in the Content-Type header. If the MIME-Version header is not present, we must treat this message as untyped. */ ok = (mv && !strcmp(mv, "1.0")); #else /* #### actually, we didn't check this in Mozilla 2.0, and checking it now could cause some compatibility nonsense, so for now, let's just believe any Content-Type header we see. */ ok = true; #endif if (ok) { ct = MimeHeaders_get (msg->hdrs, HEADER_CONTENT_TYPE, true, false); /* If there is no Content-Type header, but there is a MIME-Version header, then assume that this *is* in fact a MIME message. (I've seen messages with MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable and no Content-Type, and we should treat those as being of type MimeInlineTextPlain rather than MimeUntypedText.) */ if (mv && !ct) ct = strdup(TEXT_PLAIN); } PR_FREEIF(mv); /* done with this now. */ } /* If this message has a body which is encrypted and we're going to decrypt it (whithout converting it to HTML, since decrypt_p and write_html_p are never true at the same time) */ if (obj->output_p && obj->options && obj->options->decrypt_p #ifdef ENABLE_SMIME && !mime_crypto_object_p (msg->hdrs, false) #endif /* ENABLE_SMIME */ ) { /* The body of this message is not an encrypted object, so we need to turn off the decrypt_p flag (to prevent us from s#$%ing the body of the internal object up into one.) In this case, our output will end up being identical to our input. */ obj->options->decrypt_p = false; } /* Emit the HTML for this message's headers. Do this before creating the object representing the body. */ if (obj->output_p && obj->options && obj->options->write_html_p) { /* If citation headers are on, and this is not the outermost message, turn them off. */ if (obj->options->headers == MimeHeadersCitation && !outer_p) obj->options->headers = MimeHeadersSome; /* Emit a normal header block. */ status = MimeMessage_write_headers_html(obj); if (status < 0) return status; } else if (obj->output_p) { /* Dump the headers, raw. */ status = MimeObject_write(obj, "", 0, false); /* initialize */ if (status < 0) return status; status = MimeHeaders_write_raw_headers(msg->hdrs, obj->options, obj->options->decrypt_p); if (status < 0) return status; } #ifdef XP_UNIX if (outer_p && obj->output_p) /* Kludge from mimehdrs.c */ MimeHeaders_do_unix_display_hook_hack(msg->hdrs); #endif /* XP_UNIX */ } /* Never put out a separator after a message header block. */ if (obj->options && obj->options->state) obj->options->state->separator_suppressed_p = true; #ifdef MIME_DRAFTS if ( !obj->headers && /* outer most message header */ obj->options && obj->options->decompose_file_p && ct ) obj->options->is_multipart_msg = PL_strcasestr(ct, "multipart/") != NULL; #endif /* MIME_DRAFTS */ body = mime_create(ct, msg->hdrs, obj->options); PR_FREEIF(ct); if (!body) return MIME_OUT_OF_MEMORY; status = ((MimeContainerClass *) obj->clazz)->add_child (obj, body); if (status < 0) { mime_free(body); return status; } // Only do this if this is a Text Object! if ( mime_typep(body, (MimeObjectClass *) &mimeInlineTextClass) ) { ((MimeInlineText *) body)->needUpdateMsgWinCharset = true; } /* Now that we've added this new object to our list of children, start its parser going. */ status = body->clazz->parse_begin(body); if (status < 0) return status; // Now notify the emitter if this is the outer most message, unless // it is a part that is not the head of the message. If it's a part, // we need to figure out the content type/charset of the part // bool outer_p = !obj->headers; /* is this the outermost message? */ if ( (outer_p || obj->options->notify_nested_bodies) && (!obj->options->part_to_load || obj->options->format_out == nsMimeOutput::nsMimeMessageBodyDisplay)) { // call SetMailCharacterSetToMsgWindow() to set a menu charset if (mime_typep(body, (MimeObjectClass *) &mimeInlineTextClass)) { MimeInlineText *text = (MimeInlineText *) body; if (text && text->charset && *text->charset) SetMailCharacterSetToMsgWindow(body, text->charset); } char *msgID = MimeHeaders_get (msg->hdrs, HEADER_MESSAGE_ID, false, false); const char *outCharset = NULL; if (!obj->options->force_user_charset) /* Only convert if the user prefs is false */ outCharset = "UTF-8"; mimeEmitterStartBody(obj->options, (obj->options->headers == MimeHeadersNone), msgID, outCharset); PR_FREEIF(msgID); // setting up truncated message html fotter function char *xmoz = MimeHeaders_get(msg->hdrs, HEADER_X_MOZILLA_STATUS, false, false); if (xmoz) { uint32_t flags = 0; char dummy = 0; if (sscanf(xmoz, " %x %c", &flags, &dummy) == 1 && flags & nsMsgMessageFlags::Partial) { obj->options->html_closure = obj; obj->options->generate_footer_html_fn = MimeMessage_partial_message_html; } PR_FREEIF(xmoz); } } return 0; }
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); }