Issue #1258 - Part 1: Import mailnews, ldap, and mork from comm-esr52.9.1

This commit is contained in:
Matt A. Tobin 2019-11-03 00:17:46 -04:00 • committed by Roy Tam
commit e400f4130a
1564 changed files with 510348 additions and 0 deletions

View file

@ -0,0 +1,16 @@
# vim: set filetype=python:
# 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/.
UNIFIED_SOURCES += [
'nsBeckyAddressBooks.cpp',
'nsBeckyFilters.cpp',
'nsBeckyImport.cpp',
'nsBeckyMail.cpp',
'nsBeckySettings.cpp',
'nsBeckyStringBundle.cpp',
'nsBeckyUtils.cpp',
]
FINAL_LIBRARY = 'import'

View file

@ -0,0 +1,383 @@
/* vim: set ts=2 et sw=2 tw=80: */
/* 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 "nsCOMPtr.h"
#include "nsComponentManagerUtils.h"
#include "nsServiceManagerUtils.h"
#include "nsIFile.h"
#include "nsISimpleEnumerator.h"
#include "nsIDirectoryEnumerator.h"
#include "nsIMutableArray.h"
#include "nsStringGlue.h"
#include "nsAbBaseCID.h"
#include "nsIAbManager.h"
#include "nsIImportService.h"
#include "nsIImportABDescriptor.h"
#include "nsMsgUtils.h"
#include "nsIStringBundle.h"
#include "nsVCardAddress.h"
#include "nsBeckyAddressBooks.h"
#include "nsBeckyStringBundle.h"
#include "nsBeckyUtils.h"
NS_IMPL_ISUPPORTS(nsBeckyAddressBooks, nsIImportAddressBooks)
nsresult
nsBeckyAddressBooks::Create(nsIImportAddressBooks **aImport)
{
NS_ENSURE_ARG_POINTER(aImport);
*aImport = new nsBeckyAddressBooks();
NS_ADDREF(*aImport);
return NS_OK;
}
nsBeckyAddressBooks::nsBeckyAddressBooks()
: mReadBytes(0)
{
}
nsBeckyAddressBooks::~nsBeckyAddressBooks()
{
}
NS_IMETHODIMP
nsBeckyAddressBooks::GetSupportsMultiple(bool *_retval)
{
NS_ENSURE_ARG_POINTER(_retval);
*_retval = true;
return NS_OK;
}
NS_IMETHODIMP
nsBeckyAddressBooks::GetAutoFind(char16_t **aDescription,
bool *_retval)
{
NS_ENSURE_ARG_POINTER(aDescription);
NS_ENSURE_ARG_POINTER(_retval);
*aDescription =
nsBeckyStringBundle::GetStringByName(u"BeckyImportDescription");
*_retval = false;
return NS_OK;
}
NS_IMETHODIMP
nsBeckyAddressBooks::GetNeedsFieldMap(nsIFile *aLocation, bool *_retval)
{
NS_ENSURE_ARG_POINTER(_retval);
*_retval = false;
return NS_OK;
}
nsresult
nsBeckyAddressBooks::FindAddressBookDirectory(nsIFile **aAddressBookDirectory)
{
nsCOMPtr<nsIFile> userDirectory;
nsresult rv = nsBeckyUtils::FindUserDirectory(getter_AddRefs(userDirectory));
NS_ENSURE_SUCCESS(rv, rv);
rv = userDirectory->Append(NS_LITERAL_STRING("AddrBook"));
NS_ENSURE_SUCCESS(rv, rv);
bool exists = false;
rv = userDirectory->Exists(&exists);
NS_ENSURE_SUCCESS(rv, rv);
if (!exists)
return NS_ERROR_FILE_NOT_FOUND;
bool isDirectory = false;
rv = userDirectory->IsDirectory(&isDirectory);
NS_ENSURE_SUCCESS(rv, rv);
if (!isDirectory)
return NS_ERROR_FILE_NOT_FOUND;
userDirectory.forget(aAddressBookDirectory);
return NS_OK;
}
NS_IMETHODIMP
nsBeckyAddressBooks::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;
if (NS_SUCCEEDED(nsBeckyAddressBooks::FindAddressBookDirectory(aLocation))) {
*aFound = true;
*aUserVerify = false;
}
return NS_OK;
}
nsresult
nsBeckyAddressBooks::CreateAddressBookDescriptor(nsIImportABDescriptor **aDescriptor)
{
nsresult rv;
nsCOMPtr<nsIImportService> importService = do_GetService(NS_IMPORTSERVICE_CONTRACTID, &rv);
NS_ENSURE_SUCCESS(rv, rv);
return importService->CreateNewABDescriptor(aDescriptor);
}
bool
nsBeckyAddressBooks::IsAddressBookFile(nsIFile *aFile)
{
if (!aFile)
return false;
nsresult rv;
bool isFile = false;
rv = aFile->IsFile(&isFile);
if (NS_FAILED(rv) && !isFile)
return false;
nsAutoString name;
rv = aFile->GetLeafName(name);
return StringEndsWith(name, NS_LITERAL_STRING(".bab"));
}
bool
nsBeckyAddressBooks::HasAddressBookFile(nsIFile *aDirectory)
{
if (!aDirectory)
return false;
nsresult rv;
bool isDirectory = false;
rv = aDirectory->IsDirectory(&isDirectory);
if (NS_FAILED(rv) || !isDirectory)
return false;
nsCOMPtr<nsISimpleEnumerator> entries;
rv = aDirectory->GetDirectoryEntries(getter_AddRefs(entries));
NS_ENSURE_SUCCESS(rv, false);
bool more;
nsCOMPtr<nsISupports> entry;
while (NS_SUCCEEDED(entries->HasMoreElements(&more)) && more) {
rv = entries->GetNext(getter_AddRefs(entry));
NS_ENSURE_SUCCESS(rv, false);
nsCOMPtr<nsIFile> file = do_QueryInterface(entry, &rv);
NS_ENSURE_SUCCESS(rv, false);
if (IsAddressBookFile(file))
return true;
}
return false;
}
uint32_t
nsBeckyAddressBooks::CountAddressBookSize(nsIFile *aDirectory)
{
if (!aDirectory)
return 0;
nsresult rv;
bool isDirectory = false;
rv = aDirectory->IsDirectory(&isDirectory);
if (NS_FAILED(rv) || !isDirectory)
return 0;
nsCOMPtr<nsISimpleEnumerator> entries;
rv = aDirectory->GetDirectoryEntries(getter_AddRefs(entries));
NS_ENSURE_SUCCESS(rv, 0);
uint32_t total = 0;
bool more;
nsCOMPtr<nsISupports> entry;
while (NS_SUCCEEDED(entries->HasMoreElements(&more)) && more) {
rv = entries->GetNext(getter_AddRefs(entry));
NS_ENSURE_SUCCESS(rv, 0);
nsCOMPtr<nsIFile> file = do_QueryInterface(entry, &rv);
NS_ENSURE_SUCCESS(rv, 0);
int64_t size;
file->GetFileSize(&size);
if (total + size > std::numeric_limits<uint32_t>::max())
return std::numeric_limits<uint32_t>::max();
total += static_cast<uint32_t>(size);
}
return total;
}
nsresult
nsBeckyAddressBooks::AppendAddressBookDescriptor(nsIFile *aEntry,
nsIMutableArray *aCollected)
{
NS_ENSURE_ARG_POINTER(aCollected);
if (!HasAddressBookFile(aEntry))
return NS_OK;
nsresult rv;
nsCOMPtr<nsIImportABDescriptor> descriptor;
rv = CreateAddressBookDescriptor(getter_AddRefs(descriptor));
NS_ENSURE_SUCCESS(rv, rv);
uint32_t size = CountAddressBookSize(aEntry);
descriptor->SetSize(size);
descriptor->SetAbFile(aEntry);
nsAutoString name;
aEntry->GetLeafName(name);
descriptor->SetPreferredName(name);
return aCollected->AppendElement(descriptor, false);
}
nsresult
nsBeckyAddressBooks::CollectAddressBooks(nsIFile *aTarget,
nsIMutableArray *aCollected)
{
nsresult rv = AppendAddressBookDescriptor(aTarget, aCollected);
NS_ENSURE_SUCCESS(rv, rv);
nsCOMPtr<nsISimpleEnumerator> entries;
rv = aTarget->GetDirectoryEntries(getter_AddRefs(entries));
NS_ENSURE_SUCCESS(rv, rv);
bool more;
nsCOMPtr<nsISupports> entry;
while (NS_SUCCEEDED(entries->HasMoreElements(&more)) && more) {
rv = entries->GetNext(getter_AddRefs(entry));
NS_ENSURE_SUCCESS(rv, rv);
nsCOMPtr<nsIFile> file = do_QueryInterface(entry, &rv);
NS_ENSURE_SUCCESS(rv, rv);
bool isDirectory = false;
rv = file->IsDirectory(&isDirectory);
if (NS_SUCCEEDED(rv) && isDirectory)
rv = CollectAddressBooks(file, aCollected);
NS_ENSURE_SUCCESS(rv, rv);
}
return NS_OK;
}
NS_IMETHODIMP
nsBeckyAddressBooks::FindAddressBooks(nsIFile *aLocation,
nsIArray **_retval)
{
NS_ENSURE_ARG_POINTER(aLocation);
NS_ENSURE_ARG_POINTER(_retval);
nsresult rv;
nsCOMPtr<nsIMutableArray> array(do_CreateInstance(NS_ARRAY_CONTRACTID, &rv));
NS_ENSURE_SUCCESS(rv, rv);
bool isDirectory = false;
rv = aLocation->IsDirectory(&isDirectory);
if (NS_FAILED(rv) || !isDirectory)
return NS_ERROR_FAILURE;
rv = CollectAddressBooks(aLocation, array);
NS_ENSURE_SUCCESS(rv, rv);
array.forget(_retval);
return NS_OK;
}
NS_IMETHODIMP
nsBeckyAddressBooks::InitFieldMap(nsIImportFieldMap *aFieldMap)
{
return NS_ERROR_FAILURE;
}
NS_IMETHODIMP
nsBeckyAddressBooks::ImportAddressBook(nsIImportABDescriptor *aSource,
nsIAddrDatabase *aDestination,
nsIImportFieldMap *aFieldMap,
nsISupports *aSupportService,
char16_t **aErrorLog,
char16_t **aSuccessLog,
bool *aFatalError)
{
NS_ENSURE_ARG_POINTER(aSource);
NS_ENSURE_ARG_POINTER(aDestination);
NS_ENSURE_ARG_POINTER(aErrorLog);
NS_ENSURE_ARG_POINTER(aSuccessLog);
NS_ENSURE_ARG_POINTER(aFatalError);
mReadBytes = 0;
nsCOMPtr<nsIFile> file;
nsresult rv = aSource->GetAbFile(getter_AddRefs(file));
NS_ENSURE_SUCCESS(rv, rv);
nsCOMPtr<nsISimpleEnumerator> entries;
rv = file->GetDirectoryEntries(getter_AddRefs(entries));
NS_ENSURE_SUCCESS(rv, rv);
bool more;
nsCOMPtr<nsISupports> entry;
nsAutoString error;
while (NS_SUCCEEDED(entries->HasMoreElements(&more)) && more) {
rv = entries->GetNext(getter_AddRefs(entry));
NS_ENSURE_SUCCESS(rv, rv);
nsCOMPtr<nsIFile> file = do_QueryInterface(entry, &rv);
NS_ENSURE_SUCCESS(rv, rv);
if (!IsAddressBookFile(file))
continue;
bool aborted = false;
nsAutoString name;
aSource->GetPreferredName(name);
nsVCardAddress vcard;
rv = vcard.ImportAddresses(&aborted, name.get(), file, aDestination, error, &mReadBytes);
if (NS_FAILED(rv)) {
break;
}
}
if (!error.IsEmpty())
*aErrorLog = ToNewUnicode(error);
else
*aSuccessLog = nsBeckyStringBundle::GetStringByName(u"BeckyImportAddressSuccess");
return rv;
}
NS_IMETHODIMP
nsBeckyAddressBooks::GetImportProgress(uint32_t *_retval)
{
NS_ENSURE_ARG_POINTER(_retval);
*_retval = mReadBytes;
return NS_OK;
}
NS_IMETHODIMP
nsBeckyAddressBooks::SetSampleLocation(nsIFile *aLocation)
{
return NS_OK;
}
NS_IMETHODIMP
nsBeckyAddressBooks::GetSampleData(int32_t aRecordNumber,
bool *aRecordExists,
char16_t **_retval)
{
return NS_ERROR_FAILURE;
}

View file

@ -0,0 +1,35 @@
/* vim: set ts=2 et sw=2 tw=80: */
/* 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 nsBeckyAddressBooks_h___
#define nsBeckyAddressBooks_h___
#include "nsIImportAddressBooks.h"
class nsBeckyAddressBooks final : public nsIImportAddressBooks
{
public:
nsBeckyAddressBooks();
static nsresult Create(nsIImportAddressBooks **aImport);
NS_DECL_ISUPPORTS
NS_DECL_NSIIMPORTADDRESSBOOKS
private:
virtual ~nsBeckyAddressBooks();
uint32_t mReadBytes;
nsresult CollectAddressBooks(nsIFile *aTarget, nsIMutableArray *aCollected);
nsresult FindAddressBookDirectory(nsIFile **aAddressBookDirectory);
nsresult AppendAddressBookDescriptor(nsIFile *aEntry,
nsIMutableArray *aCollected);
uint32_t CountAddressBookSize(nsIFile *aDirectory);
bool HasAddressBookFile(nsIFile *aDirectory);
bool IsAddressBookFile(nsIFile *aFile);
nsresult CreateAddressBookDescriptor(nsIImportABDescriptor **aDescriptor);
};
#endif /* nsBeckyAddressBooks_h___ */

View file

@ -0,0 +1,793 @@
/* vim: set ts=2 et sw=2 tw=80: */
/* 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 "nsArrayUtils.h"
#include "nsILineInputStream.h"
#include "nsIStringBundle.h"
#include "nsComponentManagerUtils.h"
#include "nsServiceManagerUtils.h"
#include "nsIMsgFilter.h"
#include "nsIMsgFilterList.h"
#include "nsIMsgAccountManager.h"
#include "nsIMsgAccount.h"
#include "nsIMsgSearchTerm.h"
#include "nsIMsgFolder.h"
#include "nsCOMPtr.h"
#include "nsMsgSearchCore.h"
#include "nsMsgBaseCID.h"
#include "nsMsgUtils.h"
#include "msgCore.h"
#include "nsBeckyFilters.h"
#include "nsBeckyStringBundle.h"
#include "nsBeckyUtils.h"
NS_IMPL_ISUPPORTS(nsBeckyFilters, nsIImportFilters)
nsresult
nsBeckyFilters::Create(nsIImportFilters **aImport)
{
NS_ENSURE_ARG_POINTER(aImport);
*aImport = new nsBeckyFilters();
NS_ADDREF(*aImport);
return NS_OK;
}
nsBeckyFilters::nsBeckyFilters()
: mLocation(nullptr),
mServer(nullptr),
mConvertedFile(nullptr)
{
}
nsBeckyFilters::~nsBeckyFilters()
{
}
nsresult
nsBeckyFilters::GetDefaultFilterLocation(nsIFile **aFile)
{
NS_ENSURE_ARG_POINTER(aFile);
nsresult rv;
nsCOMPtr<nsIFile> filterDir;
rv = nsBeckyUtils::GetDefaultMailboxDirectory(getter_AddRefs(filterDir));
NS_ENSURE_SUCCESS(rv, rv);
filterDir.forget(aFile);
return NS_OK;
}
nsresult
nsBeckyFilters::GetFilterFile(bool aIncoming, nsIFile *aLocation, nsIFile **aFile)
{
NS_ENSURE_ARG_POINTER(aLocation);
NS_ENSURE_ARG_POINTER(aFile);
// We assume the caller has already checked that aLocation is a directory,
// otherwise it would not make sense to call us.
nsresult rv;
nsCOMPtr<nsIFile> filter;
aLocation->Clone(getter_AddRefs(filter));
if (aIncoming)
rv = filter->Append(NS_LITERAL_STRING("IFilter.def"));
else
rv = filter->Append(NS_LITERAL_STRING("OFilter.def"));
NS_ENSURE_SUCCESS(rv, rv);
bool exists = false;
rv = filter->Exists(&exists);
NS_ENSURE_SUCCESS(rv, rv);
if (!exists)
return NS_ERROR_FILE_NOT_FOUND;
filter.forget(aFile);
return NS_OK;
}
NS_IMETHODIMP
nsBeckyFilters::AutoLocate(char16_t **aDescription,
nsIFile **aLocation,
bool *_retval)
{
NS_ENSURE_ARG_POINTER(aLocation);
NS_ENSURE_ARG_POINTER(_retval);
if (aDescription) {
*aDescription =
nsBeckyStringBundle::GetStringByName(u"BeckyImportDescription");
}
*aLocation = nullptr;
*_retval = false;
nsresult rv;
nsCOMPtr<nsIFile> location;
rv = GetDefaultFilterLocation(getter_AddRefs(location));
if (NS_FAILED(rv))
location = do_CreateInstance(NS_LOCAL_FILE_CONTRACTID, &rv);
else
*_retval = true;
location.forget(aLocation);
return NS_OK;
}
NS_IMETHODIMP
nsBeckyFilters::SetLocation(nsIFile *aLocation)
{
NS_ENSURE_ARG_POINTER(aLocation);
bool exists = false;
nsresult rv = aLocation->Exists(&exists);
NS_ENSURE_SUCCESS(rv, rv);
if (!exists)
return NS_ERROR_FILE_NOT_FOUND;
mLocation = aLocation;
return NS_OK;
}
static nsMsgSearchAttribValue
ConvertSearchKeyToAttrib(const nsACString &aKey)
{
if (aKey.EqualsLiteral("From") ||
aKey.EqualsLiteral("Sender") ||
aKey.EqualsLiteral("From, Sender, X-Sender")) {
return nsMsgSearchAttrib::Sender;
} else if (aKey.EqualsLiteral("Subject")) {
return nsMsgSearchAttrib::Subject;
} else if (aKey.EqualsLiteral("[body]")) {
return nsMsgSearchAttrib::Body;
} else if (aKey.EqualsLiteral("Date")) {
return nsMsgSearchAttrib::Date;
} else if (aKey.EqualsLiteral("To")) {
return nsMsgSearchAttrib::To;
} else if (aKey.EqualsLiteral("Cc")) {
return nsMsgSearchAttrib::CC;
} else if (aKey.EqualsLiteral("To, Cc, Bcc:")) {
return nsMsgSearchAttrib::ToOrCC;
}
return -1;
}
static nsMsgSearchOpValue
ConvertSearchFlagsToOperator(const nsACString &aFlags)
{
nsCString flags(aFlags);
int32_t lastTabPosition = flags.RFindChar('\t');
if ((lastTabPosition == -1) ||
((int32_t)aFlags.Length() == lastTabPosition - 1)) {
return -1;
}
switch (aFlags.CharAt(0)) {
case 'X':
return nsMsgSearchOp::DoesntContain;
case 'O':
if (aFlags.FindChar('T', lastTabPosition + 1) >= 0)
return nsMsgSearchOp::BeginsWith;
return nsMsgSearchOp::Contains;
default:
return -1;
}
}
nsresult
nsBeckyFilters::ParseRuleLine(const nsCString &aLine,
nsMsgSearchAttribValue *aSearchAttribute,
nsMsgSearchOpValue *aSearchOperator,
nsString &aSearchKeyword)
{
int32_t firstColonPosition = aLine.FindChar(':');
if (firstColonPosition == -1 ||
(int32_t)aLine.Length() == firstColonPosition - 1) {
return NS_ERROR_FAILURE;
}
int32_t secondColonPosition = aLine.FindChar(':', firstColonPosition + 1);
if (secondColonPosition == -1 ||
(int32_t)aLine.Length() == secondColonPosition - 1) {
return NS_ERROR_FAILURE;
}
int32_t length = secondColonPosition - firstColonPosition - 1;
nsMsgSearchAttribValue searchAttribute;
searchAttribute = ConvertSearchKeyToAttrib(Substring(aLine, firstColonPosition + 1, length));
if (searchAttribute < 0)
return NS_ERROR_FAILURE;
int32_t tabPosition = aLine.FindChar('\t');
if (tabPosition == -1 ||
(int32_t)aLine.Length() == tabPosition - 1) {
return NS_ERROR_FAILURE;
}
nsMsgSearchOpValue searchOperator;
searchOperator = ConvertSearchFlagsToOperator(Substring(aLine, tabPosition + 1));
if (searchOperator < 0)
return NS_ERROR_FAILURE;
*aSearchOperator = searchOperator;
*aSearchAttribute = searchAttribute;
length = tabPosition - secondColonPosition - 1;
CopyUTF8toUTF16(Substring(aLine, secondColonPosition + 1, length), aSearchKeyword);
return NS_OK;
}
nsresult
nsBeckyFilters::SetSearchTerm(const nsCString &aLine, nsIMsgFilter *aFilter)
{
NS_ENSURE_ARG_POINTER(aFilter);
nsresult rv;
nsMsgSearchAttribValue searchAttribute = -1;
nsMsgSearchOpValue searchOperator = -1;
nsAutoString searchKeyword;
rv = ParseRuleLine(aLine, &searchAttribute, &searchOperator, searchKeyword);
NS_ENSURE_SUCCESS(rv, rv);
nsCOMPtr<nsIMsgSearchTerm> term;
rv = aFilter->CreateTerm(getter_AddRefs(term));
NS_ENSURE_SUCCESS(rv, rv);
rv = term->SetAttrib(searchAttribute);
NS_ENSURE_SUCCESS(rv, rv);
rv = term->SetOp(searchOperator);
NS_ENSURE_SUCCESS(rv, rv);
nsCOMPtr<nsIMsgSearchValue> value;
rv = term->GetValue(getter_AddRefs(value));
NS_ENSURE_SUCCESS(rv, rv);
rv = value->SetAttrib(searchAttribute);
NS_ENSURE_SUCCESS(rv, rv);
rv = value->SetStr(searchKeyword);
NS_ENSURE_SUCCESS(rv, rv);
rv = term->SetValue(value);
NS_ENSURE_SUCCESS(rv, rv);
rv = term->SetBooleanAnd(false);
NS_ENSURE_SUCCESS(rv, rv);
if (!searchKeyword.IsEmpty())
rv = aFilter->SetFilterName(searchKeyword);
else
rv = aFilter->SetFilterName(NS_LITERAL_STRING("No name"));
NS_ENSURE_SUCCESS(rv, rv);
return aFilter->AppendTerm(term);
}
nsresult
nsBeckyFilters::CreateRuleAction(nsIMsgFilter *aFilter,
nsMsgRuleActionType actionType,
nsIMsgRuleAction **_retval)
{
nsresult rv;
nsCOMPtr<nsIMsgRuleAction> action;
rv = aFilter->CreateAction(getter_AddRefs(action));
NS_ENSURE_SUCCESS(rv, rv);
rv = action->SetType(actionType);
NS_ENSURE_SUCCESS(rv, rv);
action.forget(_retval);
return NS_OK;
}
nsresult
nsBeckyFilters::GetActionTarget(const nsCString &aLine,
nsCString &aTarget)
{
int32_t firstColonPosition = aLine.FindChar(':');
if (firstColonPosition < -1 ||
aLine.Length() == static_cast<uint32_t>(firstColonPosition)) {
return NS_ERROR_FAILURE;
}
aTarget.Assign(Substring(aLine, firstColonPosition + 1));
return NS_OK;
}
nsresult
nsBeckyFilters::GetResendTarget(const nsCString &aLine,
nsCString &aTemplate,
nsCString &aTargetAddress)
{
nsresult rv;
nsAutoCString target;
rv = GetActionTarget(aLine, target);
NS_ENSURE_SUCCESS(rv, rv);
int32_t asteriskPosition = target.FindChar('*');
if (asteriskPosition < 0) {
aTemplate.Assign(target);
return NS_OK;
}
if (target.Length() == static_cast<uint32_t>(asteriskPosition))
return NS_ERROR_FAILURE;
aTemplate.Assign(StringHead(target, asteriskPosition - 1));
aTargetAddress.Assign(Substring(target, asteriskPosition + 1));
return NS_OK;
}
nsresult
nsBeckyFilters::CreateResendAction(const nsCString &aLine,
nsIMsgFilter *aFilter,
const nsMsgRuleActionType &aActionType,
nsIMsgRuleAction **_retval)
{
nsresult rv;
nsCOMPtr<nsIMsgRuleAction> action;
rv = CreateRuleAction(aFilter, aActionType, getter_AddRefs(action));
NS_ENSURE_SUCCESS(rv, rv);
nsAutoCString templateString;
nsAutoCString targetAddress;
rv = GetResendTarget(aLine, templateString, targetAddress);
NS_ENSURE_SUCCESS(rv, rv);
if (aActionType == nsMsgFilterAction::Forward)
rv = action->SetStrValue(targetAddress);
else
rv = action->SetStrValue(templateString);
NS_ENSURE_SUCCESS(rv, rv);
action.forget(_retval);
return NS_OK;
}
nsresult
nsBeckyFilters::GetFolderNameFromTarget(const nsCString &aTarget, nsAString &aName)
{
int32_t backslashPosition = aTarget.RFindChar('\\');
if (backslashPosition > 0) {
NS_ConvertUTF8toUTF16 utf16String(Substring(aTarget, backslashPosition + 1));
nsBeckyUtils::TranslateFolderName(utf16String, aName);
}
return NS_OK;
}
nsresult
nsBeckyFilters::GetDistributeTarget(const nsCString &aLine,
nsCString &aTargetFolder)
{
nsresult rv;
nsAutoCString target;
rv = GetActionTarget(aLine, target);
NS_ENSURE_SUCCESS(rv, rv);
target.Trim("\\", false, true);
nsAutoString folderName;
rv = GetFolderNameFromTarget(target, folderName);
NS_ENSURE_SUCCESS(rv, rv);
nsCOMPtr <nsIMsgFolder> folder;
rv = GetMessageFolder(folderName, getter_AddRefs(folder));
NS_ENSURE_SUCCESS(rv, rv);
if (!folder) {
rv = mServer->GetRootMsgFolder(getter_AddRefs(folder));
NS_ENSURE_SUCCESS(rv, rv);
}
return folder->GetURI(aTargetFolder);
}
nsresult
nsBeckyFilters::CreateDistributeAction(const nsCString &aLine,
nsIMsgFilter *aFilter,
const nsMsgRuleActionType &aActionType,
nsIMsgRuleAction **_retval)
{
nsresult rv;
nsCOMPtr<nsIMsgRuleAction> action;
rv = CreateRuleAction(aFilter, aActionType, getter_AddRefs(action));
NS_ENSURE_SUCCESS(rv, rv);
nsAutoCString targetFolder;
rv = GetDistributeTarget(aLine, targetFolder);
NS_ENSURE_SUCCESS(rv, rv);
rv = action->SetTargetFolderUri(targetFolder);
NS_ENSURE_SUCCESS(rv, rv);
action.forget(_retval);
return NS_OK;
}
nsresult
nsBeckyFilters::CreateLeaveOrDeleteAction(const nsCString &aLine,
nsIMsgFilter *aFilter,
nsIMsgRuleAction **_retval)
{
nsresult rv;
nsMsgRuleActionType actionType;
if (aLine.CharAt(3) == '0') {
actionType = nsMsgFilterAction::LeaveOnPop3Server;
} else if (aLine.CharAt(3) == '1') {
if (aLine.CharAt(5) == '1')
actionType = nsMsgFilterAction::Delete;
else
actionType = nsMsgFilterAction::DeleteFromPop3Server;
} else {
return NS_ERROR_FAILURE;
}
nsCOMPtr<nsIMsgRuleAction> action;
rv = CreateRuleAction(aFilter, actionType, getter_AddRefs(action));
NS_ENSURE_SUCCESS(rv, rv);
action.forget(_retval);
return NS_OK;
}
nsresult
nsBeckyFilters::SetRuleAction(const nsCString &aLine, nsIMsgFilter *aFilter)
{
if (!aFilter || aLine.Length() < 4)
return NS_ERROR_FAILURE;
nsresult rv = NS_OK;
nsCOMPtr<nsIMsgRuleAction> action;
switch (aLine.CharAt(1)) {
case 'R': // Reply
rv = CreateResendAction(aLine,
aFilter,
nsMsgFilterAction::Reply,
getter_AddRefs(action));
break;
case 'F': // Forward
rv = CreateResendAction(aLine,
aFilter,
nsMsgFilterAction::Forward,
getter_AddRefs(action));
break;
case 'L': // Leave or delete
rv = CreateLeaveOrDeleteAction(aLine, aFilter, getter_AddRefs(action));
break;
case 'Y': // Copy
rv = CreateDistributeAction(aLine,
aFilter,
nsMsgFilterAction::CopyToFolder,
getter_AddRefs(action));
break;
case 'M': // Move
rv = CreateDistributeAction(aLine,
aFilter,
nsMsgFilterAction::MoveToFolder,
getter_AddRefs(action));
break;
case 'G': // Set flag
if (aLine.CharAt(3) == 'R') // Read
rv = CreateRuleAction(aFilter, nsMsgFilterAction::MarkRead, getter_AddRefs(action));
break;
default:
return NS_OK;
}
NS_ENSURE_SUCCESS(rv, rv);
if (action) {
rv = aFilter->AppendAction(action);
NS_ENSURE_SUCCESS(rv, rv);
}
return NS_OK;
}
nsresult
nsBeckyFilters::CreateFilter(bool aIncoming, nsIMsgFilter **_retval)
{
NS_ENSURE_STATE(mServer);
nsCOMPtr <nsIMsgFilterList> filterList;
nsresult rv = mServer->GetFilterList(nullptr, getter_AddRefs(filterList));
NS_ENSURE_SUCCESS(rv, rv);
nsCOMPtr<nsIMsgFilter> filter;
rv = filterList->CreateFilter(EmptyString(), getter_AddRefs(filter));
NS_ENSURE_SUCCESS(rv, rv);
if (aIncoming)
filter->SetFilterType(nsMsgFilterType::InboxRule | nsMsgFilterType::Manual);
else
filter->SetFilterType(nsMsgFilterType::PostOutgoing | nsMsgFilterType::Manual);
filter->SetEnabled(true);
filter.forget(_retval);
return NS_OK;
}
nsresult
nsBeckyFilters::AppendFilter(nsIMsgFilter *aFilter)
{
NS_ENSURE_STATE(mServer);
nsCOMPtr <nsIMsgFilterList> filterList;
nsresult rv = mServer->GetFilterList(nullptr, getter_AddRefs(filterList));
NS_ENSURE_SUCCESS(rv, rv);
uint32_t count;
rv = filterList->GetFilterCount(&count);
NS_ENSURE_SUCCESS(rv, rv);
return filterList->InsertFilterAt(count, aFilter);
}
nsresult
nsBeckyFilters::ParseFilterFile(nsIFile *aFile, bool aIncoming)
{
nsresult rv;
nsCOMPtr<nsILineInputStream> lineStream;
rv = nsBeckyUtils::CreateLineInputStream(aFile, getter_AddRefs(lineStream));
NS_ENSURE_SUCCESS(rv, rv);
bool more = true;
nsAutoCString line;
nsCOMPtr<nsIMsgFilter> filter;
while (NS_SUCCEEDED(rv) && more) {
rv = lineStream->ReadLine(line, &more);
switch (line.CharAt(0)) {
case ':':
if (line.EqualsLiteral(":Begin \"\"")) {
CreateFilter(aIncoming, getter_AddRefs(filter));
} else if (line.EqualsLiteral(":End \"\"")) {
if (filter)
AppendFilter(filter);
filter = nullptr;
}
break;
case '!':
SetRuleAction(line, filter);
break;
case '@':
SetSearchTerm(line, filter);
break;
case '$': // $X: disabled
if (StringBeginsWith(line, NS_LITERAL_CSTRING("$X")) && filter) {
filter->SetEnabled(false);
}
break;
default:
break;
}
}
return NS_OK;
}
NS_IMETHODIMP
nsBeckyFilters::Import(char16_t **aError,
bool *_retval)
{
NS_ENSURE_ARG_POINTER(aError);
NS_ENSURE_ARG_POINTER(_retval);
// If mLocation is null, set it to the default filter directory.
// If mLocation is a file, we import it as incoming folder.
// If mLocation is a directory, we try to import incoming and outgoing folders
// from it (in default files).
*_retval = false;
nsresult rv;
nsCOMPtr<nsIFile> filterFile;
bool haveFile = false;
if (!mLocation) {
bool retval = false;
rv = AutoLocate(nullptr, getter_AddRefs(mLocation), &retval);
NS_ENSURE_SUCCESS(rv, rv);
if (!retval)
return NS_ERROR_FILE_NOT_FOUND;
}
// What type of location do we have?
bool isDirectory = false;
rv = mLocation->IsDirectory(&isDirectory);
NS_ENSURE_SUCCESS(rv, rv);
if (isDirectory) {
haveFile = false;
} else {
bool isFile = false;
rv = mLocation->IsFile(&isFile);
NS_ENSURE_SUCCESS(rv, rv);
if (isFile) {
haveFile = true;
mLocation->Clone(getter_AddRefs(filterFile));
} else {
// mLocation is neither file nor directory.
return NS_ERROR_UNEXPECTED;
}
}
bool haveIncoming = true;
if (haveFile) {
// If the passed filename equals OFilter.def, import as outgoing filters.
// Everything else is considered incoming.
nsAutoString fileName;
rv = mLocation->GetLeafName(fileName);
NS_ENSURE_SUCCESS(rv, rv);
if (fileName.EqualsLiteral("OFilter.def"))
haveIncoming = false;
}
// Try importing from the passed in file or the default incoming filters file.
if ((haveFile && haveIncoming) || (!haveFile &&
NS_SUCCEEDED(GetFilterFile(true, mLocation, getter_AddRefs(filterFile)))))
{
rv = CollectServers();
NS_ENSURE_SUCCESS(rv, rv);
rv = nsBeckyUtils::ConvertToUTF8File(filterFile, getter_AddRefs(mConvertedFile));
NS_ENSURE_SUCCESS(rv, rv);
rv = ParseFilterFile(mConvertedFile, true);
if (NS_SUCCEEDED(rv))
*_retval = true;
(void)RemoveConvertedFile();
}
// If we didn't have a file passed (but a directory), try finding also outgoing filters.
if ((haveFile && !haveIncoming) || (!haveFile &&
NS_SUCCEEDED(GetFilterFile(false, mLocation, getter_AddRefs(filterFile)))))
{
rv = CollectServers();
NS_ENSURE_SUCCESS(rv, rv);
rv = nsBeckyUtils::ConvertToUTF8File(filterFile, getter_AddRefs(mConvertedFile));
NS_ENSURE_SUCCESS(rv, rv);
rv = ParseFilterFile(mConvertedFile, false);
if (NS_SUCCEEDED(rv))
*_retval = true;
(void)RemoveConvertedFile();
}
return rv;
}
nsresult
nsBeckyFilters::FindMessageFolder(const nsAString &aName,
nsIMsgFolder *aParentFolder,
nsIMsgFolder **_retval)
{
nsresult rv;
nsCOMPtr<nsIMsgFolder> found;
rv = aParentFolder->GetChildNamed(aName, getter_AddRefs(found));
if (found) {
found.forget(_retval);
return NS_OK;
}
nsCOMPtr<nsISimpleEnumerator> children;
rv = aParentFolder->GetSubFolders(getter_AddRefs(children));
NS_ENSURE_SUCCESS(rv, rv);
bool more;
nsCOMPtr<nsISupports> entry;
while (NS_SUCCEEDED(children->HasMoreElements(&more)) && more) {
rv = children->GetNext(getter_AddRefs(entry));
NS_ENSURE_SUCCESS(rv, rv);
nsCOMPtr<nsIMsgFolder> child = do_QueryInterface(entry, &rv);
NS_ENSURE_SUCCESS(rv, rv);
rv = FindMessageFolder(aName, child, getter_AddRefs(found));
if (found) {
found.forget(_retval);
return NS_OK;
}
}
return NS_MSG_ERROR_INVALID_FOLDER_NAME;
}
nsresult
nsBeckyFilters::FindMessageFolderInServer(const nsAString &aName,
nsIMsgIncomingServer *aServer,
nsIMsgFolder **_retval)
{
nsresult rv;
nsCOMPtr <nsIMsgFolder> rootFolder;
rv = aServer->GetRootMsgFolder(getter_AddRefs(rootFolder));
NS_ENSURE_SUCCESS(rv, rv);
return FindMessageFolder(aName, rootFolder, _retval);
}
nsresult
nsBeckyFilters::GetMessageFolder(const nsAString &aName,
nsIMsgFolder **_retval)
{
nsresult rv;
nsCOMPtr<nsIMsgAccountManager> accountManager;
accountManager = do_GetService(NS_MSGACCOUNTMANAGER_CONTRACTID, &rv);
NS_ENSURE_SUCCESS(rv, rv);
nsCOMPtr<nsIArray> accounts;
rv = accountManager->GetAccounts(getter_AddRefs(accounts));
NS_ENSURE_SUCCESS(rv, rv);
uint32_t accountCount;
rv = accounts->GetLength(&accountCount);
NS_ENSURE_SUCCESS(rv, rv);
nsCOMPtr<nsIMsgFolder> found;
for (uint32_t i = 0; i < accountCount; i++) {
nsCOMPtr<nsIMsgAccount> account(do_QueryElementAt(accounts, i));
if (!account)
continue;
nsCOMPtr<nsIMsgIncomingServer> server;
account->GetIncomingServer(getter_AddRefs(server));
if (!server)
continue;
FindMessageFolderInServer(aName, server, getter_AddRefs(found));
if (found)
break;
}
if (!found) {
nsCOMPtr<nsIMsgIncomingServer> server;
rv = accountManager->GetLocalFoldersServer(getter_AddRefs(server));
NS_ENSURE_SUCCESS(rv, rv);
FindMessageFolderInServer(aName, server, getter_AddRefs(found));
}
if (!found)
return NS_MSG_ERROR_INVALID_FOLDER_NAME;
found.forget(_retval);
return NS_OK;
}
nsresult
nsBeckyFilters::CollectServers()
{
nsresult rv;
nsCOMPtr<nsIMsgAccountManager> accountManager;
accountManager = do_GetService(NS_MSGACCOUNTMANAGER_CONTRACTID, &rv);
NS_ENSURE_SUCCESS(rv, rv);
nsCOMPtr<nsIMsgAccount> defaultAccount;
rv = accountManager->GetDefaultAccount(getter_AddRefs(defaultAccount));
NS_ENSURE_SUCCESS(rv, rv);
nsCOMPtr<nsIMsgIncomingServer> server;
return defaultAccount->GetIncomingServer(getter_AddRefs(mServer));
}
nsresult
nsBeckyFilters::RemoveConvertedFile()
{
nsresult rv = NS_OK;
if (mConvertedFile) {
bool exists = false;
mConvertedFile->Exists(&exists);
if (exists) {
rv = mConvertedFile->Remove(false);
if (NS_SUCCEEDED(rv))
mConvertedFile = nullptr;
}
}
return rv;
}

View file

@ -0,0 +1,77 @@
/* vim: set ts=2 et sw=2 tw=80: */
/* 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 nsBeckyFilters_h___
#define nsBeckyFilters_h___
#include "nsIImportFilters.h"
#include "nsIFile.h"
#include "nsIMsgIncomingServer.h"
#include "nsMsgFilterCore.h"
class nsIMsgFilter;
class nsIMsgRuleAction;
class nsCString;
class nsBeckyFilters final : public nsIImportFilters
{
public:
nsBeckyFilters();
static nsresult Create(nsIImportFilters **aImport);
NS_DECL_ISUPPORTS
NS_DECL_NSIIMPORTFILTERS
private:
virtual ~nsBeckyFilters();
nsCOMPtr<nsIFile> mLocation;
nsCOMPtr<nsIMsgIncomingServer> mServer;
nsCOMPtr<nsIFile> mConvertedFile;
nsresult GetDefaultFilterLocation(nsIFile **aFile);
nsresult GetFilterFile(bool aIncoming, nsIFile *aLocation, nsIFile **aFile);
nsresult ParseFilterFile(nsIFile *aFile, bool aIncoming);
nsresult ParseRuleLine(const nsCString &aLine,
nsMsgSearchAttribValue *aSearchAttribute,
nsMsgSearchOpValue *aSearchOperator,
nsString &aSearchKeyword);
nsresult CollectServers();
nsresult FindMessageFolder(const nsAString& aName,
nsIMsgFolder *aParantFolder,
nsIMsgFolder **_retval);
nsresult FindMessageFolderInServer(const nsAString& aName,
nsIMsgIncomingServer *aServer,
nsIMsgFolder **_retval);
nsresult GetMessageFolder(const nsAString& aName, nsIMsgFolder **_retval);
nsresult GetActionTarget(const nsCString &aLine, nsCString &aTarget);
nsresult GetFolderNameFromTarget(const nsCString &aTarget, nsAString &aName);
nsresult GetDistributeTarget(const nsCString &aLine,
nsCString &aTargetFolder);
nsresult GetResendTarget(const nsCString &aLine,
nsCString &aTemplate,
nsCString &aTargetAddress);
nsresult CreateRuleAction(nsIMsgFilter *aFilter,
nsMsgRuleActionType actionType,
nsIMsgRuleAction **_retval);
nsresult CreateDistributeAction(const nsCString &aLine,
nsIMsgFilter *aFilter,
const nsMsgRuleActionType &aActionType,
nsIMsgRuleAction **_retval);
nsresult CreateLeaveOrDeleteAction(const nsCString &aLine,
nsIMsgFilter *aFilter,
nsIMsgRuleAction **_retval);
nsresult CreateResendAction(const nsCString &aLine,
nsIMsgFilter *aFilter,
const nsMsgRuleActionType &aActionType,
nsIMsgRuleAction **_retval);
nsresult CreateFilter(bool aIncoming, nsIMsgFilter **_retval);
nsresult AppendFilter(nsIMsgFilter *aFilter);
nsresult SetRuleAction(const nsCString &aLine, nsIMsgFilter *aFilter);
nsresult SetSearchTerm(const nsCString &aLine, nsIMsgFilter *aFilter);
nsresult RemoveConvertedFile();
};
#endif /* nsBeckyFilters_h___ */

View file

@ -0,0 +1,168 @@
/* vim: set ts=2 et sw=2 tw=80: */
/* 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 "nscore.h"
#include "nsIServiceManager.h"
#include "nsIImportService.h"
#include "nsIComponentManager.h"
#include "nsIMemory.h"
#include "nsIImportMail.h"
#include "nsIImportMailboxDescriptor.h"
#include "nsIImportGeneric.h"
#include "nsIImportAddressBooks.h"
#include "nsIImportABDescriptor.h"
#include "nsIImportSettings.h"
#include "nsIImportFilters.h"
#include "nsIImportFieldMap.h"
#include "nsXPCOM.h"
#include "nsISupportsPrimitives.h"
#include "nsIOutputStream.h"
#include "nsIAddrDatabase.h"
#include "nsTextFormatter.h"
#include "nsIStringBundle.h"
#include "nsUnicharUtils.h"
#include "nsIMsgTagService.h"
#include "nsMsgBaseCID.h"
#include "nsCOMPtr.h"
#include "nsServiceManagerUtils.h"
#include "nsComponentManagerUtils.h"
#include "nsBeckyImport.h"
#include "nsBeckyMail.h"
#include "nsBeckyAddressBooks.h"
#include "nsBeckySettings.h"
#include "nsBeckyFilters.h"
#include "nsBeckyStringBundle.h"
nsBeckyImport::nsBeckyImport()
{
}
nsBeckyImport::~nsBeckyImport()
{
}
NS_IMPL_ISUPPORTS(nsBeckyImport, nsIImportModule)
NS_IMETHODIMP
nsBeckyImport::GetName(char16_t **aName)
{
NS_ENSURE_ARG_POINTER(aName);
*aName =
nsBeckyStringBundle::GetStringByName(u"BeckyImportName");
return NS_OK;
}
NS_IMETHODIMP
nsBeckyImport::GetDescription(char16_t **aDescription)
{
NS_ENSURE_ARG_POINTER(aDescription);
*aDescription =
nsBeckyStringBundle::GetStringByName(u"BeckyImportDescription");
return NS_OK;
}
NS_IMETHODIMP
nsBeckyImport::GetSupports(char **aSupports)
{
NS_ENSURE_ARG_POINTER(aSupports);
*aSupports = strdup(kBeckySupportsString);
return NS_OK;
}
NS_IMETHODIMP
nsBeckyImport::GetSupportsUpgrade(bool *aUpgrade)
{
NS_ENSURE_ARG_POINTER(aUpgrade);
*aUpgrade = true;
return NS_OK;
}
nsresult
nsBeckyImport::GetMailImportInterface(nsISupports **aInterface)
{
nsCOMPtr<nsIImportMail> importer;
nsresult rv = nsBeckyMail::Create(getter_AddRefs(importer));
NS_ENSURE_SUCCESS(rv, rv);
nsCOMPtr<nsIImportService> importService(do_GetService(NS_IMPORTSERVICE_CONTRACTID, &rv));
NS_ENSURE_SUCCESS(rv, rv);
nsCOMPtr<nsIImportGeneric> generic;
rv = importService->CreateNewGenericMail(getter_AddRefs(generic));
NS_ENSURE_SUCCESS(rv, rv);
generic->SetData("mailInterface", importer);
nsString name;
name.Adopt(nsBeckyStringBundle::GetStringByName(u"BeckyImportName"));
nsCOMPtr<nsISupportsString> nameString(do_CreateInstance(NS_SUPPORTS_STRING_CONTRACTID, &rv));
NS_ENSURE_SUCCESS(rv, rv);
nameString->SetData(name);
generic->SetData("name", nameString);
return CallQueryInterface(generic, aInterface);
}
nsresult
nsBeckyImport::GetAddressBookImportInterface(nsISupports **aInterface)
{
nsresult rv;
nsCOMPtr<nsIImportAddressBooks> importer;
rv = nsBeckyAddressBooks::Create(getter_AddRefs(importer));
NS_ENSURE_SUCCESS(rv, rv);
nsCOMPtr<nsIImportService> importService(do_GetService(NS_IMPORTSERVICE_CONTRACTID, &rv));
NS_ENSURE_SUCCESS(rv, rv);
nsCOMPtr<nsIImportGeneric> generic;
rv = importService->CreateNewGenericAddressBooks(getter_AddRefs(generic));
NS_ENSURE_SUCCESS(rv, rv);
generic->SetData("addressInterface", importer);
return CallQueryInterface(generic, aInterface);
}
nsresult
nsBeckyImport::GetSettingsImportInterface(nsISupports **aInterface)
{
nsresult rv;
nsCOMPtr<nsIImportSettings> importer;
rv = nsBeckySettings::Create(getter_AddRefs(importer));
NS_ENSURE_SUCCESS(rv, rv);
return CallQueryInterface(importer, aInterface);
}
nsresult
nsBeckyImport::GetFiltersImportInterface(nsISupports **aInterface)
{
nsresult rv;
nsCOMPtr<nsIImportFilters> importer;
rv = nsBeckyFilters::Create(getter_AddRefs(importer));
NS_ENSURE_SUCCESS(rv, rv);
return CallQueryInterface(importer, aInterface);
}
NS_IMETHODIMP
nsBeckyImport::GetImportInterface(const char *aImportType, nsISupports **aInterface)
{
NS_ENSURE_ARG_POINTER(aImportType);
NS_ENSURE_ARG_POINTER(aInterface);
*aInterface = nullptr;
if (!strcmp(aImportType, "mail"))
return GetMailImportInterface(aInterface);
if (!strcmp(aImportType, "addressbook"))
return GetAddressBookImportInterface(aInterface);
if (!strcmp(aImportType, "settings"))
return GetSettingsImportInterface(aInterface);
if (!strcmp(aImportType, "filters"))
return GetFiltersImportInterface(aInterface);
return NS_ERROR_NOT_AVAILABLE;
}

View file

@ -0,0 +1,36 @@
/* vim: set ts=2 et sw=2 tw=80: */
/* 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 nsBeckyImport_h___
#define nsBeckyImport_h___
#include "nsIImportModule.h"
#define NS_BECKYIMPORT_CID \
{ \
0x7952a6cf, 0x2442,0x4c04, \
{0x9f, 0x02, 0x15, 0x0b, 0x15, 0xa0, 0xa8, 0x41}}
#define kBeckySupportsString NS_IMPORT_MAIL_STR "," NS_IMPORT_ADDRESS_STR "," NS_IMPORT_SETTINGS_STR "," NS_IMPORT_FILTERS_STR
class nsBeckyImport final : public nsIImportModule
{
public:
nsBeckyImport();
NS_DECL_ISUPPORTS
NS_DECL_NSIIMPORTMODULE
private:
virtual ~nsBeckyImport();
nsresult GetMailImportInterface(nsISupports **aInterface);
nsresult GetAddressBookImportInterface(nsISupports **aInterface);
nsresult GetSettingsImportInterface(nsISupports **aInterface);
nsresult GetFiltersImportInterface(nsISupports **aInterface);
};
#endif /* nsBeckyImport_h___ */

View file

@ -0,0 +1,641 @@
/* vim: set ts=2 et sw=2 tw=80: */
/* 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 "nsString.h"
#include "nsCOMPtr.h"
#include "nsIFile.h"
#include "nsIInputStream.h"
#include "nsIOutputStream.h"
#include "nsILineInputStream.h"
#include "nsNetUtil.h"
#include "nsIArray.h"
#include "nsIImportService.h"
#include "nsIImportMailboxDescriptor.h"
#include "nsIMsgHdr.h"
#include "nsIMsgFolder.h"
#include "nsIMsgPluggableStore.h"
#include "nsIMutableArray.h"
#include "nsMsgUtils.h"
#include "nsMsgLocalFolderHdrs.h"
#include "nsMsgMessageFlags.h"
#include "nsTArray.h"
#include "nspr.h"
#include "nsIStringBundle.h"
#include "nsThreadUtils.h"
#include "nsBeckyMail.h"
#include "nsBeckyUtils.h"
#include "nsBeckyStringBundle.h"
#define FROM_LINE "From - Mon Jan 1 00:00:00 1965" MSG_LINEBREAK
#define X_BECKY_STATUS_HEADER "X-Becky-Status"
#define X_BECKY_INCLUDE_HEADER "X-Becky-Include"
enum {
BECKY_STATUS_READ = 1 << 0,
BECKY_STATUS_FORWARDED = 1 << 1,
BECKY_STATUS_REPLIED = 1 << 2
};
NS_IMPL_ISUPPORTS(nsBeckyMail, nsIImportMail)
nsresult
nsBeckyMail::Create(nsIImportMail **aImport)
{
NS_ENSURE_ARG_POINTER(aImport);
*aImport = new nsBeckyMail();
NS_ADDREF(*aImport);
return NS_OK;
}
nsBeckyMail::nsBeckyMail()
: mReadBytes(0)
{
}
nsBeckyMail::~nsBeckyMail()
{
}
NS_IMETHODIMP
nsBeckyMail::GetDefaultLocation(nsIFile **aLocation,
bool *aFound,
bool *aUserVerify)
{
NS_ENSURE_ARG_POINTER(aFound);
NS_ENSURE_ARG_POINTER(aLocation);
NS_ENSURE_ARG_POINTER(aUserVerify);
*aLocation = nullptr;
*aUserVerify = true;
*aFound = false;
if (NS_SUCCEEDED(nsBeckyUtils::GetDefaultMailboxDirectory(aLocation)))
*aFound = true;
return NS_OK;
}
nsresult
nsBeckyMail::CreateMailboxDescriptor(nsIImportMailboxDescriptor **aDescriptor)
{
nsresult rv;
nsCOMPtr<nsIImportService> importService;
importService = do_GetService(NS_IMPORTSERVICE_CONTRACTID, &rv);
NS_ENSURE_SUCCESS(rv, rv);
return importService->CreateNewMailboxDescriptor(aDescriptor);
}
nsresult
nsBeckyMail::GetMailboxName(nsIFile *aMailbox, nsAString &aName)
{
nsCOMPtr<nsIFile> iniFile;
nsBeckyUtils::GetMailboxINIFile(aMailbox, getter_AddRefs(iniFile));
if (iniFile) {
nsCOMPtr<nsIFile> convertedFile;
nsBeckyUtils::ConvertToUTF8File(iniFile, getter_AddRefs(convertedFile));
if (convertedFile) {
nsAutoCString utf8Name;
nsBeckyUtils::GetMailboxNameFromINIFile(convertedFile, utf8Name);
convertedFile->Remove(false);
CopyUTF8toUTF16(utf8Name, aName);
}
}
if (aName.IsEmpty()) {
nsAutoString name;
aMailbox->GetLeafName(name);
name.Trim("!", true, false);
aName.Assign(name);
}
return NS_OK;
}
nsresult
nsBeckyMail::AppendMailboxDescriptor(nsIFile *aEntry,
const nsString &aName,
uint32_t aDepth,
nsIMutableArray *aCollected)
{
nsresult rv;
nsCOMPtr<nsIImportMailboxDescriptor> descriptor;
rv = CreateMailboxDescriptor(getter_AddRefs(descriptor));
NS_ENSURE_SUCCESS(rv, rv);
int64_t size;
rv = aEntry->GetFileSize(&size);
NS_ENSURE_SUCCESS(rv, rv);
rv = descriptor->SetSize(size);
NS_ENSURE_SUCCESS(rv, rv);
rv = descriptor->SetDisplayName(aName.get());
NS_ENSURE_SUCCESS(rv, rv);
nsCOMPtr<nsIFile> mailboxFile;
rv = descriptor->GetFile(getter_AddRefs(mailboxFile));
NS_ENSURE_SUCCESS(rv, rv);
descriptor->SetDepth(aDepth);
mailboxFile->InitWithFile(aEntry);
aCollected->AppendElement(descriptor, false);
return NS_OK;
}
nsresult
nsBeckyMail::CollectMailboxesInFolderListFile(nsIFile *aListFile,
uint32_t aDepth,
nsIMutableArray *aCollected)
{
nsresult rv;
nsCOMPtr<nsILineInputStream> lineStream;
rv = nsBeckyUtils::CreateLineInputStream(aListFile,
getter_AddRefs(lineStream));
NS_ENSURE_SUCCESS(rv, rv);
nsCOMPtr<nsIFile> parent;
rv = aListFile->GetParent(getter_AddRefs(parent));
NS_ENSURE_SUCCESS(rv, rv);
bool more = true;
nsAutoCString folderName;
bool isEmpty = true;
while (more && NS_SUCCEEDED(rv)) {
rv = lineStream->ReadLine(folderName, &more);
NS_ENSURE_SUCCESS(rv, rv);
if (folderName.IsEmpty())
continue;
nsCOMPtr<nsIFile> folder;
rv = parent->Clone(getter_AddRefs(folder));
NS_ENSURE_SUCCESS(rv, rv);
rv = folder->AppendNative(folderName);
NS_ENSURE_SUCCESS(rv, rv);
isEmpty = false;
rv = CollectMailboxesInDirectory(folder, aDepth + 1, aCollected);
}
return isEmpty ? NS_ERROR_FILE_NOT_FOUND : NS_OK;
}
nsresult
nsBeckyMail::CollectMailboxesInDirectory(nsIFile *aDirectory,
uint32_t aDepth,
nsIMutableArray *aCollected)
{
nsAutoString mailboxName;
nsresult rv = GetMailboxName(aDirectory, mailboxName);
NS_ENSURE_SUCCESS(rv, rv);
if (aDepth != 0)
AppendMailboxDescriptor(aDirectory, mailboxName, aDepth, aCollected);
nsCOMPtr<nsIFile> folderListFile;
rv = nsBeckyUtils::GetFolderListFile(aDirectory, getter_AddRefs(folderListFile));
bool folderListExists = false;
if (NS_SUCCEEDED(rv)) {
rv = CollectMailboxesInFolderListFile(folderListFile, aDepth, aCollected);
folderListExists = true;
}
nsCOMPtr<nsISimpleEnumerator> entries;
rv = aDirectory->GetDirectoryEntries(getter_AddRefs(entries));
NS_ENSURE_SUCCESS(rv, rv);
bool more;
while (NS_SUCCEEDED(entries->HasMoreElements(&more)) && more) {
nsCOMPtr<nsISupports> entry;
rv = entries->GetNext(getter_AddRefs(entry));
NS_ENSURE_SUCCESS(rv, rv);
nsCOMPtr<nsIFile> file = do_QueryInterface(entry, &rv);
NS_ENSURE_SUCCESS(rv, rv);
nsAutoString name;
rv = file->GetLeafName(name);
NS_ENSURE_SUCCESS(rv, rv);
if (StringEndsWith(name, NS_LITERAL_STRING(".bmf"))) {
AppendMailboxDescriptor(file, mailboxName, aDepth, aCollected);
}
// The Folder.lst file is not created if there is only one sub folder,
// so we need to find the sub folder by our hands.
// The folder name does not begin with # or ! maybe. Yes, maybe...
if (!folderListExists) {
if (StringBeginsWith(name, NS_LITERAL_STRING("#")) ||
StringBeginsWith(name, NS_LITERAL_STRING("!")))
continue;
bool isDirectory = false;
rv = file->IsDirectory(&isDirectory);
if (isDirectory) {
CollectMailboxesInDirectory(file, aDepth + 1, aCollected);
continue;
}
}
}
return NS_OK;
}
NS_IMETHODIMP
nsBeckyMail::FindMailboxes(nsIFile *aLocation, nsIArray **_retval)
{
NS_ENSURE_ARG_POINTER(aLocation);
NS_ENSURE_ARG_POINTER(_retval);
nsresult rv;
nsCOMPtr<nsIMutableArray> array(do_CreateInstance(NS_ARRAY_CONTRACTID, &rv));
NS_ENSURE_SUCCESS(rv, rv);
rv = CollectMailboxesInDirectory(aLocation, 0, array);
NS_ENSURE_SUCCESS(rv, rv);
array.forget(_retval);
return NS_OK;
}
static nsresult
GetBeckyStatusValue(const nsCString &aHeader, nsACString &aValue)
{
int32_t valueStartPosition;
valueStartPosition = aHeader.FindChar(':');
if (valueStartPosition < 0)
return NS_ERROR_UNEXPECTED;
valueStartPosition++;
int32_t commaPosition = aHeader.FindChar(',', valueStartPosition);
if (commaPosition < 0)
return NS_ERROR_UNEXPECTED;
nsAutoCString value(Substring(aHeader,
valueStartPosition,
commaPosition - valueStartPosition));
value.Trim(" \t");
aValue.Assign(value);
return NS_OK;
}
static nsresult
GetBeckyIncludeValue(const nsCString &aHeader, nsACString &aValue)
{
int32_t valueStartPosition;
valueStartPosition = aHeader.FindChar(':');
if (valueStartPosition < 0)
return NS_ERROR_FAILURE;
valueStartPosition++;
nsAutoCString value(Substring(aHeader, valueStartPosition));
value.Trim(" \t");
aValue.Assign(value);
return NS_OK;
}
static bool
ConvertBeckyStatusToMozillaStatus(const nsCString &aHeader,
nsMsgMessageFlagType *aMozillaStatusFlag)
{
nsresult rv;
nsAutoCString statusString;
rv = GetBeckyStatusValue(aHeader, statusString);
NS_ENSURE_SUCCESS(rv, false);
nsresult errorCode;
uint32_t beckyStatusFlag = static_cast<uint32_t>(statusString.ToInteger(&errorCode, 16));
if (NS_FAILED(errorCode))
return false;
if (beckyStatusFlag & BECKY_STATUS_READ)
*aMozillaStatusFlag |= nsMsgMessageFlags::Read;
if (beckyStatusFlag & BECKY_STATUS_FORWARDED)
*aMozillaStatusFlag |= nsMsgMessageFlags::Forwarded;
if (beckyStatusFlag & BECKY_STATUS_REPLIED)
*aMozillaStatusFlag |= nsMsgMessageFlags::Replied;
return true;
}
static inline bool
CheckHeaderKey(const nsCString &aHeader, const char *aKeyString)
{
nsAutoCString key(StringHead(aHeader, aHeader.FindChar(':')));
key.Trim(" \t");
return key.Equals(aKeyString);
}
static inline bool
IsBeckyStatusHeader(const nsCString &aHeader)
{
return CheckHeaderKey(aHeader, X_BECKY_STATUS_HEADER);
}
static inline bool
IsBeckyIncludeLine(const nsCString &aLine)
{
return CheckHeaderKey(aLine, X_BECKY_INCLUDE_HEADER);
}
static inline bool
IsEndOfHeaders(const nsCString &aLine)
{
return aLine.IsEmpty();
}
static inline bool
IsEndOfMessage(const nsCString &aLine)
{
return aLine.Equals(".");
}
class ImportMessageRunnable: public mozilla::Runnable
{
public:
ImportMessageRunnable(nsIFile *aMessageFile,
nsIMsgFolder *aFolder);
NS_DECL_NSIRUNNABLE
private:
nsresult WriteHeaders(nsCString &aHeaders, nsIOutputStream *aOutputStream);
nsresult HandleHeaderLine(const nsCString &aHeaderLine, nsACString &aHeaders);
nsresult GetAttachmentFile(nsIFile *aMailboxFile,
const nsCString &aHeader,
nsIFile **_retval);
nsresult WriteAttachmentFile(nsIFile *aMailboxFile,
const nsCString &aHeader,
nsIOutputStream *aOutputStream);
nsCOMPtr<nsIFile> mMessageFile;
nsCOMPtr<nsIMsgFolder> mFolder;
};
ImportMessageRunnable::ImportMessageRunnable(nsIFile *aMessageFile,
nsIMsgFolder *aFolder) :
mMessageFile(aMessageFile), mFolder(aFolder)
{
}
nsresult
ImportMessageRunnable::WriteHeaders(nsCString &aHeaders,
nsIOutputStream *aOutputStream)
{
nsresult rv;
uint32_t writtenBytes = 0;
rv = aOutputStream->Write(FROM_LINE, strlen(FROM_LINE), &writtenBytes);
NS_ENSURE_SUCCESS(rv, rv);
rv = aOutputStream->Write(aHeaders.get(), aHeaders.Length(), &writtenBytes);
NS_ENSURE_SUCCESS(rv, rv);
rv = aOutputStream->Write(MSG_LINEBREAK, strlen(MSG_LINEBREAK), &writtenBytes);
NS_ENSURE_SUCCESS(rv, rv);
aHeaders.Truncate();
return NS_OK;
}
nsresult
ImportMessageRunnable::HandleHeaderLine(const nsCString &aHeaderLine,
nsACString &aHeaders)
{
aHeaders.Append(aHeaderLine);
aHeaders.AppendLiteral(MSG_LINEBREAK);
nsMsgMessageFlagType flag = 0;
if (IsBeckyStatusHeader(aHeaderLine) &&
ConvertBeckyStatusToMozillaStatus(aHeaderLine, &flag)) {
char *statusLine;
statusLine = PR_smprintf(X_MOZILLA_STATUS_FORMAT MSG_LINEBREAK, flag);
aHeaders.Append(statusLine);
PR_smprintf_free(statusLine);
aHeaders.AppendLiteral(X_MOZILLA_KEYWORDS);
}
return NS_OK;
}
nsresult
ImportMessageRunnable::GetAttachmentFile(nsIFile *aMailboxFile,
const nsCString &aHeader,
nsIFile **_retval)
{
nsresult rv;
nsCOMPtr<nsIFile> attachmentFile;
rv = aMailboxFile->Clone(getter_AddRefs(attachmentFile));
NS_ENSURE_SUCCESS(rv, rv);
rv = attachmentFile->Append(NS_LITERAL_STRING("#Attach"));
NS_ENSURE_SUCCESS(rv, rv);
nsAutoCString nativeAttachmentPath;
rv = GetBeckyIncludeValue(aHeader, nativeAttachmentPath);
NS_ENSURE_SUCCESS(rv, rv);
rv = attachmentFile->AppendRelativeNativePath(nativeAttachmentPath);
NS_ENSURE_SUCCESS(rv, rv);
bool exists = false;
attachmentFile->Exists(&exists);
if (!exists)
return NS_ERROR_FILE_NOT_FOUND;
attachmentFile.forget(_retval);
return NS_OK;
}
nsresult
ImportMessageRunnable::WriteAttachmentFile(nsIFile *aMailboxFile,
const nsCString &aHeader,
nsIOutputStream *aOutputStream)
{
nsresult rv;
nsCOMPtr<nsIFile> parentDirectory;
rv = aMailboxFile->GetParent(getter_AddRefs(parentDirectory));
NS_ENSURE_SUCCESS(rv, rv);
nsCOMPtr<nsIFile> attachmentFile;
rv = GetAttachmentFile(parentDirectory,
aHeader,
getter_AddRefs(attachmentFile));
NS_ENSURE_SUCCESS(rv, rv);
nsCOMPtr<nsIInputStream> inputStream;
rv = NS_NewLocalFileInputStream(getter_AddRefs(inputStream),
attachmentFile);
NS_ENSURE_SUCCESS(rv, rv);
char buffer[FILE_IO_BUFFER_SIZE];
uint32_t readBytes = 0;
uint32_t writtenBytes = 0;
rv = aOutputStream->Write(MSG_LINEBREAK, strlen(MSG_LINEBREAK), &writtenBytes);
while (NS_SUCCEEDED(inputStream->Read(buffer, sizeof(buffer), &readBytes)) &&
readBytes > 0) {
rv = aOutputStream->Write(buffer, readBytes, &writtenBytes);
if (NS_FAILED(rv))
break;
}
return rv;
}
NS_IMETHODIMP ImportMessageRunnable::Run()
{
nsCOMPtr<nsIMsgPluggableStore> msgStore;
nsresult rv = mFolder->GetMsgStore(getter_AddRefs(msgStore));
NS_ENSURE_SUCCESS(rv, rv);
nsCOMPtr<nsILineInputStream> lineStream;
rv = nsBeckyUtils::CreateLineInputStream(mMessageFile,
getter_AddRefs(lineStream));
NS_ENSURE_SUCCESS(rv, rv);
bool reusable;
nsCOMPtr<nsIMsgDBHdr> msgHdr;
nsCOMPtr<nsIOutputStream> outputStream;
rv = msgStore->GetNewMsgOutputStream(mFolder, getter_AddRefs(msgHdr), &reusable,
getter_AddRefs(outputStream));
NS_ENSURE_SUCCESS(rv, rv);
bool inHeader = true;
bool more = true;
nsAutoCString headers;
while (NS_SUCCEEDED(rv) && more) {
nsAutoCString line;
rv = lineStream->ReadLine(line, &more);
if (NS_FAILED(rv))
break;
if (inHeader) {
if (IsEndOfHeaders(line)) {
inHeader = false;
rv = WriteHeaders(headers, outputStream);
} else {
rv = HandleHeaderLine(line, headers);
}
} else if (IsEndOfMessage(line)) {
inHeader = true;
rv = msgStore->FinishNewMessage(outputStream, msgHdr);
if (!reusable)
outputStream->Close();
rv = msgStore->GetNewMsgOutputStream(mFolder, getter_AddRefs(msgHdr), &reusable,
getter_AddRefs(outputStream));
} else if (IsBeckyIncludeLine(line)) {
rv = WriteAttachmentFile(mMessageFile, line, outputStream);
} else {
uint32_t writtenBytes = 0;
if (StringBeginsWith(line, NS_LITERAL_CSTRING("..")))
line.Cut(0, 1);
else if (CheckHeaderKey(line, "From"))
line.Insert('>', 0);
line.AppendLiteral(MSG_LINEBREAK);
rv = outputStream->Write(line.get(), line.Length(), &writtenBytes);
}
}
if (outputStream) {
if (NS_FAILED(rv))
msgStore->DiscardNewMessage(outputStream, msgHdr);
outputStream->Close();
}
return rv;
}
static
nsresult ProxyImportMessage(nsIFile *aMessageFile,
nsIMsgFolder *aFolder)
{
RefPtr<ImportMessageRunnable> importMessage =
new ImportMessageRunnable(aMessageFile, aFolder);
return NS_DispatchToMainThread(importMessage, NS_DISPATCH_SYNC);
}
nsresult
nsBeckyMail::ImportMailFile(nsIFile *aMailFile,
nsIMsgFolder *aDestination)
{
int64_t size;
aMailFile->GetFileSize(&size);
if (size == 0)
return NS_OK;
return ProxyImportMessage(aMailFile, aDestination);
}
NS_IMETHODIMP
nsBeckyMail::ImportMailbox(nsIImportMailboxDescriptor *aSource,
nsIMsgFolder *aDestination,
char16_t **aErrorLog,
char16_t **aSuccessLog,
bool *aFatalError)
{
NS_ENSURE_ARG_POINTER(aSource);
NS_ENSURE_ARG_POINTER(aDestination);
NS_ENSURE_ARG_POINTER(aErrorLog);
NS_ENSURE_ARG_POINTER(aSuccessLog);
NS_ENSURE_ARG_POINTER(aFatalError);
mReadBytes = 0;
nsresult rv;
nsCOMPtr<nsIFile> mailboxFolder;
rv = aSource->GetFile(getter_AddRefs(mailboxFolder));
NS_ENSURE_SUCCESS(rv, rv);
rv = ImportMailFile(mailboxFolder, aDestination);
NS_ENSURE_SUCCESS(rv, rv);
uint32_t finalSize;
aSource->GetSize(&finalSize);
mReadBytes = finalSize;
nsAutoString name;
aSource->GetDisplayName(getter_Copies(name));
nsAutoString successMessage;
const char16_t *format = { name.get() };
rv =
nsBeckyStringBundle::FormatStringFromName(u"BeckyImportMailboxSuccess",
&format,
1,
getter_Copies(successMessage));
successMessage.AppendLiteral("\n");
*aSuccessLog = ToNewUnicode(successMessage);
return rv;
}
NS_IMETHODIMP
nsBeckyMail::GetImportProgress(uint32_t *_retval)
{
NS_ENSURE_ARG_POINTER(_retval);
*_retval = mReadBytes;
return NS_OK;
}
NS_IMETHODIMP
nsBeckyMail::TranslateFolderName(const nsAString & aFolderName,
nsAString & _retval)
{
return nsBeckyUtils::TranslateFolderName(aFolderName, _retval);
}

View file

@ -0,0 +1,45 @@
/* vim: set ts=2 et sw=2 tw=80: */
/* 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 nsBeckyMail_h___
#define nsBeckyMail_h___
#include "nsIImportMail.h"
class nsIFile;
class nsIMutableArray;
class nsIMsgFolder;
class nsBeckyMail final : public nsIImportMail
{
public:
nsBeckyMail();
static nsresult Create(nsIImportMail **aImport);
NS_DECL_ISUPPORTS
NS_DECL_NSIIMPORTMAIL
private:
virtual ~nsBeckyMail();
uint32_t mReadBytes;
nsresult CollectMailboxesInDirectory(nsIFile *aDirectory,
uint32_t aDepth,
nsIMutableArray *aCollected);
nsresult CollectMailboxesInFolderListFile(nsIFile *aListFile,
uint32_t aDepth,
nsIMutableArray *aCollected);
nsresult AppendMailboxDescriptor(nsIFile *aEntry,
const nsString &aName,
uint32_t aDepth,
nsIMutableArray *aCollected);
nsresult ImportMailFile(nsIFile *aMailFile,
nsIMsgFolder *aDestination);
nsresult CreateMailboxDescriptor(nsIImportMailboxDescriptor **aDescriptor);
nsresult GetMailboxName(nsIFile *aMailbox, nsAString &aName);
};
#endif /* nsBeckyMail_h___ */

View file

@ -0,0 +1,471 @@
/* vim: set ts=2 et sw=2 tw=80: */
/* 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 "nsMsgBaseCID.h"
#include "nsMsgCompCID.h"
#include "nsIMsgAccountManager.h"
#include "nsServiceManagerUtils.h"
#include "nsIINIParser.h"
#include "nsISmtpService.h"
#include "nsISmtpServer.h"
#include "nsIPop3IncomingServer.h"
#include "nsIStringEnumerator.h"
#include "nsIInputStream.h"
#include "nsIOutputStream.h"
#include "nsILineInputStream.h"
#include "nsNetUtil.h"
#include "nsString.h"
#include "msgCore.h"
#include "nsIStringBundle.h"
#include "nsBeckySettings.h"
#include "nsBeckyStringBundle.h"
#include "nsBeckyUtils.h"
NS_IMPL_ISUPPORTS(nsBeckySettings, nsIImportSettings)
nsresult
nsBeckySettings::Create(nsIImportSettings **aImport)
{
NS_ENSURE_ARG_POINTER(aImport);
*aImport = new nsBeckySettings();
NS_ADDREF(*aImport);
return NS_OK;
}
nsBeckySettings::nsBeckySettings()
{
}
nsBeckySettings::~nsBeckySettings()
{
}
NS_IMETHODIMP
nsBeckySettings::AutoLocate(char16_t **aDescription,
nsIFile **aLocation,
bool *_retval)
{
NS_ENSURE_ARG_POINTER(aDescription);
NS_ENSURE_ARG_POINTER(aLocation);
NS_ENSURE_ARG_POINTER(_retval);
*aDescription =
nsBeckyStringBundle::GetStringByName(u"BeckyImportName");
*aLocation = nullptr;
*_retval = false;
nsCOMPtr<nsIFile> location;
nsresult rv = nsBeckyUtils::GetDefaultMailboxINIFile(getter_AddRefs(location));
if (NS_FAILED(rv))
location = do_CreateInstance(NS_LOCAL_FILE_CONTRACTID, &rv);
else
*_retval = true;
location.forget(aLocation);
return NS_OK;
}
NS_IMETHODIMP
nsBeckySettings::SetLocation(nsIFile *aLocation)
{
mLocation = aLocation;
return NS_OK;
}
nsresult
nsBeckySettings::CreateParser()
{
if (!mLocation) {
nsresult rv = nsBeckyUtils::GetDefaultMailboxINIFile(getter_AddRefs(mLocation));
NS_ENSURE_SUCCESS(rv, rv);
}
// nsIINIParser accepts only UTF-8 encoding, so we need to convert the file
// first.
nsresult rv;
rv = nsBeckyUtils::ConvertToUTF8File(mLocation, getter_AddRefs(mConvertedFile));
NS_ENSURE_SUCCESS(rv, rv);
return nsBeckyUtils::CreateINIParserForFile(mConvertedFile,
getter_AddRefs(mParser));
}
nsresult
nsBeckySettings::CreateSmtpServer(const nsCString &aUserName,
const nsCString &aServerName,
nsISmtpServer **aServer,
bool *existing)
{
nsresult rv;
nsCOMPtr<nsISmtpService> smtpService = do_GetService(NS_SMTPSERVICE_CONTRACTID, &rv);
NS_ENSURE_SUCCESS(rv, rv);
nsCOMPtr<nsISmtpServer> server;
rv = smtpService->FindServer(aUserName.get(),
aServerName.get(),
getter_AddRefs(server));
if (NS_FAILED(rv) || !server) {
rv = smtpService->CreateServer(getter_AddRefs(server));
NS_ENSURE_SUCCESS(rv, rv);
server->SetHostname(aServerName);
server->SetUsername(aUserName);
*existing = false;
} else {
*existing = true;
}
server.forget(aServer);
return NS_OK;
}
nsresult
nsBeckySettings::CreateIncomingServer(const nsCString &aUserName,
const nsCString &aServerName,
const nsCString &aProtocol,
nsIMsgIncomingServer **aServer)
{
nsresult rv;
nsCOMPtr<nsIMsgAccountManager> accountManager = do_GetService(NS_MSGACCOUNTMANAGER_CONTRACTID, &rv);
NS_ENSURE_SUCCESS(rv, rv);
nsCOMPtr<nsIMsgIncomingServer> incomingServer;
rv = accountManager->FindServer(aUserName,
aServerName,
aProtocol,
getter_AddRefs(incomingServer));
if (NS_FAILED(rv) || !incomingServer) {
rv = accountManager->CreateIncomingServer(aUserName,
aServerName,
aProtocol,
getter_AddRefs(incomingServer));
NS_ENSURE_SUCCESS(rv, rv);
}
incomingServer.forget(aServer);
return NS_OK;
}
nsresult
nsBeckySettings::SetupSmtpServer(nsISmtpServer **aServer)
{
nsresult rv;
nsAutoCString userName, serverName;
mParser->GetString(NS_LITERAL_CSTRING("Account"),
NS_LITERAL_CSTRING("SMTPServer"),
serverName);
mParser->GetString(NS_LITERAL_CSTRING("Account"),
NS_LITERAL_CSTRING("UserID"),
userName);
nsCOMPtr<nsISmtpServer> server;
bool existing = false;
rv = CreateSmtpServer(userName, serverName, getter_AddRefs(server), &existing);
NS_ENSURE_SUCCESS(rv, rv);
// If we already have an existing server, do not touch it's settings.
if (existing) {
server.forget(aServer);
return NS_OK;
}
nsAutoCString value;
rv = mParser->GetString(NS_LITERAL_CSTRING("Account"),
NS_LITERAL_CSTRING("SMTPPort"),
value);
int32_t port = 25;
if (NS_SUCCEEDED(rv)) {
nsresult errorCode;
port = value.ToInteger(&errorCode, 10);
}
server->SetPort(port);
mParser->GetString(NS_LITERAL_CSTRING("Account"),
NS_LITERAL_CSTRING("SSLSMTP"),
value);
if (value.Equals("1"))
server->SetSocketType(nsMsgSocketType::SSL);
mParser->GetString(NS_LITERAL_CSTRING("Account"),
NS_LITERAL_CSTRING("SMTPAUTH"),
value);
if (value.Equals("1")) {
mParser->GetString(NS_LITERAL_CSTRING("Account"),
NS_LITERAL_CSTRING("SMTPAUTHMODE"),
value);
nsMsgAuthMethodValue authMethod = nsMsgAuthMethod::none;
if (value.Equals("1")) {
authMethod = nsMsgAuthMethod::passwordEncrypted;
} else if (value.Equals("2") ||
value.Equals("4") ||
value.Equals("6")) {
authMethod = nsMsgAuthMethod::passwordCleartext;
} else {
authMethod = nsMsgAuthMethod::anything;
}
server->SetAuthMethod(authMethod);
}
server.forget(aServer);
return NS_OK;
}
nsresult
nsBeckySettings::SetPop3ServerProperties(nsIMsgIncomingServer *aServer)
{
nsCOMPtr<nsIPop3IncomingServer> pop3Server = do_QueryInterface(aServer);
nsAutoCString value;
mParser->GetString(NS_LITERAL_CSTRING("Account"),
NS_LITERAL_CSTRING("POP3Auth"),
value); // 0: plain, 1: APOP, 2: CRAM-MD5, 3: NTLM
nsMsgAuthMethodValue authMethod;
if (value.IsEmpty() || value.Equals("0")) {
authMethod = nsMsgAuthMethod::passwordCleartext;
} else if (value.Equals("1")) {
authMethod = nsMsgAuthMethod::old;
} else if (value.Equals("2")) {
authMethod = nsMsgAuthMethod::passwordEncrypted;
} else if (value.Equals("3")) {
authMethod = nsMsgAuthMethod::NTLM;
} else {
authMethod = nsMsgAuthMethod::none;
}
aServer->SetAuthMethod(authMethod);
mParser->GetString(NS_LITERAL_CSTRING("Account"),
NS_LITERAL_CSTRING("LeaveServer"),
value);
if (value.Equals("1")) {
pop3Server->SetLeaveMessagesOnServer(true);
nsresult rv = mParser->GetString(NS_LITERAL_CSTRING("Account"),
NS_LITERAL_CSTRING("KeepDays"),
value);
if (NS_FAILED(rv))
return NS_OK;
nsresult errorCode;
int32_t leftDays = value.ToInteger(&errorCode, 10);
if (NS_SUCCEEDED(errorCode)) {
pop3Server->SetNumDaysToLeaveOnServer(leftDays);
pop3Server->SetDeleteByAgeFromServer(true);
}
}
return NS_OK;
}
nsresult
nsBeckySettings::SetupIncomingServer(nsIMsgIncomingServer **aServer)
{
nsAutoCString value;
mParser->GetString(NS_LITERAL_CSTRING("Account"),
NS_LITERAL_CSTRING("Protocol"),
value);
nsCString protocol;
if (value.Equals("1")) {
protocol = NS_LITERAL_CSTRING("imap");
} else {
protocol = NS_LITERAL_CSTRING("pop3");
}
nsAutoCString userName, serverName;
mParser->GetString(NS_LITERAL_CSTRING("Account"),
NS_LITERAL_CSTRING("MailServer"),
serverName);
mParser->GetString(NS_LITERAL_CSTRING("Account"),
NS_LITERAL_CSTRING("UserID"),
userName);
nsresult rv;
nsCOMPtr<nsIMsgIncomingServer> server;
rv = CreateIncomingServer(userName, serverName, protocol, getter_AddRefs(server));
NS_ENSURE_SUCCESS(rv, rv);
bool isSecure = false;
int32_t port = 0;
nsresult errorCode;
if (protocol.EqualsLiteral("pop3")) {
SetPop3ServerProperties(server);
rv = mParser->GetString(NS_LITERAL_CSTRING("Account"),
NS_LITERAL_CSTRING("POP3Port"),
value);
if (NS_SUCCEEDED(rv))
port = value.ToInteger(&errorCode, 10);
else
port = 110;
mParser->GetString(NS_LITERAL_CSTRING("Account"),
NS_LITERAL_CSTRING("SSLPOP"),
value);
if (value.Equals("1"))
isSecure = true;
} else if (protocol.EqualsLiteral("imap")) {
rv = mParser->GetString(NS_LITERAL_CSTRING("Account"),
NS_LITERAL_CSTRING("IMAP4Port"),
value);
if (NS_SUCCEEDED(rv))
port = value.ToInteger(&errorCode, 10);
else
port = 143;
mParser->GetString(NS_LITERAL_CSTRING("Account"),
NS_LITERAL_CSTRING("SSLIMAP"),
value);
if (value.Equals("1"))
isSecure = true;
}
server->SetPort(port);
if (isSecure)
server->SetSocketType(nsMsgSocketType::SSL);
mParser->GetString(NS_LITERAL_CSTRING("Account"),
NS_LITERAL_CSTRING("CheckInt"),
value);
if (value.Equals("1"))
server->SetDoBiff(true);
rv = mParser->GetString(NS_LITERAL_CSTRING("Account"),
NS_LITERAL_CSTRING("CheckEvery"),
value);
if (NS_SUCCEEDED(rv)) {
int32_t minutes = value.ToInteger(&errorCode, 10);
if (NS_SUCCEEDED(errorCode))
server->SetBiffMinutes(minutes);
}
server.forget(aServer);
return NS_OK;
}
nsresult
nsBeckySettings::CreateIdentity(nsIMsgIdentity **aIdentity)
{
nsAutoCString email, fullName, identityName, bccAddress;
mParser->GetString(NS_LITERAL_CSTRING("Account"),
NS_LITERAL_CSTRING("Name"),
identityName);
mParser->GetString(NS_LITERAL_CSTRING("Account"),
NS_LITERAL_CSTRING("YourName"),
fullName);
mParser->GetString(NS_LITERAL_CSTRING("Account"),
NS_LITERAL_CSTRING("MailAddress"),
email);
mParser->GetString(NS_LITERAL_CSTRING("Account"),
NS_LITERAL_CSTRING("PermBcc"),
bccAddress);
nsresult rv;
nsCOMPtr<nsIMsgAccountManager> accountManager =
do_GetService(NS_MSGACCOUNTMANAGER_CONTRACTID, &rv);
NS_ENSURE_SUCCESS(rv, rv);
nsCOMPtr<nsIMsgIdentity> identity;
rv = accountManager->CreateIdentity(getter_AddRefs(identity));
NS_ENSURE_SUCCESS(rv, rv);
identity->SetLabel(NS_ConvertUTF8toUTF16(identityName));
identity->SetFullName(NS_ConvertUTF8toUTF16(fullName));
identity->SetEmail(email);
if (!bccAddress.IsEmpty()) {
identity->SetDoBcc(true);
identity->SetDoBccList(bccAddress);
}
identity.forget(aIdentity);
return NS_OK;
}
nsresult
nsBeckySettings::CreateAccount(nsIMsgIdentity *aIdentity,
nsIMsgIncomingServer *aIncomingServer,
nsIMsgAccount **aAccount)
{
nsresult rv;
nsCOMPtr<nsIMsgAccountManager> accountManager =
do_GetService(NS_MSGACCOUNTMANAGER_CONTRACTID, &rv);
NS_ENSURE_SUCCESS(rv, rv);
nsCOMPtr<nsIMsgAccount> account;
rv = accountManager->CreateAccount(getter_AddRefs(account));
NS_ENSURE_SUCCESS(rv, rv);
rv = account->AddIdentity(aIdentity);
NS_ENSURE_SUCCESS(rv, rv);
rv = account->SetIncomingServer(aIncomingServer);
NS_ENSURE_SUCCESS(rv, rv);
account.forget(aAccount);
return NS_OK;
}
nsresult
nsBeckySettings::RemoveConvertedFile()
{
if (mConvertedFile) {
bool exists;
mConvertedFile->Exists(&exists);
if (exists)
mConvertedFile->Remove(false);
mConvertedFile = nullptr;
}
return NS_OK;
}
#define NS_RETURN_IF_FAILED_WITH_REMOVE_CONVERTED_FILE(expr, rv) \
if (NS_FAILED(expr)) { \
RemoveConvertedFile(); \
return rv; \
}
NS_IMETHODIMP
nsBeckySettings::Import(nsIMsgAccount **aLocalMailAccount,
bool *_retval)
{
NS_ENSURE_ARG_POINTER(aLocalMailAccount);
NS_ENSURE_ARG_POINTER(_retval);
nsresult rv = CreateParser();
NS_RETURN_IF_FAILED_WITH_REMOVE_CONVERTED_FILE(rv, rv);
nsCOMPtr<nsIMsgIncomingServer> incomingServer;
rv = SetupIncomingServer(getter_AddRefs(incomingServer));
NS_RETURN_IF_FAILED_WITH_REMOVE_CONVERTED_FILE(rv, rv);
nsCOMPtr<nsISmtpServer> smtpServer;
rv = SetupSmtpServer(getter_AddRefs(smtpServer));
NS_RETURN_IF_FAILED_WITH_REMOVE_CONVERTED_FILE(rv, rv);
nsCOMPtr<nsIMsgIdentity> identity;
rv = CreateIdentity(getter_AddRefs(identity));
NS_RETURN_IF_FAILED_WITH_REMOVE_CONVERTED_FILE(rv, rv);
nsAutoCString smtpKey;
smtpServer->GetKey(getter_Copies(smtpKey));
identity->SetSmtpServerKey(smtpKey);
nsCOMPtr<nsIMsgAccount> account;
rv = CreateAccount(identity, incomingServer, getter_AddRefs(account));
NS_RETURN_IF_FAILED_WITH_REMOVE_CONVERTED_FILE(rv, rv);
RemoveConvertedFile();
if (aLocalMailAccount)
account.forget(aLocalMailAccount);
*_retval = true;
return NS_OK;
}

View file

@ -0,0 +1,52 @@
/* vim: set ts=2 et sw=2 tw=80: */
/* 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 nsBeckySettings_h___
#define nsBeckySettings_h___
#include "nsIImportSettings.h"
#include "nsIFile.h"
#include "nsIINIParser.h"
class nsIMsgIncomingServer;
class nsIMsgIdentity;
class nsISmtpServer;
class nsBeckySettings final : public nsIImportSettings
{
public:
nsBeckySettings();
static nsresult Create(nsIImportSettings **aImport);
NS_DECL_ISUPPORTS
NS_DECL_NSIIMPORTSETTINGS
private:
virtual ~nsBeckySettings();
nsCOMPtr<nsIFile> mLocation;
nsCOMPtr<nsIFile> mConvertedFile;
nsCOMPtr<nsIINIParser> mParser;
nsresult CreateParser();
nsresult CreateIdentity(nsIMsgIdentity **aIdentity);
nsresult CreateAccount(nsIMsgIdentity *aIdentity,
nsIMsgIncomingServer *aIncomingServer,
nsIMsgAccount **aAccount);
nsresult CreateSmtpServer(const nsCString &aUserName,
const nsCString &aServerName,
nsISmtpServer **aServer,
bool *existing);
nsresult CreateIncomingServer(const nsCString &aUserName,
const nsCString &aServerName,
const nsCString &aProtocol,
nsIMsgIncomingServer **aServer);
nsresult SetupIncomingServer(nsIMsgIncomingServer **aServer);
nsresult SetupSmtpServer(nsISmtpServer **aServer);
nsresult SetPop3ServerProperties(nsIMsgIncomingServer *aServer);
nsresult RemoveConvertedFile();
};
#endif /* nsBeckySettings_h___ */

View file

@ -0,0 +1,74 @@
/* vim: set ts=2 et sw=2 tw=80: */
/* 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 "prprf.h"
#include "prmem.h"
#include "nsCOMPtr.h"
#include "nsIStringBundle.h"
#include "nsIServiceManager.h"
#include "nsIURI.h"
#include "nsServiceManagerUtils.h"
#include "nsXPCOMCIDInternal.h"
#include "nsBeckyStringBundle.h"
#define BECKY_MESSAGES_URL "chrome://messenger/locale/beckyImportMsgs.properties"
nsIStringBundle *nsBeckyStringBundle::mBundle = nullptr;
nsIStringBundle *
nsBeckyStringBundle::GetStringBundle(void)
{
if (mBundle)
return mBundle;
nsresult rv;
nsCOMPtr<nsIStringBundleService> bundleService = do_GetService(NS_STRINGBUNDLE_CONTRACTID, &rv);
if (NS_SUCCEEDED(rv) && bundleService)
rv = bundleService->CreateBundle(BECKY_MESSAGES_URL, &mBundle);
return mBundle;
}
void
nsBeckyStringBundle::EnsureStringBundle(void)
{
if (!mBundle)
(void) GetStringBundle();
}
char16_t *
nsBeckyStringBundle::GetStringByName(const char16_t *aName)
{
EnsureStringBundle();
char16_t *string = nullptr;
if (mBundle)
mBundle->GetStringFromName(aName, &string);
return string;
}
nsresult
nsBeckyStringBundle::FormatStringFromName(const char16_t *name,
const char16_t **params,
uint32_t length,
char16_t **_retval)
{
EnsureStringBundle();
return mBundle->FormatStringFromName(name,
params,
length,
_retval);
}
void
nsBeckyStringBundle::Cleanup(void)
{
if (mBundle)
mBundle->Release();
mBundle = nullptr;
}

View file

@ -0,0 +1,33 @@
/* 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 _nsBeckyStringBundle_H__
#define _nsBeckyStringBundle_H__
#include "nsString.h"
class nsIStringBundle;
class nsBeckyStringBundle final {
public:
static char16_t *GetStringByName(const char16_t *name);
static nsresult FormatStringFromName(const char16_t *name,
const char16_t **params,
uint32_t length,
char16_t **_retval);
static nsIStringBundle * GetStringBundle(void); // don't release
static void EnsureStringBundle(void);
static void Cleanup(void);
private:
static nsIStringBundle *mBundle;
};
#define BECKYIMPORT_NAME 2000
#define BECKYIMPORT_DESCRIPTION 2001
#define BECKYIMPORT_MAILBOX_SUCCESS 2002
#define BECKYIMPORT_MAILBOX_BADPARAM 2003
#define BECKYIMPORT_MAILBOX_CONVERTERROR 2004
#define BECKYIMPORT_ADDRESS_SUCCESS 2005
#endif /* _nsBeckyStringBundle_H__ */

View file

@ -0,0 +1,334 @@
/* vim: set ts=2 et sw=2 tw=80: */
/* 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 "nsCOMPtr.h"
#include "nsIFile.h"
#include "nsISimpleEnumerator.h"
#include "nsServiceManagerUtils.h"
#include "nsComponentManagerUtils.h"
#include "nsString.h"
#include "nsIUTF8ConverterService.h"
#include "nsUConvCID.h"
#include "nsNativeCharsetUtils.h"
#include "nsIInputStream.h"
#include "nsIOutputStream.h"
#include "nsILineInputStream.h"
#include "nsIConverterInputStream.h"
#include "nsIConverterOutputStream.h"
#include "nsMsgI18N.h"
#include "nsNetUtil.h"
#include "nsIINIParser.h"
#include "nsDirectoryServiceDefs.h"
#include "nsDirectoryServiceUtils.h"
#include "nsMsgUtils.h"
#include "msgCore.h"
#include "nsIImportMail.h"
#include "nsThreadUtils.h"
#include "nsBeckyUtils.h"
nsresult
nsBeckyUtils::FindUserDirectoryOnWindows7(nsIFile **aLocation)
{
NS_ENSURE_ARG_POINTER(aLocation);
nsresult rv;
nsCOMPtr<nsIFile> directory;
rv = GetSpecialDirectoryWithFileName(NS_WIN_DOCUMENTS_DIR,
"Becky",
getter_AddRefs(directory));
NS_ENSURE_SUCCESS(rv, rv);
bool exists = false;
rv = directory->Exists(&exists);
NS_ENSURE_SUCCESS(rv, rv);
if (!exists)
return NS_ERROR_FILE_NOT_FOUND;
bool isDirectory = false;
rv = directory->IsDirectory(&isDirectory);
NS_ENSURE_SUCCESS(rv, rv);
if (!isDirectory)
return NS_ERROR_FILE_NOT_FOUND;
directory.forget(aLocation);
return NS_OK;
}
nsresult
nsBeckyUtils::FindUserDirectoryOnWindowsXP(nsIFile **aLocation)
{
NS_ENSURE_ARG_POINTER(aLocation);
nsresult rv;
nsCOMPtr<nsIFile> directory = do_CreateInstance(NS_LOCAL_FILE_CONTRACTID, &rv);
NS_ENSURE_SUCCESS(rv, rv);
rv = directory->InitWithPath(NS_LITERAL_STRING("C:\\Becky!"));
NS_ENSURE_SUCCESS(rv, rv);
bool exists = false;
rv = directory->Exists(&exists);
NS_ENSURE_SUCCESS(rv, rv);
if (!exists)
return NS_ERROR_FILE_NOT_FOUND;
bool isDirectory = false;
rv = directory->IsDirectory(&isDirectory);
NS_ENSURE_SUCCESS(rv, rv);
if (!isDirectory)
return NS_ERROR_FILE_NOT_FOUND;
nsCOMPtr<nsISimpleEnumerator> entries;
rv = directory->GetDirectoryEntries(getter_AddRefs(entries));
NS_ENSURE_SUCCESS(rv, rv);
bool more;
nsCOMPtr<nsISupports> entry;
while (NS_SUCCEEDED(entries->HasMoreElements(&more)) && more) {
rv = entries->GetNext(getter_AddRefs(entry));
nsCOMPtr<nsIFile> file = do_QueryInterface(entry, &rv);
NS_ENSURE_SUCCESS(rv, rv);
bool isDirectory = false;
rv = file->IsDirectory(&isDirectory);
NS_ENSURE_SUCCESS(rv, rv);
if (isDirectory) {
file.forget(aLocation);
return NS_OK;
}
}
directory.forget(aLocation);
return NS_OK;
}
nsresult
nsBeckyUtils::FindUserDirectory(nsIFile **aLocation)
{
nsresult rv = FindUserDirectoryOnWindows7(aLocation);
if (rv == NS_ERROR_FILE_NOT_FOUND) {
rv = FindUserDirectoryOnWindowsXP(aLocation);
}
return rv;
}
nsresult
nsBeckyUtils::ConvertNativeStringToUTF8(const nsACString& aOriginal,
nsACString& _retval)
{
nsresult rv;
nsAutoString unicodeString;
rv = NS_CopyNativeToUnicode(aOriginal, unicodeString);
NS_ENSURE_SUCCESS(rv, rv);
CopyUTF16toUTF8(unicodeString, _retval);
return NS_OK;
}
nsresult
nsBeckyUtils::CreateLineInputStream(nsIFile *aFile,
nsILineInputStream **_retval)
{
NS_ENSURE_ARG_POINTER(_retval);
nsCOMPtr<nsIInputStream> inputStream;
nsresult rv = NS_NewLocalFileInputStream(getter_AddRefs(inputStream), aFile);
NS_ENSURE_SUCCESS(rv, rv);
return CallQueryInterface(inputStream, _retval);
}
nsresult
nsBeckyUtils::GetFolderListFile(nsIFile *aLocation, nsIFile **_retval)
{
nsresult rv;
nsCOMPtr<nsIFile> folderListFile;
rv = aLocation->Clone(getter_AddRefs(folderListFile));
NS_ENSURE_SUCCESS(rv, rv);
rv = folderListFile->Append(NS_LITERAL_STRING("Folder.lst"));
NS_ENSURE_SUCCESS(rv, rv);
bool exists;
rv = folderListFile->Exists(&exists);
NS_ENSURE_SUCCESS(rv, rv);
if (!exists)
return NS_ERROR_FILE_NOT_FOUND;
folderListFile.forget(_retval);
return NS_OK;
}
nsresult
nsBeckyUtils::GetDefaultFolderName(nsIFile *aFolderListFile, nsACString& name)
{
nsresult rv;
nsCOMPtr<nsILineInputStream> lineStream;
rv = CreateLineInputStream(aFolderListFile, getter_AddRefs(lineStream));
NS_ENSURE_SUCCESS(rv, rv);
bool more = true;
rv = lineStream->ReadLine(name, &more);
NS_ENSURE_SUCCESS(rv, rv);
return NS_OK;
}
nsresult
nsBeckyUtils::GetDefaultMailboxDirectory(nsIFile **_retval)
{
nsCOMPtr<nsIFile> userDirectory;
nsresult rv = FindUserDirectory(getter_AddRefs(userDirectory));
NS_ENSURE_SUCCESS(rv, rv);
nsCOMPtr<nsIFile> folderListFile;
rv = GetFolderListFile(userDirectory, getter_AddRefs(folderListFile));
NS_ENSURE_SUCCESS(rv, rv);
nsAutoCString defaultFolderName;
rv = GetDefaultFolderName(folderListFile, defaultFolderName);
NS_ENSURE_SUCCESS(rv, rv);
rv = userDirectory->AppendNative(defaultFolderName);
NS_ENSURE_SUCCESS(rv, rv);
bool exists;
rv = userDirectory->Exists(&exists);
NS_ENSURE_SUCCESS(rv, rv);
if (!exists)
return NS_ERROR_FILE_NOT_FOUND;
bool isDirectory = false;
rv = userDirectory->IsDirectory(&isDirectory);
NS_ENSURE_SUCCESS(rv, rv);
if (!isDirectory)
return NS_ERROR_FILE_NOT_FOUND;
userDirectory.forget(_retval);
return NS_OK;
}
nsresult
nsBeckyUtils::GetDefaultMailboxINIFile(nsIFile **_retval)
{
nsresult rv;
nsCOMPtr<nsIFile> mailboxDirectory;
rv = GetDefaultMailboxDirectory(getter_AddRefs(mailboxDirectory));
NS_ENSURE_SUCCESS(rv, rv);
return GetMailboxINIFile(mailboxDirectory, _retval);
}
nsresult
nsBeckyUtils::GetMailboxINIFile(nsIFile *aDirectory, nsIFile **_retval)
{
nsresult rv;
nsCOMPtr<nsIFile> target;
rv = aDirectory->Clone(getter_AddRefs(target));
NS_ENSURE_SUCCESS(rv, rv);
rv = target->Append(NS_LITERAL_STRING("Mailbox.ini"));
NS_ENSURE_SUCCESS(rv, rv);
bool exists;
rv = target->Exists(&exists);
if (!exists)
return NS_ERROR_FILE_NOT_FOUND;
target.forget(_retval);
return NS_OK;
}
nsresult
nsBeckyUtils::CreateINIParserForFile(nsIFile *aFile,
nsIINIParser **aParser)
{
nsresult rv;
nsCOMPtr<nsIINIParserFactory> factory =
do_GetService("@mozilla.org/xpcom/ini-processor-factory;1", &rv);
NS_ENSURE_SUCCESS(rv, rv);
return factory->CreateINIParser(aFile, aParser);
}
nsresult
nsBeckyUtils::GetMailboxNameFromINIFile(nsIFile *aFile, nsCString &aName)
{
nsresult rv;
nsCOMPtr<nsIINIParser> parser;
rv = CreateINIParserForFile(aFile, getter_AddRefs(parser));
NS_ENSURE_SUCCESS(rv, rv);
return parser->GetString(NS_LITERAL_CSTRING("Account"),
NS_LITERAL_CSTRING("Name"),
aName);
}
nsresult
nsBeckyUtils::ConvertToUTF8File(nsIFile *aSourceFile,
nsIFile **_retval)
{
nsresult rv;
nsCOMPtr<nsIFile> convertedFile;
rv = GetSpecialDirectoryWithFileName(NS_OS_TEMP_DIR,
"thunderbird-becky-import",
getter_AddRefs(convertedFile));
NS_ENSURE_SUCCESS(rv, rv);
rv = convertedFile->CreateUnique(nsIFile::NORMAL_FILE_TYPE, 0600);
NS_ENSURE_SUCCESS(rv, rv);
nsCOMPtr<nsIInputStream> source;
rv = NS_NewLocalFileInputStream(getter_AddRefs(source), aSourceFile);
NS_ENSURE_SUCCESS(rv, rv);
nsCOMPtr<nsIOutputStream> destination;
rv = NS_NewLocalFileOutputStream(getter_AddRefs(destination),
convertedFile);
NS_ENSURE_SUCCESS(rv, rv);
const uint32_t kBlock = 8192;
nsCOMPtr<nsIConverterInputStream> convertedInput =
do_CreateInstance("@mozilla.org/intl/converter-input-stream;1");
convertedInput->Init(source, nsMsgI18NFileSystemCharset(), kBlock, 0x0000);
nsCOMPtr<nsIConverterOutputStream> convertedOutput =
do_CreateInstance("@mozilla.org/intl/converter-output-stream;1");
convertedOutput->Init(destination, "UTF-8", kBlock, 0x0000);
char16_t *line = (char16_t *)moz_xmalloc(kBlock);
uint32_t readBytes = kBlock;
bool writtenBytes;
while (readBytes == kBlock) {
rv = convertedInput->Read(line, kBlock, &readBytes);
rv = convertedOutput->Write(readBytes, line, &writtenBytes);
}
convertedOutput->Close();
convertedInput->Close();
convertedFile.forget(_retval);
return NS_OK;
}
nsresult
nsBeckyUtils::TranslateFolderName(const nsAString & aFolderName,
nsAString & _retval)
{
if (aFolderName.LowerCaseEqualsLiteral("!trash"))
_retval = NS_LITERAL_STRING(kDestTrashFolderName);
else if (aFolderName.LowerCaseEqualsLiteral("!!!!inbox"))
_retval = NS_LITERAL_STRING(kDestInboxFolderName);
else if (aFolderName.LowerCaseEqualsLiteral("!!!!outbox"))
_retval = NS_LITERAL_STRING(kDestSentFolderName);
else if (aFolderName.LowerCaseEqualsLiteral("!!!!unsent"))
_retval = NS_LITERAL_STRING(kDestUnsentMessagesFolderName);
else
_retval = aFolderName;
return NS_OK;
}

View file

@ -0,0 +1,37 @@
/* 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 _nsBeckyUtils_H__
#define _nsBeckyUtils_H__
class nsIFile;
class nsILineInputStream;
class nsIINIParser;
class nsBeckyUtils final {
public:
static nsresult FindUserDirectoryOnWindows7(nsIFile **aLocation);
static nsresult FindUserDirectoryOnWindowsXP(nsIFile **aLocation);
static nsresult FindUserDirectory(nsIFile **aFile);
static nsresult ConvertNativeStringToUTF8(const nsACString& aOriginal,
nsACString& _retval);
static nsresult CreateLineInputStream(nsIFile *aFile,
nsILineInputStream **_retval);
static nsresult GetDefaultMailboxDirectory(nsIFile **_retval);
static nsresult GetFolderListFile(nsIFile *aLocation,
nsIFile **_retval);
static nsresult GetDefaultFolderName(nsIFile *aFolderListFile,
nsACString& name);
static nsresult GetDefaultMailboxINIFile(nsIFile **_retval);
static nsresult GetMailboxINIFile(nsIFile *aDirectory, nsIFile **_retval);
static nsresult CreateINIParserForFile(nsIFile *aFile,
nsIINIParser **aParser);
static nsresult GetMailboxNameFromINIFile(nsIFile *aFile, nsCString &aName);
static nsresult ConvertToUTF8File(nsIFile *aSourceFile,
nsIFile **_retval);
static nsresult TranslateFolderName(const nsAString & aFolderName,
nsAString & _retval);
};
#endif /* _nsBeckyUtils_H__ */