mirror of
https://repo.dactyloidae.xyz/Dactyloidae/UXP.git
synced 2026-09-23 00:47:31 +09:00
Issue #1751 -- Remove XP_MACOSX conditionals from the rest of the tree.
This also removes some PP abuse and takes file entries out of PP when no longer needed without XP_MACOSX conditionals.
This commit is contained in:
parent
02c59100a8
commit
a4b0f333ba
153 changed files with 173 additions and 4556 deletions
|
|
@ -1,14 +0,0 @@
|
|||
# This Source Code Form is subject to the terms of the Mozilla Public
|
||||
# License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
||||
SOURCES += [
|
||||
'nsAppleMailImport.cpp',
|
||||
]
|
||||
|
||||
SOURCES += [
|
||||
'nsEmlxHelperUtils.mm',
|
||||
]
|
||||
|
||||
FINAL_LIBRARY = 'import'
|
||||
|
||||
|
|
@ -1,623 +0,0 @@
|
|||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "nsStringGlue.h"
|
||||
#include "nsCOMPtr.h"
|
||||
#include "nsISupportsPrimitives.h"
|
||||
#include "nsIImportService.h"
|
||||
#include "nsIImportMailboxDescriptor.h"
|
||||
#include "nsIImportGeneric.h"
|
||||
#include "nsIFile.h"
|
||||
#include "nsIStringBundle.h"
|
||||
#include "nsIMsgFolder.h"
|
||||
#include "nsIMsgHdr.h"
|
||||
#include "nsIMsgPluggableStore.h"
|
||||
#include "nsIMutableArray.h"
|
||||
#include "nsNetUtil.h"
|
||||
#include "nsMsgUtils.h"
|
||||
#include "mozilla/Services.h"
|
||||
|
||||
#include "nsEmlxHelperUtils.h"
|
||||
#include "nsAppleMailImport.h"
|
||||
#include "nsIOutputStream.h"
|
||||
|
||||
PRLogModuleInfo *APPLEMAILLOGMODULE = nullptr;
|
||||
|
||||
// some hard-coded strings
|
||||
#define DEFAULT_MAIL_FOLDER "~/Library/Mail/"
|
||||
#define POP_MBOX_SUFFIX ".mbox"
|
||||
#define IMAP_MBOX_SUFFIX ".imapmbox"
|
||||
|
||||
// stringbundle URI
|
||||
#define APPLEMAIL_MSGS_URL "chrome://messenger/locale/appleMailImportMsgs.properties"
|
||||
|
||||
// magic constants
|
||||
#define kAccountMailboxID 1234
|
||||
|
||||
nsAppleMailImportModule::nsAppleMailImportModule()
|
||||
{
|
||||
// Init logging module.
|
||||
if (!APPLEMAILLOGMODULE)
|
||||
APPLEMAILLOGMODULE = PR_NewLogModule("APPLEMAILIMPORTLOG");
|
||||
|
||||
IMPORT_LOG0("nsAppleMailImportModule Created");
|
||||
|
||||
nsCOMPtr<nsIStringBundleService> bundleService =
|
||||
mozilla::services::GetStringBundleService();
|
||||
if (bundleService)
|
||||
bundleService->CreateBundle(APPLEMAIL_MSGS_URL, getter_AddRefs(mBundle));
|
||||
}
|
||||
|
||||
|
||||
nsAppleMailImportModule::~nsAppleMailImportModule()
|
||||
{
|
||||
IMPORT_LOG0("nsAppleMailImportModule Deleted");
|
||||
}
|
||||
|
||||
|
||||
NS_IMPL_ISUPPORTS(nsAppleMailImportModule, nsIImportModule)
|
||||
|
||||
|
||||
NS_IMETHODIMP nsAppleMailImportModule::GetName(char16_t **aName)
|
||||
{
|
||||
return mBundle ?
|
||||
mBundle->GetStringFromName(u"ApplemailImportName", aName) : NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsAppleMailImportModule::GetDescription(char16_t **aName)
|
||||
{
|
||||
return mBundle ?
|
||||
mBundle->GetStringFromName(u"ApplemailImportDescription", aName) : NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsAppleMailImportModule::GetSupports(char **aSupports)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(aSupports);
|
||||
*aSupports = strdup(NS_IMPORT_MAIL_STR);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsAppleMailImportModule::GetSupportsUpgrade(bool *aUpgrade)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(aUpgrade);
|
||||
*aUpgrade = false;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsAppleMailImportModule::GetImportInterface(const char *aImportType, nsISupports **aInterface)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(aImportType);
|
||||
NS_ENSURE_ARG_POINTER(aInterface);
|
||||
*aInterface = nullptr;
|
||||
nsresult rv = NS_ERROR_NOT_AVAILABLE;
|
||||
|
||||
if (!strcmp(aImportType, "mail")) {
|
||||
nsCOMPtr<nsIImportMail> mail(do_CreateInstance(NS_APPLEMAILIMPL_CONTRACTID, &rv));
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
nsCOMPtr<nsIImportService> impSvc(do_GetService(NS_IMPORTSERVICE_CONTRACTID, &rv));
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
nsCOMPtr<nsIImportGeneric> generic;
|
||||
rv = impSvc->CreateNewGenericMail(getter_AddRefs(generic));
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
nsAutoString name;
|
||||
rv = mBundle->GetStringFromName(u"ApplemailImportName", getter_Copies(name));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
nsCOMPtr<nsISupportsString> nameString(do_CreateInstance(NS_SUPPORTS_STRING_CONTRACTID, &rv));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
nameString->SetData(name);
|
||||
|
||||
generic->SetData("name", nameString);
|
||||
generic->SetData("mailInterface", mail);
|
||||
|
||||
generic.forget(aInterface);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
#pragma mark -
|
||||
|
||||
nsAppleMailImportMail::nsAppleMailImportMail() : mProgress(0), mCurDepth(0)
|
||||
{
|
||||
IMPORT_LOG0("nsAppleMailImportMail created");
|
||||
}
|
||||
|
||||
nsresult nsAppleMailImportMail::Initialize()
|
||||
{
|
||||
nsCOMPtr<nsIStringBundleService> bundleService =
|
||||
mozilla::services::GetStringBundleService();
|
||||
NS_ENSURE_TRUE(bundleService, NS_ERROR_UNEXPECTED);
|
||||
|
||||
return bundleService->CreateBundle(APPLEMAIL_MSGS_URL, getter_AddRefs(mBundle));
|
||||
}
|
||||
|
||||
nsAppleMailImportMail::~nsAppleMailImportMail()
|
||||
{
|
||||
IMPORT_LOG0("nsAppleMailImportMail destroyed");
|
||||
}
|
||||
|
||||
NS_IMPL_ISUPPORTS(nsAppleMailImportMail, nsIImportMail)
|
||||
|
||||
NS_IMETHODIMP nsAppleMailImportMail::GetDefaultLocation(nsIFile **aLocation, bool *aFound, bool *aUserVerify)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(aFound);
|
||||
NS_ENSURE_ARG_POINTER(aLocation);
|
||||
NS_ENSURE_ARG_POINTER(aUserVerify);
|
||||
|
||||
*aLocation = nullptr;
|
||||
*aFound = false;
|
||||
*aUserVerify = true;
|
||||
|
||||
// try to find current user's top-level Mail folder
|
||||
nsCOMPtr<nsIFile> mailFolder(do_CreateInstance(NS_LOCAL_FILE_CONTRACTID));
|
||||
if (mailFolder) {
|
||||
nsresult rv = mailFolder->InitWithNativePath(NS_LITERAL_CSTRING(DEFAULT_MAIL_FOLDER));
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
*aFound = true;
|
||||
*aUserVerify = false;
|
||||
mailFolder.forget(aLocation);
|
||||
}
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// this is the method that initiates all searching for mailboxes.
|
||||
// it will assume that it has a directory like ~/Library/Mail/
|
||||
NS_IMETHODIMP nsAppleMailImportMail::FindMailboxes(nsIFile *aMailboxFile, nsIArray **aResult)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(aMailboxFile);
|
||||
NS_ENSURE_ARG_POINTER(aResult);
|
||||
|
||||
IMPORT_LOG0("FindMailboxes for Apple mail invoked");
|
||||
|
||||
bool exists = false;
|
||||
nsresult rv = aMailboxFile->Exists(&exists);
|
||||
if (NS_FAILED(rv) || !exists)
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
nsCOMPtr<nsIImportService> importService(do_GetService(NS_IMPORTSERVICE_CONTRACTID, &rv));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
nsCOMPtr<nsIMutableArray> resultsArray(do_CreateInstance(NS_ARRAY_CONTRACTID, &rv));
|
||||
if (!resultsArray)
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
|
||||
mCurDepth = 1;
|
||||
|
||||
// 1. look for accounts with mailboxes
|
||||
FindAccountMailDirs(aMailboxFile, resultsArray, importService);
|
||||
mCurDepth--;
|
||||
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
// 2. look for "global" mailboxes, that don't belong to any specific account. they are inside the
|
||||
// root's Mailboxes/ folder
|
||||
nsCOMPtr<nsIFile> mailboxesDir(do_CreateInstance(NS_LOCAL_FILE_CONTRACTID, &rv));
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
mailboxesDir->InitWithFile(aMailboxFile);
|
||||
rv = mailboxesDir->Append(NS_LITERAL_STRING("Mailboxes"));
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
IMPORT_LOG0("Looking for global Apple mailboxes");
|
||||
|
||||
mCurDepth++;
|
||||
rv = FindMboxDirs(mailboxesDir, resultsArray, importService);
|
||||
mCurDepth--;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (NS_SUCCEEDED(rv) && resultsArray)
|
||||
resultsArray.forget(aResult);
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
// operates on the Mail/ directory root, trying to find accounts (which are folders named something like "POP-hwaara@gmail.com")
|
||||
// and add their .mbox dirs
|
||||
void nsAppleMailImportMail::FindAccountMailDirs(nsIFile *aRoot, nsIMutableArray *aMailboxDescs, nsIImportService *aImportService)
|
||||
{
|
||||
nsCOMPtr<nsISimpleEnumerator> directoryEnumerator;
|
||||
nsresult rv = aRoot->GetDirectoryEntries(getter_AddRefs(directoryEnumerator));
|
||||
if (NS_FAILED(rv))
|
||||
return;
|
||||
|
||||
bool hasMore = false;
|
||||
while (NS_SUCCEEDED(directoryEnumerator->HasMoreElements(&hasMore)) && hasMore) {
|
||||
|
||||
// get the next file entry
|
||||
nsCOMPtr<nsIFile> currentEntry;
|
||||
{
|
||||
nsCOMPtr<nsISupports> rawSupports;
|
||||
directoryEnumerator->GetNext(getter_AddRefs(rawSupports));
|
||||
if (!rawSupports)
|
||||
continue;
|
||||
currentEntry = do_QueryInterface(rawSupports);
|
||||
if (!currentEntry)
|
||||
continue;
|
||||
}
|
||||
|
||||
// make sure it's a directory
|
||||
bool isDirectory = false;
|
||||
currentEntry->IsDirectory(&isDirectory);
|
||||
|
||||
if (isDirectory) {
|
||||
// now let's see if it's an account folder. if so, we want to traverse it for .mbox children
|
||||
nsAutoString folderName;
|
||||
currentEntry->GetLeafName(folderName);
|
||||
bool isAccountFolder = false;
|
||||
|
||||
if (StringBeginsWith(folderName, NS_LITERAL_STRING("POP-"))) {
|
||||
// cut off "POP-" prefix so we get a nice folder name
|
||||
folderName.Cut(0, 4);
|
||||
isAccountFolder = true;
|
||||
}
|
||||
else if (StringBeginsWith(folderName, NS_LITERAL_STRING("IMAP-"))) {
|
||||
// cut off "IMAP-" prefix so we get a nice folder name
|
||||
folderName.Cut(0, 5);
|
||||
isAccountFolder = true;
|
||||
}
|
||||
|
||||
if (isAccountFolder) {
|
||||
IMPORT_LOG1("Found account: %s\n", NS_ConvertUTF16toUTF8(folderName).get());
|
||||
|
||||
// create a mailbox for this account, so we get a parent for "Inbox", "Sent Messages", etc.
|
||||
nsCOMPtr<nsIImportMailboxDescriptor> desc;
|
||||
nsresult rv = aImportService->CreateNewMailboxDescriptor(getter_AddRefs(desc));
|
||||
desc->SetSize(1);
|
||||
desc->SetDepth(mCurDepth);
|
||||
desc->SetDisplayName(folderName.get());
|
||||
desc->SetIdentifier(kAccountMailboxID);
|
||||
|
||||
nsCOMPtr<nsIFile> mailboxDescFile;
|
||||
rv = desc->GetFile(getter_AddRefs(mailboxDescFile));
|
||||
if (!mailboxDescFile)
|
||||
continue;
|
||||
|
||||
mailboxDescFile->InitWithFile(currentEntry);
|
||||
|
||||
// add this mailbox descriptor to the list
|
||||
aMailboxDescs->AppendElement(desc, false);
|
||||
|
||||
// now add all the children mailboxes
|
||||
mCurDepth++;
|
||||
FindMboxDirs(currentEntry, aMailboxDescs, aImportService);
|
||||
mCurDepth--;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// adds the specified file as a mailboxdescriptor to the array
|
||||
nsresult nsAppleMailImportMail::AddMboxDir(nsIFile *aFolder, nsIMutableArray *aMailboxDescs, nsIImportService *aImportService)
|
||||
{
|
||||
nsAutoString folderName;
|
||||
aFolder->GetLeafName(folderName);
|
||||
|
||||
// cut off the suffix, if any, or prefix if this is an account folder.
|
||||
if (StringEndsWith(folderName, NS_LITERAL_STRING(POP_MBOX_SUFFIX)))
|
||||
folderName.SetLength(folderName.Length()-5);
|
||||
else if (StringEndsWith(folderName, NS_LITERAL_STRING(IMAP_MBOX_SUFFIX)))
|
||||
folderName.SetLength(folderName.Length()-9);
|
||||
else if (StringBeginsWith(folderName, NS_LITERAL_STRING("POP-")))
|
||||
folderName.Cut(4, folderName.Length());
|
||||
else if (StringBeginsWith(folderName, NS_LITERAL_STRING("IMAP-")))
|
||||
folderName.Cut(5, folderName.Length());
|
||||
|
||||
nsCOMPtr<nsIImportMailboxDescriptor> desc;
|
||||
nsresult rv = aImportService->CreateNewMailboxDescriptor(getter_AddRefs(desc));
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
// find out number of messages in this .mbox
|
||||
uint32_t numMessages = 0;
|
||||
{
|
||||
// move to the .mbox's Messages folder
|
||||
nsCOMPtr<nsIFile> messagesFolder;
|
||||
aFolder->Clone(getter_AddRefs(messagesFolder));
|
||||
nsresult rv = messagesFolder->Append(NS_LITERAL_STRING("Messages"));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
// count the number of messages in this folder. it sucks that we have to iterate through the folder
|
||||
// but XPCOM doesn't give us any way to just get the file count, unfortunately. :-(
|
||||
nsCOMPtr<nsISimpleEnumerator> dirEnumerator;
|
||||
messagesFolder->GetDirectoryEntries(getter_AddRefs(dirEnumerator));
|
||||
if (dirEnumerator) {
|
||||
bool hasMore = false;
|
||||
while (NS_SUCCEEDED(dirEnumerator->HasMoreElements(&hasMore)) && hasMore) {
|
||||
nsCOMPtr<nsISupports> rawSupports;
|
||||
dirEnumerator->GetNext(getter_AddRefs(rawSupports));
|
||||
if (!rawSupports)
|
||||
continue;
|
||||
|
||||
nsCOMPtr<nsIFile> file(do_QueryInterface(rawSupports));
|
||||
if (file) {
|
||||
bool isFile = false;
|
||||
file->IsFile(&isFile);
|
||||
if (isFile)
|
||||
numMessages++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
desc->SetSize(numMessages);
|
||||
desc->SetDisplayName(folderName.get());
|
||||
desc->SetDepth(mCurDepth);
|
||||
|
||||
IMPORT_LOG3("Will import %s with approx %d messages, depth is %d", NS_ConvertUTF16toUTF8(folderName).get(), numMessages, mCurDepth);
|
||||
|
||||
// XXX: this is silly. there's no setter for the mailbox descriptor's file, so we need to get it, and then modify it.
|
||||
nsCOMPtr<nsIFile> mailboxDescFile;
|
||||
rv = desc->GetFile(getter_AddRefs(mailboxDescFile));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
if (mailboxDescFile)
|
||||
mailboxDescFile->InitWithFile(aFolder);
|
||||
|
||||
// add this mailbox descriptor to the list
|
||||
aMailboxDescs->AppendElement(desc, false);
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// Starts looking for .mbox dirs in the specified dir. The .mbox dirs contain messages and can be considered leafs in a tree of
|
||||
// nested mailboxes (subfolders).
|
||||
//
|
||||
// If a mailbox has sub-mailboxes, they are contained in a sibling folder with the same name without the ".mbox" part.
|
||||
// example:
|
||||
// MyParentMailbox.mbox/
|
||||
// MyParentMailbox/
|
||||
// MyChildMailbox.mbox/
|
||||
// MyOtherChildMailbox.mbox/
|
||||
//
|
||||
nsresult nsAppleMailImportMail::FindMboxDirs(nsIFile *aFolder, nsIMutableArray *aMailboxDescs, nsIImportService *aImportService)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(aFolder);
|
||||
NS_ENSURE_ARG_POINTER(aMailboxDescs);
|
||||
NS_ENSURE_ARG_POINTER(aImportService);
|
||||
|
||||
// make sure this is a directory.
|
||||
bool isDir = false;
|
||||
if (NS_FAILED(aFolder->IsDirectory(&isDir)) || !isDir)
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
// iterate through the folder contents
|
||||
nsCOMPtr<nsISimpleEnumerator> directoryEnumerator;
|
||||
nsresult rv = aFolder->GetDirectoryEntries(getter_AddRefs(directoryEnumerator));
|
||||
if (NS_FAILED(rv) || !directoryEnumerator)
|
||||
return rv;
|
||||
|
||||
bool hasMore = false;
|
||||
while (NS_SUCCEEDED(directoryEnumerator->HasMoreElements(&hasMore)) && hasMore) {
|
||||
|
||||
// get the next file entry
|
||||
nsCOMPtr<nsIFile> currentEntry;
|
||||
{
|
||||
nsCOMPtr<nsISupports> rawSupports;
|
||||
directoryEnumerator->GetNext(getter_AddRefs(rawSupports));
|
||||
if (!rawSupports)
|
||||
continue;
|
||||
currentEntry = do_QueryInterface(rawSupports);
|
||||
if (!currentEntry)
|
||||
continue;
|
||||
}
|
||||
|
||||
// we only care about directories...
|
||||
if (NS_FAILED(currentEntry->IsDirectory(&isDir)) || !isDir)
|
||||
continue;
|
||||
|
||||
// now find out if this is a .mbox dir
|
||||
nsAutoString currentFolderName;
|
||||
if (NS_SUCCEEDED(currentEntry->GetLeafName(currentFolderName)) &&
|
||||
(StringEndsWith(currentFolderName, NS_LITERAL_STRING(POP_MBOX_SUFFIX)) ||
|
||||
StringEndsWith(currentFolderName, NS_LITERAL_STRING(IMAP_MBOX_SUFFIX)))) {
|
||||
IMPORT_LOG1("Adding .mbox dir: %s", NS_ConvertUTF16toUTF8(currentFolderName).get());
|
||||
|
||||
// add this .mbox
|
||||
rv = AddMboxDir(currentEntry, aMailboxDescs, aImportService);
|
||||
if (NS_FAILED(rv)) {
|
||||
IMPORT_LOG1("Couldn't add .mbox for import: %s ... continuing anyway", NS_ConvertUTF16toUTF8(currentFolderName).get());
|
||||
continue;
|
||||
}
|
||||
|
||||
// see if this .mbox dir has any sub-mailboxes
|
||||
nsAutoString siblingMailboxDirPath;
|
||||
currentEntry->GetPath(siblingMailboxDirPath);
|
||||
|
||||
// cut off suffix
|
||||
if (StringEndsWith(siblingMailboxDirPath, NS_LITERAL_STRING(IMAP_MBOX_SUFFIX)))
|
||||
siblingMailboxDirPath.SetLength(siblingMailboxDirPath.Length()-9);
|
||||
else if (StringEndsWith(siblingMailboxDirPath, NS_LITERAL_STRING(POP_MBOX_SUFFIX)))
|
||||
siblingMailboxDirPath.SetLength(siblingMailboxDirPath.Length()-5);
|
||||
|
||||
IMPORT_LOG1("trying to locate a '%s'", NS_ConvertUTF16toUTF8(siblingMailboxDirPath).get());
|
||||
nsCOMPtr<nsIFile> siblingMailboxDir(do_CreateInstance(NS_LOCAL_FILE_CONTRACTID, &rv));
|
||||
if (NS_FAILED(rv))
|
||||
continue;
|
||||
|
||||
rv = siblingMailboxDir->InitWithPath(siblingMailboxDirPath);
|
||||
bool reallyExists = false;
|
||||
siblingMailboxDir->Exists(&reallyExists);
|
||||
|
||||
if (NS_SUCCEEDED(rv) && reallyExists) {
|
||||
IMPORT_LOG1("Found what looks like an .mbox container: %s", NS_ConvertUTF16toUTF8(currentFolderName).get());
|
||||
|
||||
// traverse this folder for other .mboxes
|
||||
mCurDepth++;
|
||||
FindMboxDirs(siblingMailboxDir, aMailboxDescs, aImportService);
|
||||
mCurDepth--;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsAppleMailImportMail::ImportMailbox(nsIImportMailboxDescriptor *aMailbox,
|
||||
nsIMsgFolder *aDstFolder,
|
||||
char16_t **aErrorLog,
|
||||
char16_t **aSuccessLog, bool *aFatalError)
|
||||
{
|
||||
nsAutoString errorLog, successLog;
|
||||
|
||||
// reset progress
|
||||
mProgress = 0;
|
||||
|
||||
nsAutoString mailboxName;
|
||||
aMailbox->GetDisplayName(getter_Copies(mailboxName));
|
||||
|
||||
nsCOMPtr<nsIFile> mboxFolder;
|
||||
nsresult rv = aMailbox->GetFile(getter_AddRefs(mboxFolder));
|
||||
if (NS_FAILED(rv) || !mboxFolder) {
|
||||
ReportStatus(u"ApplemailImportMailboxConverterror", mailboxName, errorLog);
|
||||
SetLogs(successLog, errorLog, aSuccessLog, aErrorLog);
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
// if we're an account mailbox, nothing do. if we're a real mbox
|
||||
// then we've got some messages to import!
|
||||
uint32_t mailboxIdentifier;
|
||||
aMailbox->GetIdentifier(&mailboxIdentifier);
|
||||
|
||||
if (mailboxIdentifier != kAccountMailboxID) {
|
||||
// move to the .mbox's Messages folder
|
||||
nsCOMPtr<nsIFile> messagesFolder;
|
||||
mboxFolder->Clone(getter_AddRefs(messagesFolder));
|
||||
rv = messagesFolder->Append(NS_LITERAL_STRING("Messages"));
|
||||
if (NS_FAILED(rv)) {
|
||||
// even if there are no messages, it might still be a valid mailbox, or even
|
||||
// a parent for other mailboxes.
|
||||
//
|
||||
// just indicate that we're done, using the same number that we used to estimate
|
||||
// number of messages earlier.
|
||||
uint32_t finalSize;
|
||||
aMailbox->GetSize(&finalSize);
|
||||
mProgress = finalSize;
|
||||
|
||||
// report that we successfully imported this mailbox
|
||||
ReportStatus(u"ApplemailImportMailboxSuccess", mailboxName, successLog);
|
||||
SetLogs(successLog, errorLog, aSuccessLog, aErrorLog);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// let's import the messages!
|
||||
nsCOMPtr<nsISimpleEnumerator> directoryEnumerator;
|
||||
rv = messagesFolder->GetDirectoryEntries(getter_AddRefs(directoryEnumerator));
|
||||
if (NS_FAILED(rv)) {
|
||||
ReportStatus(u"ApplemailImportMailboxConvertError", mailboxName, errorLog);
|
||||
SetLogs(successLog, errorLog, aSuccessLog, aErrorLog);
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
// prepare an outstream to the destination file
|
||||
nsCOMPtr<nsIMsgPluggableStore> msgStore;
|
||||
rv = aDstFolder->GetMsgStore(getter_AddRefs(msgStore));
|
||||
if (!msgStore || NS_FAILED(rv)) {
|
||||
ReportStatus(u"ApplemailImportMailboxConverterror", mailboxName, errorLog);
|
||||
SetLogs(successLog, errorLog, aSuccessLog, aErrorLog);
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
bool hasMore = false;
|
||||
nsCOMPtr<nsIOutputStream> outStream;
|
||||
|
||||
while (NS_SUCCEEDED(directoryEnumerator->HasMoreElements(&hasMore)) && hasMore) {
|
||||
// get the next file entry
|
||||
nsCOMPtr<nsIFile> currentEntry;
|
||||
{
|
||||
nsCOMPtr<nsISupports> rawSupports;
|
||||
directoryEnumerator->GetNext(getter_AddRefs(rawSupports));
|
||||
if (!rawSupports)
|
||||
continue;
|
||||
currentEntry = do_QueryInterface(rawSupports);
|
||||
if (!currentEntry)
|
||||
continue;
|
||||
}
|
||||
|
||||
// make sure it's an .emlx file
|
||||
bool isFile = false;
|
||||
currentEntry->IsFile(&isFile);
|
||||
if (!isFile)
|
||||
continue;
|
||||
|
||||
nsAutoString leafName;
|
||||
currentEntry->GetLeafName(leafName);
|
||||
if (!StringEndsWith(leafName, NS_LITERAL_STRING(".emlx")))
|
||||
continue;
|
||||
|
||||
nsCOMPtr<nsIMsgDBHdr> msgHdr;
|
||||
bool reusable;
|
||||
rv = msgStore->GetNewMsgOutputStream(aDstFolder, getter_AddRefs(msgHdr),
|
||||
&reusable,
|
||||
getter_AddRefs(outStream));
|
||||
if (NS_FAILED(rv))
|
||||
break;
|
||||
|
||||
// add the data to the mbox stream
|
||||
if (NS_SUCCEEDED(nsEmlxHelperUtils::AddEmlxMessageToStream(currentEntry, outStream))) {
|
||||
mProgress++;
|
||||
msgStore->FinishNewMessage(outStream, msgHdr);
|
||||
}
|
||||
else {
|
||||
msgStore->DiscardNewMessage(outStream, msgHdr);
|
||||
break;
|
||||
}
|
||||
if (!reusable)
|
||||
outStream->Close();
|
||||
}
|
||||
if (outStream)
|
||||
outStream->Close();
|
||||
}
|
||||
// just indicate that we're done, using the same number that we used to estimate
|
||||
// number of messages earlier.
|
||||
uint32_t finalSize;
|
||||
aMailbox->GetSize(&finalSize);
|
||||
mProgress = finalSize;
|
||||
|
||||
// report that we successfully imported this mailbox
|
||||
ReportStatus(u"ApplemailImportMailboxSuccess", mailboxName, successLog);
|
||||
SetLogs(successLog, errorLog, aSuccessLog, aErrorLog);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
void nsAppleMailImportMail::ReportStatus(const char16_t* aErrorName, nsString &aName,
|
||||
nsAString &aStream)
|
||||
{
|
||||
// get (and format, if needed) the error string from the bundle
|
||||
nsAutoString outString;
|
||||
const char16_t *fmt = { aName.get() };
|
||||
nsresult rv = mBundle->FormatStringFromName(aErrorName, &fmt, 1, getter_Copies(outString));
|
||||
// write it out the stream
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
aStream.Append(outString);
|
||||
aStream.Append(char16_t('\n'));
|
||||
}
|
||||
}
|
||||
|
||||
void nsAppleMailImportMail::SetLogs(const nsAString &aSuccess, const nsAString &aError, char16_t **aOutSuccess, char16_t **aOutError)
|
||||
{
|
||||
if (aOutError && !*aOutError)
|
||||
*aOutError = ToNewUnicode(aError);
|
||||
if (aOutSuccess && !*aOutSuccess)
|
||||
*aOutSuccess = ToNewUnicode(aSuccess);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsAppleMailImportMail::GetImportProgress(uint32_t *aDoneSoFar)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(aDoneSoFar);
|
||||
*aDoneSoFar = mProgress;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsAppleMailImportMail::TranslateFolderName(const nsAString &aFolderName, nsAString &aResult)
|
||||
{
|
||||
aResult = aFolderName;
|
||||
return NS_OK;
|
||||
}
|
||||
|
|
@ -1,78 +0,0 @@
|
|||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#ifndef nsAppleMailImport_h___
|
||||
#define nsAppleMailImport_h___
|
||||
|
||||
#include "mozilla/Logging.h"
|
||||
#include "nsIImportModule.h"
|
||||
#include "nsCOMPtr.h"
|
||||
#include "nsIStringBundle.h"
|
||||
#include "nsIImportMail.h"
|
||||
|
||||
// logging facilities
|
||||
extern PRLogModuleInfo *APPLEMAILLOGMODULE;
|
||||
|
||||
#define IMPORT_LOG0(x) MOZ_LOG(APPLEMAILLOGMODULE, mozilla::LogLevel::Debug, (x))
|
||||
#define IMPORT_LOG1(x, y) MOZ_LOG(APPLEMAILLOGMODULE, mozilla::LogLevel::Debug, (x, y))
|
||||
#define IMPORT_LOG2(x, y, z) MOZ_LOG(APPLEMAILLOGMODULE, mozilla::LogLevel::Debug, (x, y, z))
|
||||
#define IMPORT_LOG3(a, b, c, d) MOZ_LOG(APPLEMAILLOGMODULE, mozilla::LogLevel::Debug, (a, b, c, d))
|
||||
|
||||
#define NS_APPLEMAILIMPL_CID \
|
||||
{ 0x9117a1ea, 0xe012, 0x43b5, { 0xa0, 0x20, 0xcb, 0x8a, 0x66, 0xcc, 0x09, 0xe1 } }
|
||||
|
||||
#define NS_APPLEMAILIMPORT_CID \
|
||||
{ 0x6d3f101c, 0x70ec, 0x4e04, { 0xb6, 0x8d, 0x99, 0x08, 0xd1, 0xae, 0xdd, 0xf3 } }
|
||||
|
||||
#define NS_APPLEMAILIMPL_CONTRACTID "@mozilla.org/import/import-appleMailImpl;1"
|
||||
|
||||
#define kAppleMailSupportsString "mail"
|
||||
|
||||
class nsIImportService;
|
||||
class nsIMutableArray;
|
||||
|
||||
class nsAppleMailImportModule : public nsIImportModule
|
||||
{
|
||||
public:
|
||||
|
||||
nsAppleMailImportModule();
|
||||
|
||||
NS_DECL_THREADSAFE_ISUPPORTS
|
||||
NS_DECL_NSIIMPORTMODULE
|
||||
|
||||
private:
|
||||
virtual ~nsAppleMailImportModule();
|
||||
|
||||
nsCOMPtr<nsIStringBundle> mBundle;
|
||||
};
|
||||
|
||||
class nsAppleMailImportMail : public nsIImportMail
|
||||
{
|
||||
public:
|
||||
|
||||
nsAppleMailImportMail();
|
||||
|
||||
NS_DECL_THREADSAFE_ISUPPORTS
|
||||
NS_DECL_NSIIMPORTMAIL
|
||||
|
||||
nsresult Initialize();
|
||||
|
||||
private:
|
||||
virtual ~nsAppleMailImportMail();
|
||||
|
||||
void FindAccountMailDirs(nsIFile *aRoot, nsIMutableArray *aMailboxDescs, nsIImportService *aImportService);
|
||||
nsresult FindMboxDirs(nsIFile *aFolder, nsIMutableArray *aMailboxDescs, nsIImportService *aImportService);
|
||||
nsresult AddMboxDir(nsIFile *aFolder, nsIMutableArray *aMailboxDescs, nsIImportService *aImportService);
|
||||
|
||||
// aInfoString is the format to a "foo %s" string. It may be NULL if the error string needs no such format.
|
||||
void ReportStatus(const char16_t* aErrorName, nsString &aName, nsAString &aStream);
|
||||
static void SetLogs(const nsAString& success, const nsAString& error, char16_t **aOutErrorLog, char16_t **aSuccessLog);
|
||||
|
||||
nsCOMPtr<nsIStringBundle> mBundle;
|
||||
uint32_t mProgress;
|
||||
uint16_t mCurDepth;
|
||||
};
|
||||
|
||||
#endif /* nsAppleMailImport_h___ */
|
||||
|
|
@ -1,55 +0,0 @@
|
|||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#ifndef nsEmlxHelperUtils_h___
|
||||
#define nsEmlxHelperUtils_h___
|
||||
|
||||
#include "nscore.h"
|
||||
#include "nsStringGlue.h"
|
||||
|
||||
class nsIOutputStream;
|
||||
class nsIFile;
|
||||
|
||||
class nsEmlxHelperUtils {
|
||||
/* All emlx messages have a "flags" number in the metadata.
|
||||
These are the masks to decode that, found via http://jwz.livejournal.com/505711.html */
|
||||
enum EmlxMetadataMask {
|
||||
kRead = 1 << 0, // read
|
||||
// 1 << 1, // deleted
|
||||
kAnswered = 1 << 2, // answered
|
||||
// 1 << 3, // encrypted
|
||||
kFlagged = 1 << 4, // flagged
|
||||
// 1 << 5, // recent
|
||||
// 1 << 6, // draft
|
||||
// 1 << 7, // initial (no longer used)
|
||||
kForwarded = 1 << 8, // forwarded
|
||||
// 1 << 9, // redirected
|
||||
// 3F << 10, // attachment count (6 bits)
|
||||
// 7F << 16, // priority level (7 bits)
|
||||
// 1 << 23, // signed
|
||||
// 1 << 24, // is junk
|
||||
// 1 << 25, // is not junk
|
||||
// 1 << 26, // font size delta 7 (3 bits)
|
||||
// 1 << 29, // junk mail level recorded
|
||||
// 1 << 30, // highlight text in toc
|
||||
// 1 << 31 // (unused)
|
||||
};
|
||||
|
||||
// This method will scan the raw EMLX message buffer for "dangerous" so-called "From-lines" that we need to escape.
|
||||
// If it needs to modify any lines, it will return a non-NULL aOutBuffer. If aOutBuffer is NULL, no modification needed
|
||||
// to be made.
|
||||
static nsresult ConvertToMboxRD(const char *aMessageBufferStart, const char *aMessageBufferEnd, nsCString &aOutBuffer);
|
||||
|
||||
// returns an int representing the X-Mozilla-Status flags set (e.g. "read", "flagged") converted from EMLX flags.
|
||||
static nsresult ConvertToMozillaStatusFlags(const char *aXMLBufferStart, const char *aXMLBufferEnd, uint32_t *aMozillaStatusFlags);
|
||||
|
||||
public:
|
||||
|
||||
// add an .emlx message to the mbox output
|
||||
static nsresult AddEmlxMessageToStream(nsIFile *aEmlxFile, nsIOutputStream *aOutoutStream);
|
||||
|
||||
};
|
||||
|
||||
#endif // nsEmlxHelperUtils_h___
|
||||
|
|
@ -1,240 +0,0 @@
|
|||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "nsEmlxHelperUtils.h"
|
||||
#include "nsIFileStreams.h"
|
||||
#include "nsIBufferedStreams.h"
|
||||
#include "nsIOutputStream.h"
|
||||
#include "nsNetUtil.h"
|
||||
#include "nsCOMPtr.h"
|
||||
#include "nsObjCExceptions.h"
|
||||
#include "nsMsgMessageFlags.h"
|
||||
#include "nsMsgLocalFolderHdrs.h"
|
||||
#include "msgCore.h"
|
||||
#include "nsTArray.h"
|
||||
#include "nsAppleMailImport.h"
|
||||
#include "prprf.h"
|
||||
#include "nsIFile.h"
|
||||
|
||||
#import <Cocoa/Cocoa.h>
|
||||
|
||||
|
||||
nsresult nsEmlxHelperUtils::ConvertToMozillaStatusFlags(const char *aXMLBufferStart,
|
||||
const char *aXMLBufferEnd,
|
||||
uint32_t *aMozillaStatusFlags)
|
||||
{
|
||||
// create a NSData wrapper around the buffer, so we can use the Cocoa call below
|
||||
NSData *metadata =
|
||||
[[[NSData alloc] initWithBytesNoCopy:(void *)aXMLBufferStart length:(aXMLBufferEnd-aXMLBufferStart) freeWhenDone:NO] autorelease];
|
||||
|
||||
// get the XML data as a dictionary
|
||||
NSPropertyListFormat format;
|
||||
id plist = [NSPropertyListSerialization propertyListWithData:metadata
|
||||
options:NSPropertyListImmutable
|
||||
format:&format
|
||||
error:NULL];
|
||||
|
||||
if (!plist)
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
// find the <flags>...</flags> value and convert to int
|
||||
const uint32_t emlxMessageFlags = [[(NSDictionary *)plist objectForKey:@"flags"] intValue];
|
||||
|
||||
if (emlxMessageFlags == 0)
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
if (emlxMessageFlags & nsEmlxHelperUtils::kRead)
|
||||
*aMozillaStatusFlags |= nsMsgMessageFlags::Read;
|
||||
if (emlxMessageFlags & nsEmlxHelperUtils::kForwarded)
|
||||
*aMozillaStatusFlags |= nsMsgMessageFlags::Forwarded;
|
||||
if (emlxMessageFlags & nsEmlxHelperUtils::kAnswered)
|
||||
*aMozillaStatusFlags |= nsMsgMessageFlags::Replied;
|
||||
if (emlxMessageFlags & nsEmlxHelperUtils::kFlagged)
|
||||
*aMozillaStatusFlags |= nsMsgMessageFlags::Marked;
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult nsEmlxHelperUtils::ConvertToMboxRD(const char *aMessageBufferStart, const char *aMessageBufferEnd, nsCString &aOutBuffer)
|
||||
{
|
||||
nsTArray<const char *> foundFromLines;
|
||||
|
||||
const char *cur = aMessageBufferStart;
|
||||
while (cur < aMessageBufferEnd) {
|
||||
|
||||
const char *foundFromStr = strnstr(cur, "From ", aMessageBufferEnd-cur);
|
||||
|
||||
if (foundFromStr) {
|
||||
// skip all prepending '>' chars
|
||||
const char *fromLineStart = foundFromStr;
|
||||
while (fromLineStart-- >= aMessageBufferStart) {
|
||||
if (*fromLineStart == '\n' || fromLineStart == aMessageBufferStart) {
|
||||
if (fromLineStart > aMessageBufferStart)
|
||||
fromLineStart++;
|
||||
foundFromLines.AppendElement(fromLineStart);
|
||||
break;
|
||||
}
|
||||
else if (*fromLineStart != '>')
|
||||
break;
|
||||
}
|
||||
|
||||
// advance past the last found From string.
|
||||
cur = foundFromStr + 5;
|
||||
|
||||
// look for more From lines.
|
||||
continue;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
// go through foundFromLines
|
||||
if (foundFromLines.Length()) {
|
||||
|
||||
const char *chunkStart = aMessageBufferStart;
|
||||
for (unsigned i=0; i<foundFromLines.Length(); ++i) {
|
||||
aOutBuffer.Append(chunkStart, (foundFromLines[i]-chunkStart));
|
||||
aOutBuffer.Append(NS_LITERAL_CSTRING(">"));
|
||||
|
||||
chunkStart = foundFromLines[i];
|
||||
}
|
||||
aOutBuffer.Append(chunkStart, (aMessageBufferEnd - chunkStart));
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult nsEmlxHelperUtils::AddEmlxMessageToStream(nsIFile *aMessage, nsIOutputStream *aOut)
|
||||
{
|
||||
NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NSRESULT;
|
||||
|
||||
// needed to be sure autoreleased objects are released too, which they might not
|
||||
// in a C++ environment where the main event loop has no autorelease pool (e.g on a XPCOM thread)
|
||||
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
|
||||
|
||||
nsresult rv = NS_ERROR_FAILURE;
|
||||
|
||||
nsAutoCString path;
|
||||
aMessage->GetNativePath(path);
|
||||
|
||||
NSData *data = [NSData dataWithContentsOfFile:[NSString stringWithUTF8String:path.get()]];
|
||||
if (!data) {
|
||||
[pool release];
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
char *startOfMessageData = NULL;
|
||||
uint32_t actualBytesWritten = 0;
|
||||
|
||||
// The anatomy of an EMLX file:
|
||||
//
|
||||
// -------------------------------
|
||||
// < A number describing how many bytes ahead there is message data >
|
||||
// < Message data >
|
||||
// < XML metadata for this message >
|
||||
// -------------------------------
|
||||
|
||||
// read the first line of the emlx file, which is a number of how many bytes ahead the actual
|
||||
// message data is.
|
||||
uint64_t numberOfBytesToRead = strtol((char *)[data bytes], &startOfMessageData, 10);
|
||||
if (numberOfBytesToRead <= 0 || !startOfMessageData) {
|
||||
[pool release];
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
// skip whitespace
|
||||
while (*startOfMessageData == ' ' ||
|
||||
*startOfMessageData == '\n' ||
|
||||
*startOfMessageData == '\r' ||
|
||||
*startOfMessageData == '\t')
|
||||
++startOfMessageData;
|
||||
|
||||
NS_NAMED_LITERAL_CSTRING(kBogusFromLine, "From \n");
|
||||
NS_NAMED_LITERAL_CSTRING(kEndOfMessage, "\n\n");
|
||||
|
||||
// write the bogus "From " line which is a magic separator in the mbox format
|
||||
rv = aOut->Write(kBogusFromLine.get(), kBogusFromLine.Length(), &actualBytesWritten);
|
||||
if (NS_FAILED(rv)) {
|
||||
[pool release];
|
||||
return rv;
|
||||
}
|
||||
|
||||
// now read the XML metadata, so we can extract info like which flags (read? replied? flagged? etc) this message has.
|
||||
const char *startOfXMLMetadata = startOfMessageData + numberOfBytesToRead;
|
||||
const char *endOfXMLMetadata = (char *)[data bytes] + [data length];
|
||||
|
||||
uint32_t x_mozilla_flags = 0;
|
||||
ConvertToMozillaStatusFlags(startOfXMLMetadata, endOfXMLMetadata, &x_mozilla_flags);
|
||||
|
||||
// write the X-Mozilla-Status header according to which flags we've gathered above.
|
||||
uint32_t dummyRv;
|
||||
nsAutoCString buf(PR_smprintf(X_MOZILLA_STATUS_FORMAT MSG_LINEBREAK, x_mozilla_flags));
|
||||
NS_ASSERTION(!buf.IsEmpty(), "printf error with X-Mozilla-Status header");
|
||||
if (buf.IsEmpty()) {
|
||||
[pool release];
|
||||
return rv;
|
||||
}
|
||||
|
||||
rv = aOut->Write(buf.get(), buf.Length(), &dummyRv);
|
||||
if (NS_FAILED(rv)) {
|
||||
[pool release];
|
||||
return rv;
|
||||
}
|
||||
|
||||
// write out X-Mozilla-Keywords header as well to reserve some space for it
|
||||
// in the mbox file.
|
||||
rv = aOut->Write(X_MOZILLA_KEYWORDS, X_MOZILLA_KEYWORDS_LEN, &dummyRv);
|
||||
if (NS_FAILED(rv)) {
|
||||
[pool release];
|
||||
return rv;
|
||||
}
|
||||
|
||||
// write out empty X-Mozilla_status2 header
|
||||
buf.Adopt(PR_smprintf(X_MOZILLA_STATUS2_FORMAT MSG_LINEBREAK, 0));
|
||||
NS_ASSERTION(!buf.IsEmpty(), "printf error with X-Mozilla-Status2 header");
|
||||
if (buf.IsEmpty()) {
|
||||
[pool release];
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
rv = aOut->Write(buf.get(), buf.Length(), &dummyRv);
|
||||
if (NS_FAILED(rv)) {
|
||||
[pool release];
|
||||
return rv;
|
||||
}
|
||||
|
||||
// do any conversion needed for the mbox data to be valid mboxrd.
|
||||
nsCString convertedData;
|
||||
rv = ConvertToMboxRD(startOfMessageData, (startOfMessageData + numberOfBytesToRead), convertedData);
|
||||
if (NS_FAILED(rv)) {
|
||||
[pool release];
|
||||
return rv;
|
||||
}
|
||||
|
||||
// write the actual message data.
|
||||
if (convertedData.IsEmpty())
|
||||
rv = aOut->Write(startOfMessageData, (uint32_t)numberOfBytesToRead, &actualBytesWritten);
|
||||
else {
|
||||
IMPORT_LOG1("Escaped From-lines in %s!", path.get());
|
||||
rv = aOut->Write(convertedData.get(), convertedData.Length(), &actualBytesWritten);
|
||||
}
|
||||
|
||||
if (NS_FAILED(rv)) {
|
||||
[pool release];
|
||||
return rv;
|
||||
}
|
||||
|
||||
NS_ASSERTION(actualBytesWritten == (convertedData.IsEmpty() ? numberOfBytesToRead : convertedData.Length()),
|
||||
"Didn't write as many bytes as expected for .emlx file?");
|
||||
|
||||
// add newlines to denote the end of this message in the mbox
|
||||
rv = aOut->Write(kEndOfMessage.get(), kEndOfMessage.Length(), &actualBytesWritten);
|
||||
|
||||
[pool release];
|
||||
|
||||
return rv;
|
||||
|
||||
NS_OBJC_END_TRY_ABORT_BLOCK_NSRESULT;
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue