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,58 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/* 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 "ImportCharSet.h"
char ImportCharSet::m_upperCaseMap[256];
char ImportCharSet::m_Ascii[256] = {0}; // the initialiser makes it strong
class UInitMaps {
public:
UInitMaps();
};
UInitMaps gInitMaps;
UInitMaps::UInitMaps()
{
int i;
for (i = 0; i < 256; i++)
ImportCharSet::m_upperCaseMap[i] = i;
for (i = 'a'; i <= 'z'; i++)
ImportCharSet::m_upperCaseMap[i] = i - 'a' + 'A';
for (i = 0; i < 256; i++)
ImportCharSet::m_Ascii[i] = 0;
for (i = ImportCharSet::cUpperAChar; i <= ImportCharSet::cUpperZChar; i++)
ImportCharSet::m_Ascii[i] |= (ImportCharSet::cAlphaNumChar | ImportCharSet::cAlphaChar);
for (i = ImportCharSet::cLowerAChar; i <= ImportCharSet::cLowerZChar; i++)
ImportCharSet::m_Ascii[i] |= (ImportCharSet::cAlphaNumChar | ImportCharSet::cAlphaChar);
for (i = ImportCharSet::cZeroChar; i <= ImportCharSet::cNineChar; i++)
ImportCharSet::m_Ascii[i] |= (ImportCharSet::cAlphaNumChar | ImportCharSet::cDigitChar);
ImportCharSet::m_Ascii[ImportCharSet::cTabChar] |= ImportCharSet::cWhiteSpaceChar;
ImportCharSet::m_Ascii[ImportCharSet::cCRChar] |= ImportCharSet::cWhiteSpaceChar;
ImportCharSet::m_Ascii[ImportCharSet::cLinefeedChar] |= ImportCharSet::cWhiteSpaceChar;
ImportCharSet::m_Ascii[ImportCharSet::cSpaceChar] |= ImportCharSet::cWhiteSpaceChar;
ImportCharSet::m_Ascii[uint8_t('(')] |= ImportCharSet::c822SpecialChar;
ImportCharSet::m_Ascii[uint8_t(')')] |= ImportCharSet::c822SpecialChar;
ImportCharSet::m_Ascii[uint8_t('<')] |= ImportCharSet::c822SpecialChar;
ImportCharSet::m_Ascii[uint8_t('>')] |= ImportCharSet::c822SpecialChar;
ImportCharSet::m_Ascii[uint8_t('@')] |= ImportCharSet::c822SpecialChar;
ImportCharSet::m_Ascii[uint8_t(',')] |= ImportCharSet::c822SpecialChar;
ImportCharSet::m_Ascii[uint8_t(';')] |= ImportCharSet::c822SpecialChar;
ImportCharSet::m_Ascii[uint8_t(':')] |= ImportCharSet::c822SpecialChar;
ImportCharSet::m_Ascii[uint8_t('\\')] |= ImportCharSet::c822SpecialChar;
ImportCharSet::m_Ascii[uint8_t('"')] |= ImportCharSet::c822SpecialChar;
ImportCharSet::m_Ascii[uint8_t('.')] |= ImportCharSet::c822SpecialChar;
ImportCharSet::m_Ascii[uint8_t('[')] |= ImportCharSet::c822SpecialChar;
ImportCharSet::m_Ascii[uint8_t(']')] |= ImportCharSet::c822SpecialChar;
}

View file

@ -0,0 +1,175 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/* 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 ImportCharSet_h___
#define ImportCharSet_h___
#include "nscore.h"
// Some useful ASCII values
// 'A' = 65, 0x41
// 'Z' = 90, 0x5a
// '_' = 95, 0x5f
// 'a' = 97, 0x61
// 'z' = 122, 0x7a
// '0' = 48, 0x30
// '1' = 49, 0x31
// '9' = 57, 0x39
// ' ' = 32, 0x20
// whitespace, 10, 13, 32, 9 (linefeed, cr, space, tab) - 0x0a, 0x0d, 0x20, 0x09
// ':' = 58, 0x3a
// a typedef enum would be nicer but some compilers still have trouble with treating
// enum's as plain numbers when needed
class ImportCharSet {
public:
enum {
cTabChar = 9,
cLinefeedChar = 10,
cCRChar = 13,
cSpaceChar = 32,
cUpperAChar = 65,
cUpperZChar = 90,
cUnderscoreChar = 95,
cLowerAChar = 97,
cLowerZChar = 122,
cZeroChar = 48,
cNineChar = 57,
cAlphaNumChar = 1,
cAlphaChar = 2,
cWhiteSpaceChar = 4,
cDigitChar = 8,
c822SpecialChar = 16
};
static char m_upperCaseMap[256];
static char m_Ascii[256];
inline static bool IsUSAscii(uint8_t ch) { return (((ch & (uint8_t)0x80) == 0));}
inline static bool Is822CtlChar(uint8_t ch) { return (ch < 32);}
inline static bool Is822SpecialChar(uint8_t ch) { return ((m_Ascii[ch] & c822SpecialChar) == c822SpecialChar);}
inline static bool IsWhiteSpace(uint8_t ch) { return ((m_Ascii[ch] & cWhiteSpaceChar) == cWhiteSpaceChar); }
inline static bool IsAlphaNum(uint8_t ch) { return ((m_Ascii[ch] & cAlphaNumChar) == cAlphaNumChar); }
inline static bool IsDigit(uint8_t ch) { return ((m_Ascii[ch] & cDigitChar) == cDigitChar); }
inline static uint8_t ToLower(uint8_t ch) { if ((m_Ascii[ch] & cAlphaChar) == cAlphaChar) { return cLowerAChar + (m_upperCaseMap[ch] - cUpperAChar); } else return ch; }
inline static long AsciiToLong(const uint8_t * pChar, uint32_t len) {
long num = 0;
while (len) {
if ((m_Ascii[*pChar] & cDigitChar) == 0)
return num;
num *= 10;
num += (*pChar - cZeroChar);
len--;
pChar++;
}
return num;
}
inline static void ByteToHex(uint8_t byte, uint8_t * pHex) {
uint8_t val = byte;
val /= 16;
if (val < 10)
*pHex = '0' + val;
else
*pHex = 'A' + (val - 10);
pHex++;
val = byte;
val &= 0x0F;
if (val < 10)
*pHex = '0' + val;
else
*pHex = 'A' + (val - 10);
}
inline static void LongToHexBytes(uint32_t type, uint8_t * pStr) {
ByteToHex((uint8_t) (type >> 24), pStr);
pStr += 2;
ByteToHex((uint8_t) ((type >> 16) & 0x0FF), pStr);
pStr += 2;
ByteToHex((uint8_t) ((type >> 8) & 0x0FF), pStr);
pStr += 2;
ByteToHex((uint8_t) (type & 0x0FF), pStr);
}
inline static void SkipWhiteSpace(const uint8_t * & pChar, uint32_t & pos, uint32_t max) {
while ((pos < max) && (IsWhiteSpace(*pChar))) {
pos++; pChar++;
}
}
inline static void SkipSpaceTab(const uint8_t * & pChar, uint32_t& pos, uint32_t max) {
while ((pos < max) && ((*pChar == (uint8_t)cSpaceChar) || (*pChar == (uint8_t)cTabChar))) {
pos++; pChar++;
}
}
inline static void SkipTilSpaceTab(const uint8_t * & pChar, uint32_t& pos, uint32_t max) {
while ((pos < max) && (*pChar != (uint8_t)cSpaceChar) && (*pChar != (uint8_t)cTabChar)) {
pos++;
pChar++;
}
}
inline static bool StrNICmp(const uint8_t * pChar, const uint8_t * pSrc, uint32_t len) {
while (len && (m_upperCaseMap[*pChar] == m_upperCaseMap[*pSrc])) {
pChar++; pSrc++; len--;
}
return len == 0;
}
inline static bool StrNCmp(const uint8_t * pChar, const uint8_t *pSrc, uint32_t len) {
while (len && (*pChar == *pSrc)) {
pChar++; pSrc++; len--;
}
return len == 0;
}
inline static int FindChar(const uint8_t * pChar, uint8_t ch, uint32_t max) {
uint32_t pos = 0;
while ((pos < max) && (*pChar != ch)) {
pos++; pChar++;
}
if (pos < max)
return (int) pos;
else
return -1;
}
inline static bool NextChar(const uint8_t * & pChar, uint8_t ch, uint32_t& pos, uint32_t max) {
if ((pos < max) && (*pChar == ch)) {
pos++;
pChar++;
return true;
}
return false;
}
inline static int32_t strcmp(const char * pS1, const char * pS2) {
while (*pS1 && *pS2 && (*pS1 == *pS2)) {
pS1++;
pS2++;
}
return *pS1 - *pS2;
}
inline static int32_t stricmp(const char * pS1, const char * pS2) {
while (*pS1 && *pS2 && (m_upperCaseMap[uint8_t(*pS1)] == m_upperCaseMap[uint8_t(*pS2)])) {
pS1++;
pS2++;
}
return m_upperCaseMap[uint8_t(*pS1)] - m_upperCaseMap[uint8_t(*pS2)];
}
};
#endif /* ImportCharSet_h__ */

View file

@ -0,0 +1,22 @@
/* -*- Mode: C++; tab-width: 4; 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 ImportDebug_h___
#define ImportDebug_h___
#ifdef NS_DEBUG
#define IMPORT_DEBUG 1
#endif
// Use MOZ_LOG for logging.
#include "mozilla/Logging.h"
extern PRLogModuleInfo *IMPORTLOGMODULE; // Logging module
#define IMPORT_LOG0(x) MOZ_LOG(IMPORTLOGMODULE, mozilla::LogLevel::Debug, (x))
#define IMPORT_LOG1(x, y) MOZ_LOG(IMPORTLOGMODULE, mozilla::LogLevel::Debug, (x, y))
#define IMPORT_LOG2(x, y, z) MOZ_LOG(IMPORTLOGMODULE, mozilla::LogLevel::Debug, (x, y, z))
#define IMPORT_LOG3(a, b, c, d) MOZ_LOG(IMPORTLOGMODULE, mozilla::LogLevel::Debug, (a, b, c, d))
#endif

View file

@ -0,0 +1,299 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/* 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 "nsStringGlue.h"
#include "prio.h"
#include "nsNetUtil.h"
#include "nsISeekableStream.h"
#include "nsMsgUtils.h"
#include "ImportOutFile.h"
#include "ImportCharSet.h"
#include "ImportDebug.h"
/*
#ifdef _MAC
#define kMacNoCreator '????'
#define kMacTextFile 'TEXT'
#else
#define kMacNoCreator 0
#define kMacTextFile 0
#endif
*/
ImportOutFile::ImportOutFile()
{
m_ownsFileAndBuffer = false;
m_pos = 0;
m_pBuf = nullptr;
m_bufSz = 0;
m_pTrans = nullptr;
m_pTransOut = nullptr;
m_pTransBuf = nullptr;
}
ImportOutFile::ImportOutFile(nsIFile *pFile, uint8_t * pBuf, uint32_t sz)
{
m_pTransBuf = nullptr;
m_pTransOut = nullptr;
m_pTrans = nullptr;
m_ownsFileAndBuffer = false;
InitOutFile(pFile, pBuf, sz);
}
ImportOutFile::~ImportOutFile()
{
if (m_ownsFileAndBuffer)
{
Flush();
delete [] m_pBuf;
}
delete m_pTrans;
delete m_pTransOut;
delete [] m_pTransBuf;
}
bool ImportOutFile::Set8bitTranslator(nsImportTranslator *pTrans)
{
if (!Flush())
return false;
m_engaged = false;
m_pTrans = pTrans;
m_supports8to7 = pTrans->Supports8bitEncoding();
return true;
}
bool ImportOutFile::End8bitTranslation(bool *pEngaged, nsCString& useCharset, nsCString& encoding)
{
if (!m_pTrans)
return false;
bool bResult = Flush();
if (m_supports8to7 && m_pTransOut) {
if (bResult)
bResult = m_pTrans->FinishConvertToFile(m_pTransOut);
if (bResult)
bResult = Flush();
}
if (m_supports8to7) {
m_pTrans->GetCharset(useCharset);
m_pTrans->GetEncoding(encoding);
}
else
useCharset.Truncate();
*pEngaged = m_engaged;
delete m_pTrans;
m_pTrans = nullptr;
delete m_pTransOut;
m_pTransOut = nullptr;
delete [] m_pTransBuf;
m_pTransBuf = nullptr;
return bResult;
}
bool ImportOutFile::InitOutFile(nsIFile *pFile, uint32_t bufSz)
{
if (!bufSz)
bufSz = 32 * 1024;
if (!m_pBuf)
m_pBuf = new uint8_t[ bufSz];
if (!m_outputStream)
{
nsresult rv;
rv = MsgNewBufferedFileOutputStream(getter_AddRefs(m_outputStream),
pFile,
PR_CREATE_FILE | PR_WRONLY | PR_TRUNCATE,
0644);
if (NS_FAILED(rv))
{
IMPORT_LOG0("Couldn't create outfile\n");
delete [] m_pBuf;
m_pBuf = nullptr;
return false;
}
}
m_pFile = pFile;
m_ownsFileAndBuffer = true;
m_pos = 0;
m_bufSz = bufSz;
return true;
}
void ImportOutFile::InitOutFile(nsIFile *pFile, uint8_t * pBuf, uint32_t sz)
{
m_ownsFileAndBuffer = false;
m_pFile = pFile;
m_pBuf = pBuf;
m_bufSz = sz;
m_pos = 0;
}
bool ImportOutFile::Flush(void)
{
if (!m_pos)
return true;
uint32_t transLen;
bool duddleyDoWrite = false;
// handle translations if appropriate
if (m_pTrans) {
if (m_engaged && m_supports8to7) {
// Markers can get confused by this crap!!!
// TLR: FIXME: Need to update the markers based on
// the difference between the translated len and untranslated len
if (!m_pTrans->ConvertToFile( m_pBuf, m_pos, m_pTransOut, &transLen))
return false;
if (!m_pTransOut->Flush())
return false;
// now update our buffer...
if (transLen < m_pos) {
memcpy(m_pBuf, m_pBuf + transLen, m_pos - transLen);
}
m_pos -= transLen;
}
else if (m_engaged) {
// does not actually support translation!
duddleyDoWrite = true;
}
else {
// should we engage?
uint8_t * pChar = m_pBuf;
uint32_t len = m_pos;
while (len) {
if (!ImportCharSet::IsUSAscii(*pChar))
break;
pChar++;
len--;
}
if (len) {
m_engaged = true;
if (m_supports8to7) {
// allocate our translation output buffer and file...
m_pTransBuf = new uint8_t[m_bufSz];
m_pTransOut = new ImportOutFile(m_pFile, m_pTransBuf, m_bufSz);
return Flush();
}
else
duddleyDoWrite = true;
}
else {
duddleyDoWrite = true;
}
}
}
else
duddleyDoWrite = true;
if (duddleyDoWrite) {
uint32_t written = 0;
nsresult rv = m_outputStream->Write((const char *)m_pBuf, (int32_t)m_pos, &written);
if (NS_FAILED(rv) || ((uint32_t)written != m_pos))
return false;
m_pos = 0;
}
return true;
}
bool ImportOutFile::WriteU8NullTerm(const uint8_t * pSrc, bool includeNull)
{
while (*pSrc) {
if (m_pos >= m_bufSz) {
if (!Flush())
return false;
}
*(m_pBuf + m_pos) = *pSrc;
m_pos++;
pSrc++;
}
if (includeNull) {
if (m_pos >= m_bufSz) {
if (!Flush())
return false;
}
*(m_pBuf + m_pos) = 0;
m_pos++;
}
return true;
}
bool ImportOutFile::SetMarker(int markerID)
{
if (!Flush()) {
return false;
}
if (markerID < kMaxMarkers) {
int64_t pos = 0;
if (m_outputStream)
{
// do we need to flush for the seek to give us the right pos?
m_outputStream->Flush();
nsresult rv;
nsCOMPtr <nsISeekableStream> seekStream = do_QueryInterface(m_outputStream, &rv);
NS_ENSURE_SUCCESS(rv, false);
rv = seekStream->Tell(&pos);
if (NS_FAILED(rv)) {
IMPORT_LOG0("*** Error, Tell failed on output stream\n");
return false;
}
}
m_markers[markerID] = (uint32_t)pos + m_pos;
}
return true;
}
void ImportOutFile::ClearMarker(int markerID)
{
if (markerID < kMaxMarkers)
m_markers[markerID] = 0;
}
bool ImportOutFile::WriteStrAtMarker(int markerID, const char *pStr)
{
if (markerID >= kMaxMarkers)
return false;
if (!Flush())
return false;
int64_t pos;
m_outputStream->Flush();
nsresult rv;
nsCOMPtr <nsISeekableStream> seekStream = do_QueryInterface(m_outputStream, &rv);
NS_ENSURE_SUCCESS(rv, false);
rv = seekStream->Tell(&pos);
if (NS_FAILED(rv))
return false;
rv = seekStream->Seek(nsISeekableStream::NS_SEEK_SET, (int32_t) m_markers[markerID]);
if (NS_FAILED(rv))
return false;
uint32_t written;
rv = m_outputStream->Write(pStr, strlen(pStr), &written);
if (NS_FAILED(rv))
return false;
rv = seekStream->Seek(nsISeekableStream::NS_SEEK_SET, pos);
if (NS_FAILED(rv))
return false;
return true;
}

View file

@ -0,0 +1,94 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/* 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 ImportOutFile_h___
#define ImportOutFile_h___
#include "nsImportTranslator.h"
#include "nsIOutputStream.h"
#include "nsIFile.h"
#define kMaxMarkers 10
class ImportOutFile;
class ImportOutFile {
public:
ImportOutFile();
ImportOutFile(nsIFile *pFile, uint8_t * pBuf, uint32_t sz);
~ImportOutFile();
bool InitOutFile(nsIFile *pFile, uint32_t bufSz = 4096);
void InitOutFile(nsIFile *pFile, uint8_t * pBuf, uint32_t sz);
inline bool WriteData(const uint8_t * pSrc, uint32_t len);
inline bool WriteByte(uint8_t byte);
bool WriteStr(const char *pStr) {return WriteU8NullTerm((const uint8_t *) pStr, false); }
bool WriteU8NullTerm(const uint8_t * pSrc, bool includeNull);
bool WriteEol(void) { return WriteStr("\x0D\x0A"); }
bool Done(void) {return Flush();}
// Marker support
bool SetMarker(int markerID);
void ClearMarker(int markerID);
bool WriteStrAtMarker(int markerID, const char *pStr);
// 8-bit to 7-bit translation
bool Set8bitTranslator(nsImportTranslator *pTrans);
bool End8bitTranslation(bool *pEngaged, nsCString& useCharset, nsCString& encoding);
protected:
bool Flush(void);
protected:
nsCOMPtr <nsIFile> m_pFile;
nsCOMPtr <nsIOutputStream> m_outputStream;
uint8_t * m_pBuf;
uint32_t m_bufSz;
uint32_t m_pos;
bool m_ownsFileAndBuffer;
// markers
uint32_t m_markers[kMaxMarkers];
// 8 bit to 7 bit translations
nsImportTranslator * m_pTrans;
bool m_engaged;
bool m_supports8to7;
ImportOutFile * m_pTransOut;
uint8_t * m_pTransBuf;
};
inline bool ImportOutFile::WriteData(const uint8_t * pSrc, uint32_t len) {
while ((len + m_pos) > m_bufSz) {
if ((m_bufSz - m_pos)) {
memcpy(m_pBuf + m_pos, pSrc, m_bufSz - m_pos);
len -= (m_bufSz - m_pos);
pSrc += (m_bufSz - m_pos);
m_pos = m_bufSz;
}
if (!Flush())
return false;
}
if (len) {
memcpy(m_pBuf + m_pos, pSrc, len);
m_pos += len;
}
return true;
}
inline bool ImportOutFile::WriteByte(uint8_t byte) {
if (m_pos == m_bufSz) {
if (!Flush())
return false;
}
*(m_pBuf + m_pos) = byte;
m_pos++;
return true;
}
#endif /* ImportOutFile_h__ */

View file

@ -0,0 +1,105 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/* 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 "ImportTranslate.h"
int ImportTranslate::m_useTranslator = -1;
bool ImportTranslate::ConvertString(const nsCString& inStr, nsCString& outStr, bool mimeHeader)
{
if (inStr.IsEmpty()) {
outStr = inStr;
return true;
}
nsImportTranslator *pTrans = GetTranslator();
// int maxLen = (int) pTrans->GetMaxBufferSize(inStr.Length());
// int hLen = 0;
nsCString set;
nsCString lang;
if (mimeHeader) {
// add the charset and language
pTrans->GetCharset(set);
pTrans->GetLanguage(lang);
}
// Unfortunatly, we didn't implement ConvertBuffer for all translators,
// just ConvertToFile. This means that this data will not always
// be converted to the charset of pTrans. In that case...
// We don't always have the data in the same charset as the current
// translator...
// It is safer to leave the charset and language field blank
set.Truncate();
lang.Truncate();
uint8_t * pBuf;
/*
pBuf = (P_U8) outStr.GetBuffer(maxLen);
if (!pBuf) {
delete pTrans;
return FALSE;
}
pTrans->ConvertBuffer((PC_U8)(PC_S8)inStr, inStr.GetLength(), pBuf);
outStr.ReleaseBuffer();
*/
outStr = inStr;
delete pTrans;
// Now I need to run the string through the mime-header special char
// encoder.
pTrans = new CMHTranslator;
pBuf = new uint8_t[pTrans->GetMaxBufferSize(outStr.Length())];
pTrans->ConvertBuffer((const uint8_t *)(outStr.get()), outStr.Length(), pBuf);
delete pTrans;
outStr.Truncate();
if (mimeHeader) {
outStr = set;
outStr += "'";
outStr += lang;
outStr += "'";
}
outStr += (const char *)pBuf;
delete [] pBuf;
return true;
}
nsImportTranslator *ImportTranslate::GetTranslator(void)
{
if (m_useTranslator == -1) {
// get the translator to use...
// CString trans;
// trans.LoadString(IDS_LANGUAGE_TRANSLATION);
m_useTranslator = 0;
// if (!trans.CompareNoCase("iso-2022-jp"))
// gWizData.m_useTranslator = 1;
}
switch(m_useTranslator) {
case 0:
return new nsImportTranslator;
//case 1:
// return new CSJis2JisTranslator;
default:
return new nsImportTranslator;
}
}
nsImportTranslator *ImportTranslate::GetMatchingTranslator(const char *pCharSet)
{
/*
CString jp = "iso-2022-jp";
if (!jp.CompareNoCase(pCharSet))
return new CSJis2JisTranslator;
*/
return nullptr;
}

View file

@ -0,0 +1,23 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/* 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 ImportTranslate_h___
#define ImportTranslate_h___
#include "nsStringGlue.h"
#include "nsImportTranslator.h"
class ImportTranslate {
public:
static bool ConvertString(const nsCString& inStr, nsCString& outStr, bool mimeHeader);
static nsImportTranslator *GetTranslator(void);
static nsImportTranslator *GetMatchingTranslator(const char *pCharSet);
protected:
static int m_useTranslator;
};
#endif /* ImportTranslate_h__ */

View file

@ -0,0 +1,25 @@
# 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/.
SOURCES += [
'ImportCharSet.cpp',
'ImportOutFile.cpp',
'ImportTranslate.cpp',
'nsImportABDescriptor.cpp',
'nsImportAddressBooks.cpp',
'nsImportEmbeddedImageData.cpp',
'nsImportEncodeScan.cpp',
'nsImportFieldMap.cpp',
'nsImportMail.cpp',
'nsImportMailboxDescriptor.cpp',
'nsImportMimeEncode.cpp',
'nsImportScanFile.cpp',
'nsImportService.cpp',
'nsImportStringBundle.cpp',
'nsImportTranslator.cpp',
]
FINAL_LIBRARY = 'import'

View file

@ -0,0 +1,32 @@
/* -*- 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 "nscore.h"
#include "nsImportABDescriptor.h"
////////////////////////////////////////////////////////////////////////
NS_METHOD nsImportABDescriptor::Create(nsISupports *aOuter, REFNSIID aIID, void **aResult)
{
if (aOuter)
return NS_ERROR_NO_AGGREGATION;
nsImportABDescriptor *it = new nsImportABDescriptor();
if (it == nullptr)
return NS_ERROR_OUT_OF_MEMORY;
NS_ADDREF(it);
nsresult rv = it->QueryInterface(aIID, aResult);
NS_RELEASE(it);
return rv;
}
NS_IMPL_ISUPPORTS(nsImportABDescriptor, nsIImportABDescriptor)
nsImportABDescriptor::nsImportABDescriptor()
: mId(0), mRef(0), mSize(0), mImport(true)
{
}

View file

@ -0,0 +1,103 @@
/* -*- 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 nsImportABDescriptor_h___
#define nsImportABDescriptor_h___
#include "mozilla/Attributes.h"
#include "nscore.h"
#include "nsStringGlue.h"
#include "nsIImportABDescriptor.h"
#include "nsIFile.h"
#include "nsCOMPtr.h"
////////////////////////////////////////////////////////////////////////
class nsImportABDescriptor : public nsIImportABDescriptor
{
public:
NS_DECL_THREADSAFE_ISUPPORTS
NS_IMETHOD GetIdentifier(uint32_t *pIdentifier) override {
*pIdentifier = mId;
return NS_OK;
}
NS_IMETHOD SetIdentifier(uint32_t ident) override {
mId = ident;
return NS_OK;
}
NS_IMETHOD GetRef(uint32_t *pRef) override {
*pRef = mRef;
return NS_OK;
}
NS_IMETHOD SetRef(uint32_t ref) override {
mRef = ref;
return NS_OK;
}
/* attribute unsigned long size; */
NS_IMETHOD GetSize(uint32_t *pSize) override {
*pSize = mSize;
return NS_OK;
}
NS_IMETHOD SetSize(uint32_t theSize) override {
mSize = theSize;
return NS_OK;
}
/* attribute AString displayName; */
NS_IMETHOD GetPreferredName(nsAString &aName) override {
aName = mDisplayName;
return NS_OK;
}
NS_IMETHOD SetPreferredName(const nsAString &aName) override {
mDisplayName = aName;
return NS_OK;
}
/* readonly attribute nsIFile fileSpec; */
NS_IMETHOD GetAbFile(nsIFile **aFile) override {
if (!mFile)
return NS_ERROR_NULL_POINTER;
return mFile->Clone(aFile);
}
NS_IMETHOD SetAbFile(nsIFile *aFile) override {
if (!aFile) {
mFile = nullptr;
return NS_OK;
}
return aFile->Clone(getter_AddRefs(mFile));
}
/* attribute boolean import; */
NS_IMETHOD GetImport(bool *pImport) override {
*pImport = mImport;
return NS_OK;
}
NS_IMETHOD SetImport(bool doImport) override {
mImport = doImport;
return NS_OK;
}
nsImportABDescriptor();
static NS_METHOD Create(nsISupports *aOuter, REFNSIID aIID, void **aResult);
private:
virtual ~nsImportABDescriptor() {}
uint32_t mId; // used by creator of the structure
uint32_t mRef; // depth in the hierarchy
nsString mDisplayName; // name of this mailbox
nsCOMPtr<nsIFile> mFile; // source file (if applicable)
uint32_t mSize; // size
bool mImport; // import it or not?
};
#endif

View file

@ -0,0 +1,894 @@
/* -*- 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 "prprf.h"
#include "plstr.h"
#include "nsCOMPtr.h"
#include "nsMsgUtils.h"
#include "nsIImportService.h"
#include "nsIImportAddressBooks.h"
#include "nsIImportGeneric.h"
#include "nsISupportsPrimitives.h"
#include "nsIImportABDescriptor.h"
#include "nsIImportFieldMap.h"
#include "nsStringGlue.h"
#include "nsIFile.h"
#include "nsIAddrDatabase.h"
#include "nsIAbManager.h"
#include "nsIAbLDIFService.h"
#include "nsAbBaseCID.h"
#include "nsIStringBundle.h"
#include "nsImportStringBundle.h"
#include "nsTextFormatter.h"
#include "nsServiceManagerUtils.h"
#include "msgCore.h"
#include "ImportDebug.h"
#include "nsIAbMDBDirectory.h"
#include "nsComponentManagerUtils.h"
#include "nsIArray.h"
#include "nsCOMArray.h"
#include "nsArrayUtils.h"
static void ImportAddressThread(void *stuff);
class AddressThreadData;
class nsImportGenericAddressBooks : public nsIImportGeneric
{
public:
nsImportGenericAddressBooks();
NS_DECL_THREADSAFE_ISUPPORTS
/* nsISupports GetData (in string dataId); */
NS_IMETHOD GetData(const char *dataId, nsISupports **_retval) override;
NS_IMETHOD SetData(const char *dataId, nsISupports *pData) override;
NS_IMETHOD GetStatus(const char *statusKind, int32_t *_retval) override;
NS_IMETHOD WantsProgress(bool *_retval) override;
NS_IMETHOD BeginImport(nsISupportsString *successLog, nsISupportsString *errorLog, bool *_retval) override;
NS_IMETHOD ContinueImport(bool *_retval) override;
NS_IMETHOD GetProgress(int32_t *_retval) override;
NS_IMETHOD CancelImport(void) override;
private:
virtual ~nsImportGenericAddressBooks();
void GetDefaultLocation(void);
void GetDefaultBooks(void);
void GetDefaultFieldMap(void);
public:
static void SetLogs(nsString& success, nsString& error, nsISupportsString *pSuccess, nsISupportsString *pError);
static void ReportError(const char16_t *pName, nsString *pStream,
nsIStringBundle *aBundle);
private:
nsIImportAddressBooks * m_pInterface;
nsCOMPtr<nsIArray> m_Books;
nsCOMArray<nsIAddrDatabase> m_DBs;
nsCOMPtr <nsIFile> m_pLocation;
nsIImportFieldMap * m_pFieldMap;
bool m_autoFind;
char16_t * m_description;
bool m_gotLocation;
bool m_found;
bool m_userVerify;
nsISupportsString * m_pSuccessLog;
nsISupportsString * m_pErrorLog;
uint32_t m_totalSize;
bool m_doImport;
AddressThreadData * m_pThreadData;
char * m_pDestinationUri;
nsCOMPtr<nsIStringBundle> m_stringBundle;
};
class AddressThreadData {
public:
bool driverAlive;
bool threadAlive;
bool abort;
bool fatalError;
uint32_t currentTotal;
uint32_t currentSize;
nsIArray *books;
nsCOMArray<nsIAddrDatabase>* dBs;
nsCOMPtr<nsIAbLDIFService> ldifService;
nsIImportAddressBooks * addressImport;
nsIImportFieldMap * fieldMap;
nsISupportsString * successLog;
nsISupportsString * errorLog;
char * pDestinationUri;
nsIStringBundle* stringBundle;
AddressThreadData();
~AddressThreadData();
};
nsresult NS_NewGenericAddressBooks(nsIImportGeneric** aImportGeneric)
{
NS_PRECONDITION(aImportGeneric != nullptr, "null ptr");
if (! aImportGeneric)
return NS_ERROR_NULL_POINTER;
nsImportGenericAddressBooks *pGen = new nsImportGenericAddressBooks();
if (pGen == nullptr)
return NS_ERROR_OUT_OF_MEMORY;
NS_ADDREF(pGen);
nsresult rv = pGen->QueryInterface(NS_GET_IID(nsIImportGeneric), (void **)aImportGeneric);
NS_RELEASE(pGen);
return rv;
}
nsImportGenericAddressBooks::nsImportGenericAddressBooks()
{
m_pInterface = nullptr;
m_pSuccessLog = nullptr;
m_pErrorLog = nullptr;
m_totalSize = 0;
m_doImport = false;
m_pThreadData = nullptr;
m_pDestinationUri = nullptr;
m_pFieldMap = nullptr;
m_autoFind = false;
m_description = nullptr;
m_gotLocation = false;
m_found = false;
m_userVerify = false;
nsImportStringBundle::GetStringBundle(IMPORT_MSGS_URL, getter_AddRefs(m_stringBundle));
}
nsImportGenericAddressBooks::~nsImportGenericAddressBooks()
{
if (m_pDestinationUri)
NS_Free(m_pDestinationUri);
if (m_description)
NS_Free(m_description);
NS_IF_RELEASE(m_pFieldMap);
NS_IF_RELEASE(m_pInterface);
NS_IF_RELEASE(m_pSuccessLog);
NS_IF_RELEASE(m_pErrorLog);
}
NS_IMPL_ISUPPORTS(nsImportGenericAddressBooks, nsIImportGeneric)
NS_IMETHODIMP nsImportGenericAddressBooks::GetData(const char *dataId, nsISupports **_retval)
{
NS_PRECONDITION(_retval != nullptr, "null ptr");
if (!_retval)
return NS_ERROR_NULL_POINTER;
nsresult rv;
*_retval = nullptr;
if (!PL_strcasecmp(dataId, "addressInterface")) {
*_retval = m_pInterface;
NS_IF_ADDREF(m_pInterface);
}
if (!PL_strcasecmp(dataId, "addressLocation")) {
if (!m_pLocation)
GetDefaultLocation();
NS_IF_ADDREF(*_retval = m_pLocation);
}
if (!PL_strcasecmp(dataId, "addressBooks")) {
if (!m_pLocation)
GetDefaultLocation();
if (!m_Books)
GetDefaultBooks();
*_retval = m_Books;
}
if (!PL_strcasecmp(dataId, "addressDestination")) {
if (m_pDestinationUri) {
nsCOMPtr<nsISupportsCString> abString = do_CreateInstance(NS_SUPPORTS_CSTRING_CONTRACTID, &rv);
NS_ENSURE_SUCCESS(rv, rv);
abString->SetData(nsDependentCString(m_pDestinationUri));
NS_IF_ADDREF(*_retval = abString);
}
}
if (!PL_strcasecmp(dataId, "fieldMap")) {
if (m_pFieldMap) {
*_retval = m_pFieldMap;
m_pFieldMap->AddRef();
}
else {
if (m_pInterface && m_pLocation) {
bool needsIt = false;
m_pInterface->GetNeedsFieldMap(m_pLocation, &needsIt);
if (needsIt) {
GetDefaultFieldMap();
if (m_pFieldMap) {
*_retval = m_pFieldMap;
m_pFieldMap->AddRef();
}
}
}
}
}
if (!PL_strncasecmp(dataId, "sampleData-", 11)) {
// extra the record number
const char *pNum = dataId + 11;
int32_t rNum = 0;
while (*pNum) {
rNum *= 10;
rNum += (*pNum - '0');
pNum++;
}
IMPORT_LOG1("Requesting sample data #: %ld\n", (long)rNum);
if (m_pInterface) {
nsCOMPtr<nsISupportsString> data = do_CreateInstance(NS_SUPPORTS_STRING_CONTRACTID, &rv);
if (NS_FAILED(rv))
return rv;
char16_t * pData = nullptr;
bool found = false;
rv = m_pInterface->GetSampleData(rNum, &found, &pData);
if (NS_FAILED(rv))
return rv;
if (found) {
data->SetData(nsDependentString(pData));
*_retval = data;
NS_ADDREF(*_retval);
}
NS_Free(pData);
}
}
return NS_OK;
}
NS_IMETHODIMP nsImportGenericAddressBooks::SetData(const char *dataId, nsISupports *item)
{
NS_PRECONDITION(dataId != nullptr, "null ptr");
if (!dataId)
return NS_ERROR_NULL_POINTER;
if (!PL_strcasecmp(dataId, "addressInterface")) {
NS_IF_RELEASE(m_pInterface);
if (item)
item->QueryInterface(NS_GET_IID(nsIImportAddressBooks), (void **) &m_pInterface);
}
if (!PL_strcasecmp(dataId, "addressBooks")) {
if (item)
item->QueryInterface(NS_GET_IID(nsIArray), (void **) &m_Books);
}
if (!PL_strcasecmp(dataId, "addressLocation")) {
m_pLocation = nullptr;
if (item) {
nsresult rv;
m_pLocation = do_QueryInterface(item, &rv);
NS_ENSURE_SUCCESS(rv,rv);
}
if (m_pInterface)
m_pInterface->SetSampleLocation(m_pLocation);
}
if (!PL_strcasecmp(dataId, "addressDestination")) {
if (item) {
nsCOMPtr<nsISupportsCString> abString;
item->QueryInterface(NS_GET_IID(nsISupportsCString), getter_AddRefs(abString));
if (abString) {
if (m_pDestinationUri)
NS_Free(m_pDestinationUri);
m_pDestinationUri = nullptr;
nsAutoCString tempUri;
abString->GetData(tempUri);
m_pDestinationUri = ToNewCString(tempUri);
}
}
}
if (!PL_strcasecmp(dataId, "fieldMap")) {
NS_IF_RELEASE(m_pFieldMap);
if (item)
item->QueryInterface(NS_GET_IID(nsIImportFieldMap), (void **) &m_pFieldMap);
}
return NS_OK;
}
NS_IMETHODIMP nsImportGenericAddressBooks::GetStatus(const char *statusKind, int32_t *_retval)
{
NS_PRECONDITION(statusKind != nullptr, "null ptr");
NS_PRECONDITION(_retval != nullptr, "null ptr");
if (!statusKind || !_retval)
return NS_ERROR_NULL_POINTER;
*_retval = 0;
if (!PL_strcasecmp(statusKind, "isInstalled")) {
GetDefaultLocation();
*_retval = (int32_t) m_found;
}
if (!PL_strcasecmp(statusKind, "canUserSetLocation")) {
GetDefaultLocation();
*_retval = (int32_t) m_userVerify;
}
if (!PL_strcasecmp(statusKind, "autoFind")) {
GetDefaultLocation();
*_retval = (int32_t) m_autoFind;
}
if (!PL_strcasecmp(statusKind, "supportsMultiple")) {
bool multi = false;
if (m_pInterface)
m_pInterface->GetSupportsMultiple(&multi);
*_retval = (int32_t) multi;
}
if (!PL_strcasecmp(statusKind, "needsFieldMap")) {
bool needs = false;
if (m_pInterface && m_pLocation)
m_pInterface->GetNeedsFieldMap(m_pLocation, &needs);
*_retval = (int32_t) needs;
}
return NS_OK;
}
void nsImportGenericAddressBooks::GetDefaultLocation(void)
{
if (!m_pInterface)
return;
if ((m_pLocation && m_gotLocation) || m_autoFind)
return;
if (m_description)
NS_Free(m_description);
m_description = nullptr;
m_pInterface->GetAutoFind(&m_description, &m_autoFind);
m_gotLocation = true;
if (m_autoFind) {
m_found = true;
m_userVerify = false;
return;
}
nsCOMPtr <nsIFile> pLoc;
m_pInterface->GetDefaultLocation(getter_AddRefs(pLoc), &m_found, &m_userVerify);
if (!m_pLocation)
m_pLocation = pLoc;
}
void nsImportGenericAddressBooks::GetDefaultBooks(void)
{
if (!m_pInterface || m_Books)
return;
if (!m_pLocation && !m_autoFind)
return;
nsresult rv = m_pInterface->FindAddressBooks(m_pLocation, getter_AddRefs(m_Books));
if (NS_FAILED(rv)) {
IMPORT_LOG0("*** Error: FindAddressBooks failed\n");
}
}
void nsImportGenericAddressBooks::GetDefaultFieldMap(void)
{
if (!m_pInterface || !m_pLocation)
return;
NS_IF_RELEASE(m_pFieldMap);
nsresult rv;
nsCOMPtr<nsIImportService> impSvc(do_GetService(NS_IMPORTSERVICE_CONTRACTID, &rv));
if (NS_FAILED(rv)) {
IMPORT_LOG0("*** Unable to get nsIImportService.\n");
return;
}
rv = impSvc->CreateNewFieldMap(&m_pFieldMap);
if (NS_FAILED(rv))
return;
int32_t sz = 0;
rv = m_pFieldMap->GetNumMozFields(&sz);
if (NS_SUCCEEDED(rv))
rv = m_pFieldMap->DefaultFieldMap(sz);
if (NS_SUCCEEDED(rv))
rv = m_pInterface->InitFieldMap(m_pFieldMap);
if (NS_FAILED(rv)) {
IMPORT_LOG0("*** Error: Unable to initialize field map\n");
NS_IF_RELEASE(m_pFieldMap);
}
}
NS_IMETHODIMP nsImportGenericAddressBooks::WantsProgress(bool *_retval)
{
NS_PRECONDITION(_retval != nullptr, "null ptr");
NS_ENSURE_ARG_POINTER(_retval);
GetDefaultLocation();
GetDefaultBooks();
bool result = false;
if (m_Books) {
uint32_t count = 0;
uint32_t i;
bool import;
uint32_t size;
uint32_t totalSize = 0;
m_Books->GetLength(&count);
for (i = 0; i < count; i++) {
nsCOMPtr<nsIImportABDescriptor> book = do_QueryElementAt(m_Books, i);
if (book) {
import = false;
size = 0;
nsresult rv = book->GetImport(&import);
if (NS_SUCCEEDED(rv) && import) {
(void) book->GetSize(&size);
result = true;
}
totalSize += size;
}
}
m_totalSize = totalSize;
}
m_doImport = result;
*_retval = result;
return NS_OK;
}
void nsImportGenericAddressBooks::SetLogs(nsString& success, nsString& error, nsISupportsString *pSuccess, nsISupportsString *pError)
{
nsAutoString str;
if (pSuccess) {
pSuccess->GetData(str);
str.Append(success);
pSuccess->SetData(success);
}
if (pError) {
pError->GetData(str);
str.Append(error);
pError->SetData(error);
}
}
already_AddRefed<nsIAddrDatabase> GetAddressBookFromUri(const char *pUri)
{
if (!pUri)
return nullptr;
nsCOMPtr<nsIAbManager> abManager = do_GetService(NS_ABMANAGER_CONTRACTID);
if (!abManager)
return nullptr;
nsCOMPtr<nsIAbDirectory> directory;
abManager->GetDirectory(nsDependentCString(pUri),
getter_AddRefs(directory));
if (!directory)
return nullptr;
nsCOMPtr<nsIAbMDBDirectory> mdbDirectory = do_QueryInterface(directory);
if (!mdbDirectory)
return nullptr;
nsCOMPtr<nsIAddrDatabase> pDatabase;
mdbDirectory->GetDatabase(getter_AddRefs(pDatabase));
return pDatabase.forget();
}
already_AddRefed<nsIAddrDatabase> GetAddressBook(const char16_t *name,
bool makeNew)
{
if (!makeNew) {
// FIXME: How do I get the list of address books and look for a
// specific name. Major bogosity!
// For now, assume we didn't find anything with that name
}
IMPORT_LOG0("In GetAddressBook\n");
nsresult rv;
nsCOMPtr<nsIAddrDatabase> pDatabase;
nsCOMPtr<nsIFile> dbPath;
nsCOMPtr<nsIAbManager> abManager = do_GetService(NS_ABMANAGER_CONTRACTID, &rv);
if (NS_SUCCEEDED(rv))
{
/* Get the profile directory */
rv = abManager->GetUserProfileDirectory(getter_AddRefs(dbPath));
if (NS_SUCCEEDED(rv))
{
// Create a new address book file - we don't care what the file
// name is, as long as it's unique
rv = dbPath->Append(NS_LITERAL_STRING("impab.mab"));
if (NS_SUCCEEDED(rv))
{
rv = dbPath->CreateUnique(nsIFile::NORMAL_FILE_TYPE, 0600);
if (NS_SUCCEEDED(rv))
{
IMPORT_LOG0("Getting the address database factory\n");
nsCOMPtr<nsIAddrDatabase> addrDBFactory =
do_GetService(NS_ADDRDATABASE_CONTRACTID, &rv);
if (NS_FAILED(rv))
return nullptr;
IMPORT_LOG0("Opening the new address book\n");
rv = addrDBFactory->Open(dbPath, true, true,
getter_AddRefs(pDatabase));
}
}
}
}
if (NS_FAILED(rv))
{
IMPORT_LOG0("Failed to get the user profile directory from the address book session\n");
}
if (pDatabase && dbPath)
{
// We made a database, add it to the UI?!?!?!?!?!?!
// This is major bogosity again! Why doesn't the address book
// just handle this properly for me? Uggggg...
nsCOMPtr<nsIAbDirectory> parentDir;
abManager->GetDirectory(NS_LITERAL_CSTRING(kAllDirectoryRoot),
getter_AddRefs(parentDir));
if (parentDir)
{
nsAutoCString URI("moz-abmdbdirectory://");
nsAutoCString leafName;
rv = dbPath->GetNativeLeafName(leafName);
if (NS_FAILED(rv))
IMPORT_LOG0("*** Error: Unable to get name of database file\n");
else
{
URI.Append(leafName);
rv = parentDir->CreateDirectoryByURI(nsDependentString(name), URI);
if (NS_FAILED(rv))
IMPORT_LOG0("*** Error: Unable to create address book directory\n");
}
}
if (NS_SUCCEEDED(rv))
IMPORT_LOG0("Added new address book to the UI\n");
else
IMPORT_LOG0("*** Error: An error occurred while adding the address book to the UI\n");
}
return pDatabase.forget();
}
NS_IMETHODIMP nsImportGenericAddressBooks::BeginImport(nsISupportsString *successLog, nsISupportsString *errorLog, bool *_retval)
{
NS_PRECONDITION(_retval != nullptr, "null ptr");
if (!_retval)
return NS_ERROR_NULL_POINTER;
nsString success;
nsString error;
if (!m_doImport) {
*_retval = true;
nsImportStringBundle::GetStringByID(IMPORT_NO_ADDRBOOKS, m_stringBundle,
success);
SetLogs(success, error, successLog, errorLog);
return NS_OK;
}
if (!m_pInterface || !m_Books) {
nsImportStringBundle::GetStringByID(IMPORT_ERROR_AB_NOTINITIALIZED,
m_stringBundle, error);
SetLogs(success, error, successLog, errorLog);
*_retval = false;
return NS_OK;
}
bool needsFieldMap = false;
if (NS_FAILED(m_pInterface->GetNeedsFieldMap(m_pLocation, &needsFieldMap)) ||
(needsFieldMap && !m_pFieldMap)) {
nsImportStringBundle::GetStringByID(IMPORT_ERROR_AB_NOTINITIALIZED,
m_stringBundle, error);
SetLogs(success, error, successLog, errorLog);
*_retval = false;
return NS_OK;
}
NS_IF_RELEASE(m_pSuccessLog);
NS_IF_RELEASE(m_pErrorLog);
m_pSuccessLog = successLog;
m_pErrorLog = errorLog;
NS_IF_ADDREF(m_pSuccessLog);
NS_IF_ADDREF(m_pErrorLog);
// create the info need to drive address book import. We're
// not going to create a new thread for this since address books
// don't tend to be large, and import is rare.
m_pThreadData = new AddressThreadData();
m_pThreadData->books = m_Books;
NS_ADDREF(m_Books);
m_pThreadData->addressImport = m_pInterface;
NS_ADDREF(m_pInterface);
m_pThreadData->fieldMap = m_pFieldMap;
NS_IF_ADDREF(m_pFieldMap);
m_pThreadData->errorLog = m_pErrorLog;
NS_IF_ADDREF(m_pErrorLog);
m_pThreadData->successLog = m_pSuccessLog;
NS_IF_ADDREF(m_pSuccessLog);
if (m_pDestinationUri)
m_pThreadData->pDestinationUri = strdup(m_pDestinationUri);
uint32_t count = 0;
m_Books->GetLength(&count);
// Create/obtain any address books that we need here, so that we don't need
// to do so inside the import thread which would just proxy the create
// operations back to the main thread anyway.
nsCOMPtr<nsIAddrDatabase> db = GetAddressBookFromUri(m_pDestinationUri);
for (uint32_t i = 0; i < count; ++i)
{
nsCOMPtr<nsIImportABDescriptor> book = do_QueryElementAt(m_Books, i);
if (book)
{
if (!db)
{
nsString name;
book->GetPreferredName(name);
db = GetAddressBook(name.get(), true);
}
m_DBs.AppendObject(db);
}
}
m_pThreadData->dBs = &m_DBs;
NS_IF_ADDREF(m_pThreadData->stringBundle = m_stringBundle);
nsresult rv;
m_pThreadData->ldifService = do_GetService(NS_ABLDIFSERVICE_CONTRACTID, &rv);
ImportAddressThread(m_pThreadData);
delete m_pThreadData;
m_pThreadData = nullptr;
*_retval = true;
return NS_OK;
}
NS_IMETHODIMP nsImportGenericAddressBooks::ContinueImport(bool *_retval)
{
NS_PRECONDITION(_retval != nullptr, "null ptr");
if (!_retval)
return NS_ERROR_NULL_POINTER;
*_retval = true;
if (m_pThreadData) {
if (m_pThreadData->fatalError)
*_retval = false;
}
return NS_OK;
}
NS_IMETHODIMP nsImportGenericAddressBooks::GetProgress(int32_t *_retval)
{
// This returns the progress from the the currently
// running import mail or import address book thread.
NS_PRECONDITION(_retval != nullptr, "null ptr");
if (!_retval)
return NS_ERROR_NULL_POINTER;
if (!m_pThreadData || !(m_pThreadData->threadAlive)) {
*_retval = 100;
return NS_OK;
}
uint32_t sz = 0;
if (m_pThreadData->currentSize && m_pInterface) {
if (NS_FAILED(m_pInterface->GetImportProgress(&sz)))
sz = 0;
}
if (m_totalSize)
*_retval = ((m_pThreadData->currentTotal + sz) * 100) / m_totalSize;
else
*_retval = 0;
// never return less than 5 so it looks like we are doing something!
if (*_retval < 5)
*_retval = 5;
// as long as the thread is alive don't return completely
// done.
if (*_retval > 99)
*_retval = 99;
return NS_OK;
}
NS_IMETHODIMP nsImportGenericAddressBooks::CancelImport(void)
{
if (m_pThreadData) {
m_pThreadData->abort = true;
m_pThreadData = nullptr;
}
return NS_OK;
}
AddressThreadData::AddressThreadData()
{
fatalError = false;
driverAlive = true;
threadAlive = true;
abort = false;
currentTotal = 0;
currentSize = 0;
books = nullptr;
addressImport = nullptr;
successLog = nullptr;
errorLog = nullptr;
pDestinationUri = nullptr;
fieldMap = nullptr;
stringBundle = nullptr;
ldifService = nullptr;
}
AddressThreadData::~AddressThreadData()
{
if (pDestinationUri)
NS_Free(pDestinationUri);
NS_IF_RELEASE(books);
NS_IF_RELEASE(addressImport);
NS_IF_RELEASE(errorLog);
NS_IF_RELEASE(successLog);
NS_IF_RELEASE(fieldMap);
NS_IF_RELEASE(stringBundle);
}
void nsImportGenericAddressBooks::ReportError(const char16_t *pName,
nsString *pStream,
nsIStringBundle* aBundle)
{
if (!pStream)
return;
// load the error string
char16_t *pFmt = nsImportStringBundle::GetStringByID(IMPORT_ERROR_GETABOOK, aBundle);
char16_t *pText = nsTextFormatter::smprintf(pFmt, pName);
pStream->Append(pText);
nsTextFormatter::smprintf_free(pText);
NS_Free(pFmt);
pStream->AppendLiteral(MSG_LINEBREAK);
}
static void ImportAddressThread(void *stuff)
{
IMPORT_LOG0("In Begin ImportAddressThread\n");
AddressThreadData *pData = (AddressThreadData *)stuff;
uint32_t count = 0;
uint32_t i;
bool import;
uint32_t size;
nsString success;
nsString error;
(void) pData->books->GetLength(&count);
for (i = 0; (i < count) && !(pData->abort); i++) {
nsCOMPtr<nsIImportABDescriptor> book =
do_QueryElementAt(pData->books, i);
if (book) {
import = false;
size = 0;
nsresult rv = book->GetImport(&import);
if (NS_SUCCEEDED(rv) && import)
rv = book->GetSize(&size);
if (NS_SUCCEEDED(rv) && size && import) {
nsString name;
book->GetPreferredName(name);
nsCOMPtr<nsIAddrDatabase> db = pData->dBs->ObjectAt(i);
bool fatalError = false;
pData->currentSize = size;
if (db) {
char16_t *pSuccess = nullptr;
char16_t *pError = nullptr;
/*
if (pData->fieldMap) {
int32_t sz = 0;
int32_t mapIndex;
bool active;
pData->fieldMap->GetMapSize(&sz);
IMPORT_LOG1("**** Field Map Size: %d\n", (int) sz);
for (int32_t i = 0; i < sz; i++) {
pData->fieldMap->GetFieldMap(i, &mapIndex);
pData->fieldMap->GetFieldActive(i, &active);
IMPORT_LOG3("Field map #%d: index=%d, active=%d\n", (int) i, (int) mapIndex, (int) active);
}
}
*/
rv = pData->addressImport->ImportAddressBook(book,
db,
pData->fieldMap,
pData->ldifService,
&pError,
&pSuccess,
&fatalError);
if (NS_SUCCEEDED(rv) && pSuccess) {
success.Append(pSuccess);
NS_Free(pSuccess);
}
if (pError) {
error.Append(pError);
NS_Free(pError);
}
}
else {
nsImportGenericAddressBooks::ReportError(name.get(), &error, pData->stringBundle);
}
pData->currentSize = 0;
pData->currentTotal += size;
if (db)
db->Close(true);
if (fatalError) {
pData->fatalError = true;
break;
}
}
}
}
nsImportGenericAddressBooks::SetLogs(success, error, pData->successLog, pData->errorLog);
if (pData->abort || pData->fatalError) {
// FIXME: do what is necessary to get rid of what has been imported so far.
// Nothing if we went into an existing address book! Otherwise, delete
// the ones we created?
}
}

View file

@ -0,0 +1,64 @@
/* -*- 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 "nsImportEmbeddedImageData.h"
NS_IMPL_ISUPPORTS(nsImportEmbeddedImageData, nsIMsgEmbeddedImageData)
nsImportEmbeddedImageData::nsImportEmbeddedImageData()
{
}
nsImportEmbeddedImageData::nsImportEmbeddedImageData(
nsIURI *aUri, const nsACString &aCid) : m_uri(aUri), m_cid(aCid)
{
}
nsImportEmbeddedImageData::nsImportEmbeddedImageData(
nsIURI *aUri, const nsACString &aCid, const nsACString &aName)
: m_uri(aUri), m_cid(aCid), m_name(aName)
{
}
nsImportEmbeddedImageData::~nsImportEmbeddedImageData()
{
}
NS_IMETHODIMP nsImportEmbeddedImageData::GetUri(nsIURI **aUri)
{
NS_ENSURE_ARG_POINTER(aUri);
NS_IF_ADDREF(*aUri = m_uri);
return NS_OK;
}
NS_IMETHODIMP nsImportEmbeddedImageData::SetUri(nsIURI *aUri)
{
m_uri = aUri;
return NS_OK;
}
NS_IMETHODIMP nsImportEmbeddedImageData::GetCid(nsACString &aCid)
{
aCid = m_cid;
return NS_OK;
}
NS_IMETHODIMP nsImportEmbeddedImageData::SetCid(const nsACString &aCid)
{
m_cid = aCid;
return NS_OK;
}
NS_IMETHODIMP nsImportEmbeddedImageData::GetName(nsACString &aName)
{
aName = m_name;
return NS_OK;
}
NS_IMETHODIMP nsImportEmbeddedImageData::SetName(const nsACString &aName)
{
m_name = aName;
return NS_OK;
}

View file

@ -0,0 +1,32 @@
/* -*- 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 __IMPORTEMBEDDEDIMAGETDATA_H__
#define __IMPORTEMBEDDEDIMAGETDATA_H__
#include "nsIMsgSend.h"
#include "nsStringGlue.h"
#include "nsCOMPtr.h"
#include "nsIURI.h"
class nsImportEmbeddedImageData final : public nsIMsgEmbeddedImageData
{
public:
nsImportEmbeddedImageData(nsIURI *aUri, const nsACString &aCID);
nsImportEmbeddedImageData(nsIURI *aUri, const nsACString &aCID, const nsACString &aName);
nsImportEmbeddedImageData();
NS_DECL_NSIMSGEMBEDDEDIMAGEDATA
NS_DECL_ISUPPORTS
nsCOMPtr<nsIURI> m_uri;
nsCString m_cid;
nsCString m_name;
private:
~nsImportEmbeddedImageData();
};
#endif

View file

@ -0,0 +1,374 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/* 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 "nsImportEncodeScan.h"
#include "nsNetUtil.h"
#define kBeginAppleSingle 0
#define kBeginDataFork 1
#define kBeginResourceFork 2
#define kAddEntries 3
#define kScanningDataFork 4
#define kScanningRsrcFork 5
#define kDoneWithFile 6
uint32_t gAppleSingleHeader[6] = {0x00051600, 0x00020000, 0, 0, 0, 0};
#define kAppleSingleHeaderSize (6 * sizeof(uint32_t))
#ifdef _MAC_IMPORT_CODE
#include "MoreFilesExtras.h"
#include "MoreDesktopMgr.h"
CInfoPBRec gCatInfoPB;
U32 g2000Secs = 0;
long gGMTDelta = 0;
long GetGmtDelta(void);
U32 Get2000Secs(void);
long GetGmtDelta(void)
{
MachineLocation myLocation;
ReadLocation(&myLocation);
long myDelta = BitAnd(myLocation.u.gmtDelta, 0x00FFFFFF);
if (BitTst(&myDelta, 23))
myDelta = BitOr(myDelta, 0xFF000000);
return myDelta;
}
U32 Get2000Secs(void)
{
DateTimeRec dr;
dr.year = 2000;
dr.month = 1;
dr.day = 1;
dr.hour = 0;
dr.minute = 0;
dr.second = 0;
dr.dayOfWeek = 0;
U32 result;
DateToSeconds(&dr, &result);
return result;
}
#endif
nsImportEncodeScan::nsImportEncodeScan()
{
m_isAppleSingle = false;
m_encodeScanState = 0;
m_resourceForkSize = 0;
m_dataForkSize = 0;
}
nsImportEncodeScan::~nsImportEncodeScan()
{
}
bool nsImportEncodeScan::InitEncodeScan(bool appleSingleEncode, nsIFile *fileLoc, const char *pName, uint8_t * pBuf, uint32_t sz)
{
CleanUpEncodeScan();
m_isAppleSingle = appleSingleEncode;
m_encodeScanState = kBeginAppleSingle;
m_pInputFile = do_QueryInterface(fileLoc);
m_useFileName = pName;
m_pBuf = pBuf;
m_bufSz = sz;
if (!m_isAppleSingle)
{
if (!m_inputStream)
{
nsresult rv = NS_NewLocalFileInputStream(getter_AddRefs(m_inputStream), m_pInputFile);
NS_ENSURE_SUCCESS(rv, false);
}
InitScan(m_inputStream, pBuf, sz);
}
else {
#ifdef _MAC_IMPORT_CODE
// Fill in the file sizes
m_resourceForkSize = fileLoc.GetMacFileSize(UFileLocation::eResourceFork);
m_dataForkSize = fileLoc.GetMacFileSize(UFileLocation::eDataFork);
#endif
}
return true;
}
void nsImportEncodeScan::CleanUpEncodeScan(void)
{
m_pInputStream->Close();
m_pInputStream = nullptr;
m_pInputFile = nullptr;
}
// 26 + 12 per entry
void nsImportEncodeScan::FillInEntries(int numEntries)
{
#ifdef _MAC_IMPORT_CODE
int len = m_useFileName.GetLength();
if (len < 32)
len = 32;
long entry[3];
long fileOffset = 26 + (12 * numEntries);
entry[0] = 3;
entry[1] = fileOffset;
entry[2] = m_useFileName.GetLength();
fileOffset += len;
MemCpy(m_pBuf + m_bytesInBuf, entry, 12);
m_bytesInBuf += 12;
Str255 comment;
comment[0] = 0;
OSErr err = FSpDTGetComment(m_inputFileLoc, comment);
if (comment[0] > 200)
comment[0] = 200;
entry[0] = 4;
entry[1] = fileOffset;
entry[2] = comment[0];
fileOffset += 200;
MemCpy(m_pBuf + m_bytesInBuf, entry, 12);
m_bytesInBuf += 12;
entry[0] = 8;
entry[1] = fileOffset;
entry[2] = 16;
fileOffset += 16;
MemCpy(m_pBuf + m_bytesInBuf, entry, 12);
m_bytesInBuf += 12;
entry[0] = 9;
entry[1] = fileOffset;
entry[2] = 32;
fileOffset += 32;
MemCpy(m_pBuf + m_bytesInBuf, entry, 12);
m_bytesInBuf += 12;
entry[0] = 10;
entry[1] = fileOffset;
entry[2] = 4;
fileOffset += 4;
MemCpy(m_pBuf + m_bytesInBuf, entry, 12);
m_bytesInBuf += 12;
if (m_resourceForkSize) {
entry[0] = 2;
entry[1] = fileOffset;
entry[2] = m_resourceForkSize;
fileOffset += m_resourceForkSize;
MemCpy(m_pBuf + m_bytesInBuf, entry, 12);
m_bytesInBuf += 12;
}
if (m_dataForkSize) {
entry[0] = 1;
entry[1] = fileOffset;
entry[2] = m_dataForkSize;
fileOffset += m_dataForkSize;
MemCpy(m_pBuf + m_bytesInBuf, entry, 12);
m_bytesInBuf += 12;
}
#endif
}
bool nsImportEncodeScan::AddEntries(void)
{
#ifdef _MAC_IMPORT_CODE
if (!g2000Secs) {
g2000Secs = Get2000Secs();
gGMTDelta = GetGmtDelta();
}
MemCpy(m_pBuf + m_bytesInBuf, (PC_S8) m_useFileName, m_useFileName.GetLength());
m_bytesInBuf += m_useFileName.GetLength();
if (m_useFileName.GetLength() < 32) {
int len = m_useFileName.GetLength();
while (len < 32) {
*((P_S8)m_pBuf + m_bytesInBuf) = 0;
m_bytesInBuf++;
len++;
}
}
Str255 comment;
comment[0] = 0;
OSErr err = FSpDTGetComment(m_inputFileLoc, comment);
comment[0] = 200;
MemCpy(m_pBuf + m_bytesInBuf, &(comment[1]), comment[0]);
m_bytesInBuf += comment[0];
long dates[4];
dates[0] = gCatInfoPB.hFileInfo.ioFlCrDat;
dates[1] = gCatInfoPB.hFileInfo.ioFlMdDat;
dates[2] = gCatInfoPB.hFileInfo.ioFlBkDat;
dates[3] = 0x80000000;
for (short i = 0; i < 3; i++) {
dates[i] -= g2000Secs;
dates[i] += gGMTDelta;
}
MemCpy(m_pBuf + m_bytesInBuf, dates, 16);
m_bytesInBuf += 16;
FInfo fInfo = gCatInfoPB.hFileInfo.ioFlFndrInfo;
FXInfo fxInfo = gCatInfoPB.hFileInfo.ioFlXFndrInfo;
fInfo.fdFlags = 0;
fInfo.fdLocation.h = 0;
fInfo.fdLocation.v = 0;
fInfo.fdFldr = 0;
MemSet(&fxInfo, 0, sizeof(fxInfo));
MemCpy(m_pBuf + m_bytesInBuf, &fInfo, 16);
m_bytesInBuf += 16;
MemCpy(m_pBuf + m_bytesInBuf, &fxInfo, 16);
m_bytesInBuf += 16;
dates[0] = 0;
if ((gCatInfoPB.hFileInfo.ioFlAttrib & 1) != 0)
dates[0] |= 1;
MemCpy(m_pBuf + m_bytesInBuf, dates, 4);
m_bytesInBuf += 4;
#endif
return true;
}
bool nsImportEncodeScan::Scan(bool *pDone)
{
nsresult rv;
*pDone = false;
if (m_isAppleSingle) {
// Stuff the buffer with things needed to encode the file...
// then just allow UScanFile to handle each fork, but be careful
// when handling eof.
switch(m_encodeScanState) {
case kBeginAppleSingle: {
#ifdef _MAC_IMPORT_CODE
OSErr err = GetCatInfoNoName(m_inputFileLoc.GetVRefNum(), m_inputFileLoc.GetParID(), m_inputFileLoc.GetFileNamePtr(), &gCatInfoPB);
if (err != noErr)
return FALSE;
#endif
m_eof = false;
m_pos = 0;
memcpy(m_pBuf, gAppleSingleHeader, kAppleSingleHeaderSize);
m_bytesInBuf = kAppleSingleHeaderSize;
int numEntries = 5;
if (m_dataForkSize)
numEntries++;
if (m_resourceForkSize)
numEntries++;
memcpy(m_pBuf + m_bytesInBuf, &numEntries, sizeof(numEntries));
m_bytesInBuf += sizeof(numEntries);
FillInEntries(numEntries);
m_encodeScanState = kAddEntries;
return ScanBuffer(pDone);
}
break;
case kBeginDataFork: {
if (!m_dataForkSize) {
m_encodeScanState = kDoneWithFile;
return true;
}
// Initialize the scan of the data fork...
if (!m_inputStream)
{
rv = NS_NewLocalFileInputStream(getter_AddRefs(m_inputStream), m_pInputFile);
NS_ENSURE_SUCCESS(rv, false);
}
m_encodeScanState = kScanningDataFork;
return true;
}
break;
case kScanningDataFork: {
bool result = FillBufferFromFile();
if (!result)
return false;
if (m_eof) {
m_eof = false;
result = ScanBuffer(pDone);
if (!result)
return false;
m_inputStream->Close();
m_inputStream = nullptr;
m_encodeScanState = kDoneWithFile;
return true;
}
else
return ScanBuffer(pDone);
}
break;
case kScanningRsrcFork: {
bool result = FillBufferFromFile();
if (!result)
return false;
if (m_eof) {
m_eof = false;
result = ScanBuffer(pDone);
if (!result)
return false;
m_inputStream->Close();
m_inputStream = nullptr;
m_encodeScanState = kBeginDataFork;
return true;
}
else
return ScanBuffer(pDone);
}
break;
case kBeginResourceFork: {
if (!m_resourceForkSize) {
m_encodeScanState = kBeginDataFork;
return true;
}
/*
// FIXME: Open the resource fork on the Mac!!!
m_fH = UFile::OpenRsrcFileRead(m_inputFileLoc);
if (m_fH == TR_FILE_ERROR)
return FALSE;
*/
m_encodeScanState = kScanningRsrcFork;
return true;
}
break;
case kAddEntries: {
ShiftBuffer();
if (!AddEntries())
return false;
m_encodeScanState = kBeginResourceFork;
return ScanBuffer(pDone);
}
break;
case kDoneWithFile: {
ShiftBuffer();
m_eof = true;
if (!ScanBuffer(pDone))
return false;
*pDone = true;
return true;
}
break;
}
}
else
return nsImportScanFile::Scan(pDone);
return false;
}

View file

@ -0,0 +1,39 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/* 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 nsImportEncodeScan_h___
#define nsImportEncodeScan_h___
#include "mozilla/Attributes.h"
#include "nsIFile.h"
#include "nsImportScanFile.h"
#include "nsStringGlue.h"
class nsImportEncodeScan : public nsImportScanFile {
public:
nsImportEncodeScan();
~nsImportEncodeScan();
bool InitEncodeScan(bool appleSingleEncode, nsIFile *pFile, const char *pName, uint8_t * pBuf, uint32_t sz);
void CleanUpEncodeScan(void);
virtual bool Scan(bool *pDone) override;
protected:
void FillInEntries(int numEntries);
bool AddEntries(void);
protected:
bool m_isAppleSingle;
nsCOMPtr<nsIFile> m_pInputFile;
nsCOMPtr<nsIInputStream> m_inputStream;
int m_encodeScanState;
long m_resourceForkSize;
long m_dataForkSize;
nsCString m_useFileName;
};
#endif /* nsImportEncodeScan_h__ */

View file

@ -0,0 +1,384 @@
/* -*- 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 "nscore.h"
#include "nsIStringBundle.h"
#include "nsImportFieldMap.h"
#include "nsImportStringBundle.h"
#include "nsCRTGlue.h"
#include "ImportDebug.h"
#include "nsCOMPtr.h"
////////////////////////////////////////////////////////////////////////
NS_METHOD nsImportFieldMap::Create(nsIStringBundle *aBundle, nsISupports *aOuter, REFNSIID aIID, void **aResult)
{
if (aOuter)
return NS_ERROR_NO_AGGREGATION;
nsImportFieldMap *it = new nsImportFieldMap(aBundle);
if (it == nullptr)
return NS_ERROR_OUT_OF_MEMORY;
NS_ADDREF(it);
nsresult rv = it->QueryInterface(aIID, aResult);
NS_RELEASE(it);
return rv;
}
NS_IMPL_ISUPPORTS(nsImportFieldMap, nsIImportFieldMap)
NS_IMETHODIMP nsImportFieldMap::GetSkipFirstRecord(bool *result)
{
NS_ENSURE_ARG_POINTER(result);
*result = m_skipFirstRecord;
return NS_OK;
}
NS_IMETHODIMP nsImportFieldMap::SetSkipFirstRecord(bool aResult)
{
m_skipFirstRecord = aResult;
return NS_OK;
}
nsImportFieldMap::nsImportFieldMap(nsIStringBundle *aBundle)
{
m_numFields = 0;
m_pFields = nullptr;
m_pActive = nullptr;
m_allocated = 0;
// need to init the description array
m_mozFieldCount = 0;
m_skipFirstRecord = false;
nsCOMPtr<nsIStringBundle> pBundle = aBundle;
nsString *pStr;
for (int32_t i = IMPORT_FIELD_DESC_START; i <= IMPORT_FIELD_DESC_END; i++, m_mozFieldCount++) {
pStr = new nsString();
if (pBundle) {
nsImportStringBundle::GetStringByID(i, pBundle, *pStr);
}
else
pStr->AppendInt(i);
m_descriptions.AppendElement(pStr);
}
}
nsImportFieldMap::~nsImportFieldMap()
{
if (m_pFields)
delete [] m_pFields;
if (m_pActive)
delete [] m_pActive;
nsString * pStr;
for (int32_t i = 0; i < m_mozFieldCount; i++) {
pStr = m_descriptions.ElementAt(i);
delete pStr;
}
m_descriptions.Clear();
}
NS_IMETHODIMP nsImportFieldMap::GetNumMozFields(int32_t *aNumFields)
{
NS_PRECONDITION(aNumFields != nullptr, "null ptr");
if (!aNumFields)
return NS_ERROR_NULL_POINTER;
*aNumFields = m_mozFieldCount;
return NS_OK;
}
NS_IMETHODIMP nsImportFieldMap::GetMapSize(int32_t *aNumFields)
{
NS_PRECONDITION(aNumFields != nullptr, "null ptr");
if (!aNumFields)
return NS_ERROR_NULL_POINTER;
*aNumFields = m_numFields;
return NS_OK;
}
NS_IMETHODIMP nsImportFieldMap::GetFieldDescription(int32_t index, char16_t **_retval)
{
NS_PRECONDITION(_retval != nullptr, "null ptr");
if (!_retval)
return NS_ERROR_NULL_POINTER;
*_retval = nullptr;
if ((index < 0) || ((size_t)index >= m_descriptions.Length()))
return NS_ERROR_FAILURE;
*_retval = ToNewUnicode(*(m_descriptions.ElementAt(index)));
return NS_OK;
}
NS_IMETHODIMP nsImportFieldMap::SetFieldMapSize(int32_t size)
{
nsresult rv = Allocate(size);
if (NS_FAILED(rv))
return rv;
m_numFields = size;
return NS_OK;
}
NS_IMETHODIMP nsImportFieldMap::DefaultFieldMap(int32_t size)
{
nsresult rv = SetFieldMapSize(size);
if (NS_FAILED(rv))
return rv;
for (int32_t i = 0; i < size; i++) {
m_pFields[i] = i;
m_pActive[i] = true;
}
return NS_OK;
}
NS_IMETHODIMP nsImportFieldMap::GetFieldMap(int32_t index, int32_t *_retval)
{
NS_PRECONDITION(_retval != nullptr, "null ptr");
if (!_retval)
return NS_ERROR_NULL_POINTER;
if ((index < 0) || (index >= m_numFields))
return NS_ERROR_FAILURE;
*_retval = m_pFields[index];
return NS_OK;
}
NS_IMETHODIMP nsImportFieldMap::SetFieldMap(int32_t index, int32_t fieldNum)
{
if (index == -1) {
nsresult rv = Allocate(m_numFields + 1);
if (NS_FAILED(rv))
return rv;
index = m_numFields;
m_numFields++;
}
else {
if ((index < 0) || (index >= m_numFields))
return NS_ERROR_FAILURE;
}
if ((fieldNum != -1) && ((fieldNum < 0) || (fieldNum >= m_mozFieldCount)))
return NS_ERROR_FAILURE;
m_pFields[index] = fieldNum;
return NS_OK;
}
NS_IMETHODIMP nsImportFieldMap::GetFieldActive(int32_t index, bool *active)
{
NS_PRECONDITION(active != nullptr, "null ptr");
if (!active)
return NS_ERROR_NULL_POINTER;
if ((index < 0) || (index >= m_numFields))
return NS_ERROR_FAILURE;
*active = m_pActive[index];
return NS_OK;
}
NS_IMETHODIMP nsImportFieldMap::SetFieldActive(int32_t index, bool active)
{
if ((index < 0) || (index >= m_numFields))
return NS_ERROR_FAILURE;
m_pActive[index] = active;
return NS_OK;
}
NS_IMETHODIMP nsImportFieldMap::SetFieldValue(nsIAddrDatabase *database, nsIMdbRow *row, int32_t fieldNum, const char16_t *value)
{
NS_PRECONDITION(database != nullptr, "null ptr");
NS_PRECONDITION(row != nullptr, "null ptr");
NS_PRECONDITION(value != nullptr, "null ptr");
if (!database || !row || !value)
return NS_ERROR_NULL_POINTER;
// Allow the special value for a null field
if (fieldNum == -1)
return NS_OK;
if ((fieldNum < 0) || (fieldNum >= m_mozFieldCount))
return NS_ERROR_FAILURE;
// UGGG!!!!! lot's of typing here!
nsresult rv;
nsString str(value);
char *pVal = ToNewUTF8String(str);
switch(fieldNum) {
case 0:
rv = database->AddFirstName(row, pVal);
break;
case 1:
rv = database->AddLastName(row, pVal);
break;
case 2:
rv = database->AddDisplayName(row, pVal);
break;
case 3:
rv = database->AddNickName(row, pVal);
break;
case 4:
rv = database->AddPrimaryEmail(row, pVal);
break;
case 5:
rv = database->Add2ndEmail(row, pVal);
break;
case 6:
rv = database->AddWorkPhone(row, pVal);
break;
case 7:
rv = database->AddHomePhone(row, pVal);
break;
case 8:
rv = database->AddFaxNumber(row, pVal);
break;
case 9:
rv = database->AddPagerNumber(row, pVal);
break;
case 10:
rv = database->AddCellularNumber(row, pVal);
break;
case 11:
rv = database->AddHomeAddress(row, pVal);
break;
case 12:
rv = database->AddHomeAddress2(row, pVal);
break;
case 13:
rv = database->AddHomeCity(row, pVal);
break;
case 14:
rv = database->AddHomeState(row, pVal);
break;
case 15:
rv = database->AddHomeZipCode(row, pVal);
break;
case 16:
rv = database->AddHomeCountry(row, pVal);
break;
case 17:
rv = database->AddWorkAddress(row, pVal);
break;
case 18:
rv = database->AddWorkAddress2(row, pVal);
break;
case 19:
rv = database->AddWorkCity(row, pVal);
break;
case 20:
rv = database->AddWorkState(row, pVal);
break;
case 21:
rv = database->AddWorkZipCode(row, pVal);
break;
case 22:
rv = database->AddWorkCountry(row, pVal);
break;
case 23:
rv = database->AddJobTitle(row, pVal);
break;
case 24:
rv = database->AddDepartment(row, pVal);
break;
case 25:
rv = database->AddCompany(row, pVal);
break;
case 26:
rv = database->AddWebPage1(row, pVal);
break;
case 27:
rv = database->AddWebPage2(row, pVal);
break;
case 28:
rv = database->AddBirthYear(row, pVal);
break;
case 29:
rv = database->AddBirthMonth(row, pVal);
break;
case 30:
rv = database->AddBirthDay(row, pVal);
break;
case 31:
rv = database->AddCustom1(row, pVal);
break;
case 32:
rv = database->AddCustom2(row, pVal);
break;
case 33:
rv = database->AddCustom3(row, pVal);
break;
case 34:
rv = database->AddCustom4(row, pVal);
break;
case 35:
rv = database->AddNotes(row, pVal);
break;
case 36:
rv = database->AddAimScreenName(row, pVal);
break;
default:
/* Get the field description, and add it as an anonymous attr? */
/* OR WHAT???? */
{
rv = NS_ERROR_FAILURE;
}
}
NS_Free(pVal);
return rv;
}
nsresult nsImportFieldMap::Allocate(int32_t newSize)
{
if (newSize <= m_allocated)
return NS_OK;
int32_t sz = m_allocated;
while (sz < newSize)
sz += 30;
int32_t *pData = new int32_t[ sz];
if (!pData)
return NS_ERROR_OUT_OF_MEMORY;
bool *pActive = new bool[sz];
if (!pActive) {
delete [] pData;
return NS_ERROR_OUT_OF_MEMORY;
}
int32_t i;
for (i = 0; i < sz; i++) {
pData[i] = -1;
pActive[i] = true;
}
if (m_numFields) {
for (i = 0; i < m_numFields; i++) {
pData[i] = m_pFields[i];
pActive[i] = m_pActive[i];
}
delete [] m_pFields;
delete [] m_pActive;
}
m_allocated = sz;
m_pFields = pData;
m_pActive = pActive;
return NS_OK;
}

View file

@ -0,0 +1,46 @@
/* -*- 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 nsImportFieldMap_h___
#define nsImportFieldMap_h___
#include "nscore.h"
#include "nsIImportFieldMap.h"
#include "nsIAddrDatabase.h"
#include "nsTArray.h"
#include "nsString.h"
////////////////////////////////////////////////////////////////////////
class nsIStringBundle;
class nsImportFieldMap : public nsIImportFieldMap
{
public:
NS_DECL_THREADSAFE_ISUPPORTS
NS_DECL_NSIIMPORTFIELDMAP
nsImportFieldMap(nsIStringBundle *aBundle);
static NS_METHOD Create(nsIStringBundle *aBundle, nsISupports *aOuter, REFNSIID aIID, void **aResult);
private:
virtual ~nsImportFieldMap();
nsresult Allocate(int32_t newSize);
private:
int32_t m_numFields;
int32_t * m_pFields;
bool * m_pActive;
int32_t m_allocated;
nsTArray<nsString*> m_descriptions;
int32_t m_mozFieldCount;
bool m_skipFirstRecord;
};
#endif

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,39 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/* 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 "nsImportMailboxDescriptor.h"
#include "nsComponentManagerUtils.h"
////////////////////////////////////////////////////////////////////////
NS_METHOD nsImportMailboxDescriptor::Create(nsISupports *aOuter, REFNSIID aIID, void **aResult)
{
if (aOuter)
return NS_ERROR_NO_AGGREGATION;
nsImportMailboxDescriptor *it = new nsImportMailboxDescriptor();
if (it == nullptr)
return NS_ERROR_OUT_OF_MEMORY;
NS_ADDREF(it);
nsresult rv = it->QueryInterface(aIID, aResult);
NS_RELEASE(it);
return rv;
}
NS_IMPL_ISUPPORTS(nsImportMailboxDescriptor, nsIImportMailboxDescriptor)
nsImportMailboxDescriptor::nsImportMailboxDescriptor()
{
m_import = true;
m_size = 0;
m_depth = 0;
m_id = 0;
m_pFile = do_CreateInstance(NS_LOCAL_FILE_CONTRACTID);
}

View file

@ -0,0 +1,63 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/* 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 nsImportMailboxDescriptor_h___
#define nsImportMailboxDescriptor_h___
#include "mozilla/Attributes.h"
#include "nscore.h"
#include "nsStringGlue.h"
#include "nsIImportMailboxDescriptor.h"
#include "nsIFile.h"
#include "nsCOMPtr.h"
////////////////////////////////////////////////////////////////////////
class nsImportMailboxDescriptor : public nsIImportMailboxDescriptor
{
public:
NS_DECL_THREADSAFE_ISUPPORTS
NS_IMETHOD GetIdentifier(uint32_t *pIdentifier) override { *pIdentifier = m_id; return NS_OK;}
NS_IMETHOD SetIdentifier(uint32_t ident) override { m_id = ident; return NS_OK;}
/* attribute unsigned long depth; */
NS_IMETHOD GetDepth(uint32_t *pDepth) override { *pDepth = m_depth; return NS_OK;}
NS_IMETHOD SetDepth(uint32_t theDepth) override { m_depth = theDepth; return NS_OK;}
/* attribute unsigned long size; */
NS_IMETHOD GetSize(uint32_t *pSize) override { *pSize = m_size; return NS_OK;}
NS_IMETHOD SetSize(uint32_t theSize) override { m_size = theSize; return NS_OK;}
/* attribute wstring displayName; */
NS_IMETHOD GetDisplayName(char16_t **pName) override { *pName = ToNewUnicode(m_displayName); return NS_OK;}
NS_IMETHOD SetDisplayName(const char16_t * pName) override { m_displayName = pName; return NS_OK;}
/* attribute boolean import; */
NS_IMETHOD GetImport(bool *pImport) override { *pImport = m_import; return NS_OK;}
NS_IMETHOD SetImport(bool doImport) override { m_import = doImport; return NS_OK;}
/* readonly attribute nsIFile file; */
NS_IMETHOD GetFile(nsIFile * *aFile) override { if (m_pFile) { NS_ADDREF(*aFile = m_pFile); return NS_OK;} else return NS_ERROR_FAILURE; }
nsImportMailboxDescriptor();
static NS_METHOD Create(nsISupports *aOuter, REFNSIID aIID, void **aResult);
private:
virtual ~nsImportMailboxDescriptor() {}
uint32_t m_id; // used by creator of the structure
uint32_t m_depth; // depth in the hierarchy
nsString m_displayName;// name of this mailbox
nsCOMPtr <nsIFile> m_pFile; // source file (if applicable)
uint32_t m_size;
bool m_import; // import it or not?
};
#endif

View file

@ -0,0 +1,411 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/* 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 "nsImportMimeEncode.h"
#include "ImportCharSet.h"
#include "ImportTranslate.h"
#define kNoState 0
#define kStartState 1
#define kEncodeState 2
#define kDoneState 3
#define kEncodeBufferSz (8192 * 8)
nsImportMimeEncode::nsImportMimeEncode()
{
m_pOut = nullptr;
m_state = kNoState;
m_bytesProcessed = 0;
m_pInputBuf = nullptr;
}
nsImportMimeEncode::~nsImportMimeEncode()
{
delete [] m_pInputBuf;
}
void nsImportMimeEncode::EncodeFile(nsIFile *pInFile, ImportOutFile *pOut, const char *pFileName, const char *pMimeType)
{
m_fileName = pFileName;
m_mimeType = pMimeType;
m_pMimeFile = pInFile;
m_pOut = pOut;
m_state = kStartState;
}
void nsImportMimeEncode::CleanUp(void)
{
CleanUpEncodeScan();
}
bool nsImportMimeEncode::SetUpEncode(void)
{
nsCString errStr;
if (!m_pInputBuf) {
m_pInputBuf = new uint8_t[kEncodeBufferSz];
}
m_appleSingle = false;
#ifdef _MAC_IMPORT_CODE
// First let's see just what kind of beast we have?
// For files with only a data fork and a known mime type
// proceed with normal mime encoding just as on the PC.
// For unknown mime types and files with both forks,
// encode as AppleSingle format.
if (m_filePath.GetMacFileSize(UFileLocation::eResourceFork) || !pMimeType) {
m_appleSingle = TRUE;
m_mimeType = "application/applefile";
}
#endif
if (!InitEncodeScan(m_appleSingle, m_pMimeFile, m_fileName.get(), m_pInputBuf, kEncodeBufferSz)) {
return false;
}
m_state = kEncodeState;
m_lineLen = 0;
// Write out the boundary header
bool bResult = true;
bResult = m_pOut->WriteStr("Content-type: ");
if (bResult)
bResult = m_pOut->WriteStr(m_mimeType.get());
#ifdef _MAC_IMPORT_CODE
// include the type an creator here
if (bResult)
bResult = m_pOut->WriteStr("; x-mac-type=\"");
U8 hex[8];
LongToHexBytes(m_filePath.GetFileType(), hex);
if (bResult)
bResult = m_pOut->WriteData(hex, 8);
LongToHexBytes(m_filePath.GetFileCreator(), hex);
if (bResult)
bResult = m_pOut->WriteStr("\"; x-mac-creator=\"");
if (bResult)
bResult = m_pOut->WriteData(hex, 8);
if (bResult)
bResult = m_pOut->WriteStr("\"");
#endif
/*
if (bResult)
bResult = m_pOut->WriteStr(gMimeTypeFileName);
*/
if (bResult)
bResult = m_pOut->WriteStr(";\x0D\x0A");
nsCString fName;
bool trans = TranslateFileName(m_fileName, fName);
if (bResult)
bResult = WriteFileName(fName, trans, "name");
if (bResult)
bResult = m_pOut->WriteStr("Content-transfer-encoding: base64");
if (bResult)
bResult = m_pOut->WriteEol();
if (bResult)
bResult = m_pOut->WriteStr("Content-Disposition: attachment;\x0D\x0A");
if (bResult)
bResult = WriteFileName(fName, trans, "filename");
if (bResult)
bResult = m_pOut->WriteEol();
if (!bResult) {
CleanUp();
}
return bResult;
}
bool nsImportMimeEncode::DoWork(bool *pDone)
{
*pDone = false;
switch(m_state) {
case kNoState:
return false;
break;
case kStartState:
return SetUpEncode();
break;
case kEncodeState:
if (!Scan(pDone)) {
CleanUp();
return false;
}
if (*pDone) {
*pDone = false;
m_state = kDoneState;
}
break;
case kDoneState:
CleanUp();
m_state = kNoState;
*pDone = true;
break;
}
return true;
}
static uint8_t gBase64[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
bool nsImportMimeEncode::ScanBuffer(bool *pDone)
{
uint32_t pos = m_pos;
uint32_t start = pos;
uint8_t * pChar = m_pBuf + pos;
uint32_t max = m_bytesInBuf;
uint8_t byte[4];
uint32_t lineLen = m_lineLen;
while ((pos + 2) < max) {
// Encode 3 bytes
byte[0] = gBase64[*pChar >> 2];
byte[1] = gBase64[(((*pChar) & 0x3)<< 4) | (((*(pChar + 1)) & 0xF0) >> 4)];
pChar++;
byte[2] = gBase64[(((*pChar) & 0xF) << 2) | (((*(pChar + 1)) & 0xC0) >>6)];
pChar++;
byte[3] = gBase64[(*pChar) & 0x3F];
if (!m_pOut->WriteData(byte, 4))
return false;
pos += 3;
pChar++;
lineLen += 4;
if (lineLen > 71) {
if (!m_pOut->WriteEol())
return false;
lineLen = 0;
}
}
if ((pos < max) && m_eof) {
// Get the last few bytes!
byte[0] = gBase64[*pChar >> 2];
pos++;
if (pos < max) {
byte[1] = gBase64[(((*pChar) & 0x3)<< 4) | (((*(pChar + 1)) & 0xF0) >> 4)];
pChar++;
pos++;
if (pos < max) {
// Should be dead code!! (Then why is it here doofus?)
byte[2] = gBase64[(((*pChar) & 0xF) << 2) | (((*(pChar + 1)) & 0xC0) >>6)];
pChar++;
byte[3] = gBase64[(*pChar) & 0x3F];
pos++;
}
else {
byte[2] = gBase64[(((*pChar) & 0xF) << 2)];
byte[3] = '=';
}
}
else {
byte[1] = gBase64[(((*pChar) & 0x3)<< 4)];
byte[2] = '=';
byte[3] = '=';
}
if (!m_pOut->WriteData(byte, 4))
return false;
if (!m_pOut->WriteEol())
return false;
}
else if (m_eof) {
/*
byte[0] = '=';
if (!m_pOut->WriteData(byte, 1))
return FALSE;
*/
if (!m_pOut->WriteEol())
return false;
}
m_lineLen = (int) lineLen;
m_pos = pos;
m_bytesProcessed += (pos - start);
return true;
}
bool nsImportMimeEncode::TranslateFileName(nsCString& inFile, nsCString& outFile)
{
const uint8_t * pIn = (const uint8_t *) inFile.get();
int len = inFile.Length();
while (len) {
if (!ImportCharSet::IsUSAscii(*pIn))
break;
len--;
pIn++;
}
if (len) {
// non US ascii!
// assume this string needs translating...
if (!ImportTranslate::ConvertString(inFile, outFile, true)) {
outFile = inFile;
return false;
}
else {
return true;
}
}
else {
outFile = inFile;
return false;
}
}
bool nsImportMimeEncode::WriteFileName(nsCString& fName, bool wasTrans, const char *pTag)
{
int tagNum = 0;
int idx = 0;
bool result = true;
int len;
nsCString numStr;
while ((((fName.Length() - idx) + strlen(pTag)) > 70) && result) {
len = 68 - strlen(pTag) - 5;
if (wasTrans) {
if (fName.CharAt(idx + len - 1) == '%')
len--;
else if (fName.CharAt(idx + len - 2) == '%')
len -= 2;
}
if (result)
result = m_pOut->WriteStr("\x09");
if (result)
result = m_pOut->WriteStr(pTag);
numStr = "*";
numStr.AppendInt(tagNum);
if (result)
result = m_pOut->WriteStr(numStr.get());
if (wasTrans && result)
result = m_pOut->WriteStr("*=");
else if (result)
result = m_pOut->WriteStr("=\"");
if (result)
result = m_pOut->WriteData(((const uint8_t *)fName.get()) + idx, len);
if (wasTrans && result)
result = m_pOut->WriteStr("\x0D\x0A");
else if (result)
result = m_pOut->WriteStr("\"\x0D\x0A");
idx += len;
tagNum++;
}
if (idx) {
if ((fName.Length() - idx) > 0) {
if (result)
result = m_pOut->WriteStr("\x09");
if (result)
result = m_pOut->WriteStr(pTag);
numStr = "*";
numStr.AppendInt(tagNum);
if (result)
result = m_pOut->WriteStr(numStr.get());
if (wasTrans && result)
result = m_pOut->WriteStr("*=");
else if (result)
result = m_pOut->WriteStr("=\"");
if (result)
result = m_pOut->WriteData(((const uint8_t *)fName.get()) + idx, fName.Length() - idx);
if (wasTrans && result)
result = m_pOut->WriteStr("\x0D\x0A");
else if (result)
result = m_pOut->WriteStr("\"\x0D\x0A");
}
}
else {
if (result)
result = m_pOut->WriteStr("\x09");
if (result)
result = m_pOut->WriteStr(pTag);
if (wasTrans && result)
result = m_pOut->WriteStr("*=");
else if (result)
result = m_pOut->WriteStr("=\"");
if (result)
result = m_pOut->WriteStr(fName.get());
if (wasTrans && result)
result = m_pOut->WriteStr("\x0D\x0A");
else if (result)
result = m_pOut->WriteStr("\"\x0D\x0A");
}
return result;
}
//////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////
nsIImportMimeEncodeImpl::nsIImportMimeEncodeImpl()
{
m_pOut = nullptr;
m_pEncode = nullptr;
}
nsIImportMimeEncodeImpl::~nsIImportMimeEncodeImpl()
{
if (m_pOut)
delete m_pOut;
if (m_pEncode)
delete m_pEncode;
}
NS_IMPL_ISUPPORTS(nsIImportMimeEncodeImpl, nsIImportMimeEncode)
NS_METHOD nsIImportMimeEncodeImpl::EncodeFile(nsIFile *inFile, nsIFile *outFile, const char *fileName, const char *mimeType)
{
return Initialize(inFile, outFile, fileName, mimeType);
}
NS_METHOD nsIImportMimeEncodeImpl::DoWork(bool *done, bool *_retval)
{
if (done && _retval && m_pEncode) {
*_retval = m_pEncode->DoWork(done);
return NS_OK;
}
return NS_ERROR_FAILURE;
}
NS_METHOD nsIImportMimeEncodeImpl::NumBytesProcessed(int32_t *_retval)
{
if (m_pEncode && _retval)
*_retval = m_pEncode->NumBytesProcessed();
return NS_OK;
}
NS_METHOD nsIImportMimeEncodeImpl::DoEncoding(bool *_retval)
{
if (_retval && m_pEncode) {
bool done = false;
while (m_pEncode->DoWork(&done) && !done);
*_retval = done;
return NS_OK;
}
return NS_ERROR_FAILURE;
}
NS_METHOD nsIImportMimeEncodeImpl::Initialize(nsIFile *inFile, nsIFile *outFile, const char *fileName, const char *mimeType)
{
delete m_pEncode;
delete m_pOut;
m_pOut = new ImportOutFile();
m_pOut->InitOutFile(outFile);
m_pEncode = new nsImportMimeEncode();
m_pEncode->EncodeFile(inFile, m_pOut, fileName, mimeType);
return NS_OK;
}

View file

@ -0,0 +1,73 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/* 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 nsImportMimeEncode_h__
#define nsImportMimeEncode_h__
#include "mozilla/Attributes.h"
#include "nsImportScanFile.h"
#include "ImportOutFile.h"
#include "nsImportEncodeScan.h"
#include "nsStringGlue.h"
#include "nsIImportMimeEncode.h"
// Content-Type: image/gif; name="blah.xyz"
// Content-Transfer-Encoding: base64
// Content-Disposition: attachment; filename="blah.xyz"
class nsImportMimeEncode : public nsImportEncodeScan {
public:
nsImportMimeEncode();
~nsImportMimeEncode();
void EncodeFile(nsIFile *pInFile, ImportOutFile *pOut, const char *pFileName, const char *pMimeType);
bool DoWork(bool *pDone);
long NumBytesProcessed(void) { long val = m_bytesProcessed; m_bytesProcessed = 0; return val;}
protected:
void CleanUp(void);
bool SetUpEncode(void);
bool WriteFileName(nsCString& fName, bool wasTrans, const char *pTag);
bool TranslateFileName(nsCString& inFile, nsCString& outFile);
virtual bool ScanBuffer(bool *pDone) override;
protected:
nsCString m_fileName;
nsCOMPtr <nsIFile> m_pMimeFile;
ImportOutFile * m_pOut;
nsCString m_mimeType;
int m_state;
long m_bytesProcessed;
uint8_t * m_pInputBuf;
bool m_appleSingle;
// Actual encoding variables
int m_lineLen;
};
class nsIImportMimeEncodeImpl : public nsIImportMimeEncode {
public:
NS_DECL_ISUPPORTS
NS_DECL_NSIIMPORTMIMEENCODE
nsIImportMimeEncodeImpl();
private:
virtual ~nsIImportMimeEncodeImpl();
ImportOutFile * m_pOut;
nsImportMimeEncode * m_pEncode;
};
#endif /* nsImportMimeEncode_h__ */

View file

@ -0,0 +1,172 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/* 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 "nsIFile.h"
#include "nsImportScanFile.h"
#include "ImportCharSet.h"
nsImportScanFile::nsImportScanFile()
{
m_allocated = false;
m_eof = false;
m_pBuf = nullptr;
}
nsImportScanFile::~nsImportScanFile()
{
if (m_allocated)
CleanUpScan();
}
void nsImportScanFile::InitScan(nsIInputStream *pInputStream, uint8_t * pBuf, uint32_t sz)
{
m_pInputStream = pInputStream;
m_pBuf = pBuf;
m_bufSz = sz;
m_bytesInBuf = 0;
m_pos = 0;
}
void nsImportScanFile::CleanUpScan(void)
{
m_pInputStream = nullptr;
if (m_allocated) {
delete [] m_pBuf;
m_pBuf = NULL;
}
}
void nsImportScanFile::ShiftBuffer(void)
{
uint8_t * pTop;
uint8_t * pCurrent;
if (m_pos < m_bytesInBuf) {
pTop = m_pBuf;
pCurrent = pTop + m_pos;
uint32_t cnt = m_bytesInBuf - m_pos;
while (cnt) {
*pTop = *pCurrent;
pTop++; pCurrent++;
cnt--;
}
}
m_bytesInBuf -= m_pos;
m_pos = 0;
}
bool nsImportScanFile::FillBufferFromFile(void)
{
uint64_t available;
nsresult rv = m_pInputStream->Available(&available);
if (NS_FAILED(rv))
return false;
// Fill up a buffer and scan it
ShiftBuffer();
// Read in some more bytes
uint32_t cnt = m_bufSz - m_bytesInBuf;
// To distinguish from disk errors
// Check first for end of file?
// Set a done flag if true...
uint32_t read;
char *pBuf = (char *)m_pBuf;
pBuf += m_bytesInBuf;
rv = m_pInputStream->Read(pBuf, (int32_t) cnt, &read);
if (NS_FAILED(rv))
return false;
rv = m_pInputStream->Available(&available);
if (NS_FAILED(rv))
m_eof = true;
m_bytesInBuf += cnt;
return true;
}
bool nsImportScanFile::Scan(bool *pDone)
{
uint64_t available;
nsresult rv = m_pInputStream->Available(&available);
if (NS_FAILED(rv))
{
if (m_pos < m_bytesInBuf)
ScanBuffer(pDone);
*pDone = true;
return true;
}
// Fill up a buffer and scan it
if (!FillBufferFromFile())
return false;
return ScanBuffer(pDone);
}
bool nsImportScanFile::ScanBuffer(bool *)
{
return true;
}
bool nsImportScanFileLines::ScanBuffer(bool *pDone)
{
// m_pos, m_bytesInBuf, m_eof, m_pBuf are relevant
uint32_t pos = m_pos;
uint32_t max = m_bytesInBuf;
uint8_t * pChar = m_pBuf + pos;
uint32_t startPos;
while (pos < max) {
if (m_needEol) {
// Find the next eol...
while ((pos < max) && (*pChar != ImportCharSet::cCRChar) && (*pChar != ImportCharSet::cLinefeedChar)) {
pos++;
pChar++;
}
m_pos = pos;
if (pos < max)
m_needEol = false;
if (pos == max) // need more buffer for an end of line
break;
}
// Skip past any eol characters
while ((pos < max) && ((*pChar == ImportCharSet::cCRChar) || (*pChar == ImportCharSet::cLinefeedChar))) {
pos++;
pChar++;
}
m_pos = pos;
if (pos == max)
break;
// Make sure we can find either the eof or the
// next end of line
startPos = pos;
while ((pos < max) && (*pChar != ImportCharSet::cCRChar) && (*pChar != ImportCharSet::cLinefeedChar)) {
pos++;
pChar++;
}
// Is line too big for our buffer?
if ((pos == max) && !m_eof) {
if (!m_pos) { // line too big for our buffer
m_pos = pos;
m_needEol = true;
}
break;
}
if (!ProcessLine(m_pBuf + startPos, pos - startPos, pDone)) {
return false;
}
m_pos = pos;
}
return true;
}

View file

@ -0,0 +1,54 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/* 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 nsImportScanFile_h__
#define nsImportScanFile_h__
#include "mozilla/Attributes.h"
#include "nsCOMPtr.h"
#include "nsIInputStream.h"
class nsImportScanFile {
public:
nsImportScanFile();
virtual ~nsImportScanFile();
void InitScan(nsIInputStream *pInputStream, uint8_t * pBuf, uint32_t sz);
void CleanUpScan(void);
virtual bool Scan(bool *pDone);
protected:
void ShiftBuffer(void);
bool FillBufferFromFile(void);
virtual bool ScanBuffer(bool *pDone);
protected:
nsCOMPtr <nsIInputStream> m_pInputStream;
uint8_t * m_pBuf;
uint32_t m_bufSz;
uint32_t m_bytesInBuf;
uint32_t m_pos;
bool m_eof;
bool m_allocated;
};
class nsImportScanFileLines : public nsImportScanFile {
public:
nsImportScanFileLines() {m_needEol = false;}
void ResetLineScan(void) { m_needEol = false;}
virtual bool ProcessLine(uint8_t * /* pLine */, uint32_t /* len */, bool * /* pDone */) {return true;}
protected:
virtual bool ScanBuffer(bool *pDone) override;
bool m_needEol;
};
#endif /* nsImportScanFile_h__ */

View file

@ -0,0 +1,583 @@
/* -*- 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 "nsICharsetConverterManager.h"
#include "nsIPlatformCharset.h"
#include "nsICharsetConverterManager.h"
#include "nsStringGlue.h"
#include "nsIComponentManager.h"
#include "nsIServiceManager.h"
#include "nsMemory.h"
#include "nsIImportModule.h"
#include "nsIImportService.h"
#include "nsImportMailboxDescriptor.h"
#include "nsImportABDescriptor.h"
#include "nsIImportGeneric.h"
#include "nsImportFieldMap.h"
#include "nsICategoryManager.h"
#include "nsXPCOM.h"
#include "nsISupportsPrimitives.h"
#include "plstr.h"
#include "prmem.h"
#include "nsMsgCompCID.h"
#include "nsThreadUtils.h"
#include "nsIEditor.h"
#include "ImportDebug.h"
#include "nsImportService.h"
#include "nsImportStringBundle.h"
#include "nsCRTGlue.h"
#include "nsServiceManagerUtils.h"
#include "nsComponentManagerUtils.h"
#include "nsIMutableArray.h"
#include "nsIArray.h"
#include "nsIMsgSend.h"
#include "nsMsgUtils.h"
PRLogModuleInfo *IMPORTLOGMODULE = nullptr;
static nsIImportService * gImportService = nullptr;
static const char * kWhitespace = "\b\t\r\n ";
////////////////////////////////////////////////////////////////////////
nsImportService::nsImportService() : m_pModules(nullptr)
{
// Init logging module.
if (!IMPORTLOGMODULE)
IMPORTLOGMODULE = PR_NewLogModule("IMPORT");
IMPORT_LOG0("* nsImport Service Created\n");
m_didDiscovery = false;
m_pDecoder = nullptr;
m_pEncoder = nullptr;
nsresult rv = nsImportStringBundle::GetStringBundle(IMPORT_MSGS_URL, getter_AddRefs(m_stringBundle));
if (NS_FAILED(rv))
IMPORT_LOG0("Failed to get string bundle for Importing Mail");
}
nsImportService::~nsImportService()
{
NS_IF_RELEASE(m_pDecoder);
NS_IF_RELEASE(m_pEncoder);
gImportService = nullptr;
if (m_pModules != nullptr)
delete m_pModules;
IMPORT_LOG0("* nsImport Service Deleted\n");
}
NS_IMPL_ISUPPORTS(nsImportService, nsIImportService)
NS_IMETHODIMP nsImportService::DiscoverModules(void)
{
m_didDiscovery = false;
return DoDiscover();
}
NS_IMETHODIMP nsImportService::CreateNewFieldMap(nsIImportFieldMap **_retval)
{
return nsImportFieldMap::Create(m_stringBundle, nullptr, NS_GET_IID(nsIImportFieldMap), (void**)_retval);
}
NS_IMETHODIMP nsImportService::CreateNewMailboxDescriptor(nsIImportMailboxDescriptor **_retval)
{
return nsImportMailboxDescriptor::Create(nullptr, NS_GET_IID(nsIImportMailboxDescriptor), (void**)_retval);
}
NS_IMETHODIMP nsImportService::CreateNewABDescriptor(nsIImportABDescriptor **_retval)
{
return nsImportABDescriptor::Create(nullptr, NS_GET_IID(nsIImportABDescriptor), (void**)_retval);
}
extern nsresult NS_NewGenericMail(nsIImportGeneric** aImportGeneric);
NS_IMETHODIMP nsImportService::CreateNewGenericMail(nsIImportGeneric **_retval)
{
NS_PRECONDITION(_retval != nullptr, "null ptr");
if (! _retval)
return NS_ERROR_NULL_POINTER;
return NS_NewGenericMail(_retval);
}
extern nsresult NS_NewGenericAddressBooks(nsIImportGeneric** aImportGeneric);
NS_IMETHODIMP nsImportService::CreateNewGenericAddressBooks(nsIImportGeneric **_retval)
{
NS_PRECONDITION(_retval != nullptr, "null ptr");
if (! _retval)
return NS_ERROR_NULL_POINTER;
return NS_NewGenericAddressBooks(_retval);
}
NS_IMETHODIMP nsImportService::GetModuleCount(const char *filter, int32_t *_retval)
{
NS_PRECONDITION(_retval != nullptr, "null ptr");
if (! _retval)
return NS_ERROR_NULL_POINTER;
DoDiscover();
if (m_pModules != nullptr) {
ImportModuleDesc * pDesc;
int32_t count = 0;
for (int32_t i = 0; i < m_pModules->GetCount(); i++) {
pDesc = m_pModules->GetModuleDesc(i);
if (pDesc->SupportsThings(filter))
count++;
}
*_retval = count;
}
else
*_retval = 0;
return NS_OK;
}
NS_IMETHODIMP nsImportService::GetModuleWithCID(const nsCID& cid, nsIImportModule **ppModule)
{
NS_PRECONDITION(ppModule != nullptr, "null ptr");
if (!ppModule)
return NS_ERROR_NULL_POINTER;
*ppModule = nullptr;
nsresult rv = DoDiscover();
if (NS_FAILED(rv))
return rv;
if (m_pModules == nullptr)
return NS_ERROR_FAILURE;
int32_t cnt = m_pModules->GetCount();
ImportModuleDesc *pDesc;
for (int32_t i = 0; i < cnt; i++) {
pDesc = m_pModules->GetModuleDesc(i);
if (!pDesc)
return NS_ERROR_FAILURE;
if (pDesc->GetCID().Equals(cid)) {
*ppModule = pDesc->GetModule();
IMPORT_LOG0("* nsImportService::GetSpecificModule - attempted to load module\n");
if (*ppModule == nullptr)
return NS_ERROR_FAILURE;
return NS_OK;
}
}
IMPORT_LOG0("* nsImportService::GetSpecificModule - module not found\n");
return NS_ERROR_NOT_AVAILABLE;
}
NS_IMETHODIMP nsImportService::GetModuleInfo(const char *filter, int32_t index, char16_t **name, char16_t **moduleDescription)
{
NS_PRECONDITION(name != nullptr, "null ptr");
NS_PRECONDITION(moduleDescription != nullptr, "null ptr");
if (!name || !moduleDescription)
return NS_ERROR_NULL_POINTER;
*name = nullptr;
*moduleDescription = nullptr;
DoDiscover();
if (!m_pModules)
return NS_ERROR_FAILURE;
if ((index < 0) || (index >= m_pModules->GetCount()))
return NS_ERROR_FAILURE;
ImportModuleDesc * pDesc;
int32_t count = 0;
for (int32_t i = 0; i < m_pModules->GetCount(); i++) {
pDesc = m_pModules->GetModuleDesc(i);
if (pDesc->SupportsThings(filter)) {
if (count == index) {
*name = NS_strdup(pDesc->GetName());
*moduleDescription = NS_strdup(pDesc->GetDescription());
return NS_OK;
}
else
count++;
}
}
return NS_ERROR_FAILURE;
}
NS_IMETHODIMP nsImportService::GetModuleName(const char *filter, int32_t index, char16_t **_retval)
{
NS_PRECONDITION(_retval != nullptr, "null ptr");
if (!_retval)
return NS_ERROR_NULL_POINTER;
*_retval = nullptr;
DoDiscover();
if (!m_pModules)
return NS_ERROR_FAILURE;
if ((index < 0) || (index >= m_pModules->GetCount()))
return NS_ERROR_FAILURE;
ImportModuleDesc * pDesc;
int32_t count = 0;
for (int32_t i = 0; i < m_pModules->GetCount(); i++) {
pDesc = m_pModules->GetModuleDesc(i);
if (pDesc->SupportsThings(filter)) {
if (count == index) {
*_retval = NS_strdup(pDesc->GetName());
return NS_OK;
}
else
count++;
}
}
return NS_ERROR_FAILURE;
}
NS_IMETHODIMP nsImportService::GetModuleDescription(const char *filter, int32_t index, char16_t **_retval)
{
NS_PRECONDITION(_retval != nullptr, "null ptr");
if (!_retval)
return NS_ERROR_NULL_POINTER;
*_retval = nullptr;
DoDiscover();
if (!m_pModules)
return NS_ERROR_FAILURE;
if ((index < 0) || (index >= m_pModules->GetCount()))
return NS_ERROR_FAILURE;
ImportModuleDesc * pDesc;
int32_t count = 0;
for (int32_t i = 0; i < m_pModules->GetCount(); i++) {
pDesc = m_pModules->GetModuleDesc(i);
if (pDesc->SupportsThings(filter)) {
if (count == index) {
*_retval = NS_strdup(pDesc->GetDescription());
return NS_OK;
}
else
count++;
}
}
return NS_ERROR_FAILURE;
}
class nsProxySendRunnable : public mozilla::Runnable
{
public:
nsProxySendRunnable(nsIMsgIdentity *aIdentity,
nsIMsgCompFields *aMsgFields,
const char *attachment1_type,
const nsACString &attachment1_body,
bool aIsDraft,
nsIArray *aLoadedAttachments,
nsIArray *aEmbeddedAttachments,
nsIMsgSendListener *aListener);
NS_DECL_NSIRUNNABLE
private:
nsCOMPtr<nsIMsgIdentity> m_identity;
nsCOMPtr<nsIMsgCompFields> m_compFields;
bool m_isDraft;
nsCString m_bodyType;
nsCString m_body;
nsCOMPtr<nsIArray> m_loadedAttachments;
nsCOMPtr<nsIArray> m_embeddedAttachments;
nsCOMPtr<nsIMsgSendListener> m_listener;
};
nsProxySendRunnable::nsProxySendRunnable(nsIMsgIdentity *aIdentity,
nsIMsgCompFields *aMsgFields,
const char *aBodyType,
const nsACString &aBody,
bool aIsDraft,
nsIArray *aLoadedAttachments,
nsIArray *aEmbeddedAttachments,
nsIMsgSendListener *aListener) :
m_identity(aIdentity), m_compFields(aMsgFields),
m_isDraft(aIsDraft), m_bodyType(aBodyType),
m_body(aBody), m_loadedAttachments(aLoadedAttachments),
m_embeddedAttachments(aEmbeddedAttachments),
m_listener(aListener)
{
}
NS_IMETHODIMP nsProxySendRunnable::Run()
{
nsresult rv;
nsCOMPtr<nsIMsgSend> msgSend = do_CreateInstance(NS_MSGSEND_CONTRACTID, &rv);
NS_ENSURE_SUCCESS(rv, rv);
return msgSend->CreateRFC822Message(m_identity, m_compFields,
m_bodyType.get(), m_body,
m_isDraft, m_loadedAttachments,
m_embeddedAttachments,
m_listener);
}
NS_IMETHODIMP
nsImportService::CreateRFC822Message(nsIMsgIdentity *aIdentity,
nsIMsgCompFields *aMsgFields,
const char *aBodyType,
const nsACString &aBody,
bool aIsDraft,
nsIArray *aLoadedAttachments,
nsIArray *aEmbeddedAttachments,
nsIMsgSendListener *aListener)
{
RefPtr<nsProxySendRunnable> runnable =
new nsProxySendRunnable(aIdentity,
aMsgFields,
aBodyType,
aBody,
aIsDraft,
aLoadedAttachments,
aEmbeddedAttachments,
aListener);
// invoke the callback
return NS_DispatchToMainThread(runnable);
}
NS_IMETHODIMP nsImportService::GetModule(const char *filter, int32_t index, nsIImportModule **_retval)
{
NS_PRECONDITION(_retval != nullptr, "null ptr");
if (!_retval)
return NS_ERROR_NULL_POINTER;
*_retval = nullptr;
DoDiscover();
if (!m_pModules)
return NS_ERROR_FAILURE;
if ((index < 0) || (index >= m_pModules->GetCount()))
return NS_ERROR_FAILURE;
ImportModuleDesc * pDesc;
int32_t count = 0;
for (int32_t i = 0; i < m_pModules->GetCount(); i++) {
pDesc = m_pModules->GetModuleDesc(i);
if (pDesc->SupportsThings(filter)) {
if (count == index) {
*_retval = pDesc->GetModule();
break;
}
else
count++;
}
}
if (! (*_retval))
return NS_ERROR_FAILURE;
return NS_OK;
}
nsresult nsImportService::DoDiscover(void)
{
if (m_didDiscovery)
return NS_OK;
if (m_pModules != nullptr)
m_pModules->ClearList();
nsresult rv;
nsCOMPtr<nsICategoryManager> catMan = do_GetService(NS_CATEGORYMANAGER_CONTRACTID, &rv);
NS_ENSURE_SUCCESS(rv, rv);
nsCOMPtr<nsISimpleEnumerator> e;
rv = catMan->EnumerateCategory("mailnewsimport", getter_AddRefs(e));
NS_ENSURE_SUCCESS(rv, rv);
nsCOMPtr<nsISupports> supports;
nsCOMPtr<nsISupportsCString> contractid;
rv = e->GetNext(getter_AddRefs(supports));
while (NS_SUCCEEDED(rv) && supports)
{
contractid = do_QueryInterface(supports);
if (!contractid)
break;
nsCString contractIdStr;
contractid->ToString(getter_Copies(contractIdStr));
nsCString supportsStr;
rv = catMan->GetCategoryEntry("mailnewsimport", contractIdStr.get(), getter_Copies(supportsStr));
if (NS_SUCCEEDED(rv))
LoadModuleInfo(contractIdStr.get(), supportsStr.get());
rv = e->GetNext(getter_AddRefs(supports));
}
m_didDiscovery = true;
return NS_OK;
}
nsresult nsImportService::LoadModuleInfo(const char *pClsId, const char *pSupports)
{
if (!pClsId || !pSupports)
return NS_OK;
if (m_pModules == nullptr)
m_pModules = new nsImportModuleList();
// load the component and get all of the info we need from it....
// then call AddModule
nsresult rv;
nsCID clsId;
clsId.Parse(pClsId);
nsIImportModule * module;
rv = CallCreateInstance(clsId, &module);
if (NS_FAILED(rv)) return rv;
nsString theTitle;
nsString theDescription;
rv = module->GetName(getter_Copies(theTitle));
if (NS_FAILED(rv))
theTitle.AssignLiteral("Unknown");
rv = module->GetDescription(getter_Copies(theDescription));
if (NS_FAILED(rv))
theDescription.AssignLiteral("Unknown description");
// call the module to get the info we need
m_pModules->AddModule(clsId, pSupports, theTitle.get(), theDescription.get());
module->Release();
return NS_OK;
}
nsIImportModule *ImportModuleDesc::GetModule(bool keepLoaded)
{
if (m_pModule)
{
m_pModule->AddRef();
return m_pModule;
}
nsresult rv;
rv = CallCreateInstance(m_cid, &m_pModule);
if (NS_FAILED(rv))
{
m_pModule = nullptr;
return nullptr;
}
if (keepLoaded)
{
m_pModule->AddRef();
return m_pModule;
}
else
{
nsIImportModule *pModule = m_pModule;
m_pModule = nullptr;
return pModule;
}
}
void ImportModuleDesc::ReleaseModule(void)
{
if (m_pModule)
{
m_pModule->Release();
m_pModule = nullptr;
}
}
bool ImportModuleDesc::SupportsThings(const char *pThings)
{
if (!pThings || !*pThings)
return true;
nsCString thing(pThings);
nsCString item;
int32_t idx;
while ((idx = thing.FindChar(',')) != -1)
{
item = StringHead(thing, idx);
item.Trim(kWhitespace);
ToLowerCase(item);
if (item.Length() && (m_supports.Find(item) == -1))
return false;
thing = Substring(thing, idx + 1);
}
thing.Trim(kWhitespace);
ToLowerCase(thing);
return thing.IsEmpty() || (m_supports.Find(thing) != -1);
}
void nsImportModuleList::ClearList(void)
{
if (m_pList)
{
for (int i = 0; i < m_count; i++)
{
delete m_pList[i];
m_pList[i] = nullptr;
}
m_count = 0;
delete [] m_pList;
m_pList = nullptr;
m_alloc = 0;
}
}
void nsImportModuleList::AddModule(const nsCID& cid, const char *pSupports, const char16_t *pName, const char16_t *pDesc)
{
if (!m_pList)
{
m_alloc = 10;
m_pList = new ImportModuleDesc *[m_alloc];
m_count = 0;
memset(m_pList, 0, sizeof(ImportModuleDesc *) * m_alloc);
}
if (m_count == m_alloc)
{
ImportModuleDesc **pList = new ImportModuleDesc *[m_alloc + 10];
memset(&(pList[m_alloc]), 0, sizeof(ImportModuleDesc *) * 10);
memcpy(pList, m_pList, sizeof(ImportModuleDesc *) * m_alloc);
for(int i = 0; i < m_count; i++)
delete m_pList[i];
delete [] m_pList;
m_pList = pList;
m_alloc += 10;
}
m_pList[m_count] = new ImportModuleDesc();
m_pList[m_count]->SetCID(cid);
m_pList[m_count]->SetSupports(pSupports);
m_pList[m_count]->SetName(pName);
m_pList[m_count]->SetDescription(pDesc);
m_count++;
#ifdef IMPORT_DEBUG
IMPORT_LOG3("* nsImportService registered import module: %s, %s, %s\n", NS_LossyConvertUTF16toASCII(pName).get(), NS_LossyConvertUTF16toASCII(pDesc).get(), pSupports);
#endif
}

View file

@ -0,0 +1,96 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/* 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 nsImportService_h__
#define nsImportService_h__
#include "nsICharsetConverterManager.h"
#include "nsStringGlue.h"
#include "nsIComponentManager.h"
#include "nsIServiceManager.h"
#include "nsMemory.h"
#include "nsIImportModule.h"
#include "nsIImportService.h"
#include "nsICategoryManager.h"
#include "nsIStringBundle.h"
class nsImportModuleList;
class nsImportService : public nsIImportService
{
public:
nsImportService();
NS_DECL_THREADSAFE_ISUPPORTS
NS_DECL_NSIIMPORTSERVICE
private:
virtual ~nsImportService();
nsresult LoadModuleInfo(const char*pClsId, const char *pSupports);
nsresult DoDiscover(void);
private:
nsImportModuleList * m_pModules;
bool m_didDiscovery;
nsCString m_sysCharset;
nsIUnicodeDecoder * m_pDecoder;
nsIUnicodeEncoder * m_pEncoder;
nsCOMPtr<nsIStringBundle> m_stringBundle;
};
class ImportModuleDesc {
public:
ImportModuleDesc() { m_pModule = nullptr;}
~ImportModuleDesc() { ReleaseModule(); }
void SetCID(const nsCID& cid) { m_cid = cid;}
void SetName(const char16_t *pName) { m_name = pName;}
void SetDescription(const char16_t *pDesc) { m_description = pDesc;}
void SetSupports(const char *pSupports) { m_supports = pSupports;}
nsCID GetCID(void) { return m_cid;}
const char16_t *GetName(void) { return m_name.get();}
const char16_t *GetDescription(void) { return m_description.get();}
const char * GetSupports(void) { return m_supports.get();}
nsIImportModule * GetModule(bool keepLoaded = false); // Adds ref
void ReleaseModule(void);
bool SupportsThings(const char *pThings);
private:
nsCID m_cid;
nsString m_name;
nsString m_description;
nsCString m_supports;
nsIImportModule *m_pModule;
};
class nsImportModuleList {
public:
nsImportModuleList() { m_pList = nullptr; m_alloc = 0; m_count = 0;}
~nsImportModuleList() { ClearList(); }
void AddModule(const nsCID& cid, const char *pSupports, const char16_t *pName, const char16_t *pDesc);
void ClearList(void);
int32_t GetCount(void) { return m_count;}
ImportModuleDesc * GetModuleDesc(int32_t idx)
{ if ((idx < 0) || (idx >= m_count)) return nullptr; else return m_pList[idx];}
private:
private:
ImportModuleDesc ** m_pList;
int32_t m_alloc;
int32_t m_count;
};
#endif // nsImportService_h__

View file

@ -0,0 +1,80 @@
/* -*- 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 "prprf.h"
#include "prmem.h"
#include "nsCOMPtr.h"
#include "nsIStringBundle.h"
#include "nsImportStringBundle.h"
#include "nsIServiceManager.h"
#include "nsIURI.h"
#include "nsServiceManagerUtils.h"
#include "nsComponentManagerUtils.h"
#include "mozilla/Services.h"
nsresult nsImportStringBundle::GetStringBundle(const char *aPropertyURL,
nsIStringBundle **aBundle)
{
nsresult rv;
nsCOMPtr<nsIStringBundleService> sBundleService =
mozilla::services::GetStringBundleService();
NS_ENSURE_TRUE(sBundleService, NS_ERROR_UNEXPECTED);
rv = sBundleService->CreateBundle(aPropertyURL, aBundle);
return rv;
}
void nsImportStringBundle::GetStringByID(int32_t aStringID,
nsIStringBundle *aBundle,
nsString &aResult)
{
aResult.Adopt(GetStringByID(aStringID, aBundle));
}
char16_t *nsImportStringBundle::GetStringByID(int32_t aStringID,
nsIStringBundle *aBundle)
{
if (aBundle)
{
char16_t *ptrv = nullptr;
nsresult rv = aBundle->GetStringFromID(aStringID, &ptrv);
if (NS_SUCCEEDED(rv) && ptrv)
return ptrv;
}
nsString resultString(NS_LITERAL_STRING("[StringID "));
resultString.AppendInt(aStringID);
resultString.AppendLiteral("?]");
return ToNewUnicode(resultString);
}
void nsImportStringBundle::GetStringByName(const char *aName,
nsIStringBundle *aBundle,
nsString &aResult)
{
aResult.Adopt(GetStringByName(aName, aBundle));
}
char16_t *nsImportStringBundle::GetStringByName(const char *aName,
nsIStringBundle *aBundle)
{
if (aBundle)
{
char16_t *ptrv = nullptr;
nsresult rv = aBundle->GetStringFromName(
NS_ConvertUTF8toUTF16(aName).get(), &ptrv);
if (NS_SUCCEEDED(rv) && ptrv)
return ptrv;
}
nsString resultString(NS_LITERAL_STRING("[StringName "));
resultString.Append(NS_ConvertUTF8toUTF16(aName).get());
resultString.AppendLiteral("?]");
return ToNewUnicode(resultString);
}

View file

@ -0,0 +1,48 @@
/* 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 _nsImportStringBundle_H__
#define _nsImportStringBundle_H__
#include "nsStringGlue.h"
class nsIStringBundle;
class nsImportStringBundle
{
public:
static char16_t* GetStringByID(int32_t aStringID,
nsIStringBundle *aBundle = nullptr);
static void GetStringByID(int32_t aStringID,
nsIStringBundle *aBundle,
nsString &aResult);
static char16_t* GetStringByName(const char *aName,
nsIStringBundle *aBundle = nullptr);
static void GetStringByName(const char *aName,
nsIStringBundle *aBundle,
nsString &aResult);
static nsresult GetStringBundle(const char *aPropertyURL,
nsIStringBundle **aBundle);
};
#define IMPORT_MSGS_URL "chrome://messenger/locale/importMsgs.properties"
#define IMPORT_NO_ADDRBOOKS 2000
#define IMPORT_ERROR_AB_NOTINITIALIZED 2001
#define IMPORT_ERROR_AB_NOTHREAD 2002
#define IMPORT_ERROR_GETABOOK 2003
#define IMPORT_NO_MAILBOXES 2004
#define IMPORT_ERROR_MB_NOTINITIALIZED 2005
#define IMPORT_ERROR_MB_NOTHREAD 2006
#define IMPORT_ERROR_MB_NOPROXY 2007
#define IMPORT_ERROR_MB_FINDCHILD 2008
#define IMPORT_ERROR_MB_CREATE 2009
#define IMPORT_ERROR_MB_NODESTFOLDER 2010
#define IMPORT_FIELD_DESC_START 2100
#define IMPORT_FIELD_DESC_END 2136
#endif /* _nsImportStringBundle_H__ */

View file

@ -0,0 +1,296 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/* 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 "ImportOutFile.h"
#include "nsImportTranslator.h"
#include "ImportCharSet.h"
bool nsImportTranslator::ConvertToFile(const uint8_t * pIn, uint32_t inLen, ImportOutFile *pOutFile, uint32_t *pProcessed)
{
if (pProcessed)
*pProcessed = inLen;
return (pOutFile->WriteData(pIn, inLen));
}
void CMHTranslator::ConvertBuffer(const uint8_t * pIn, uint32_t inLen, uint8_t * pOut)
{
while (inLen) {
if (!ImportCharSet::IsUSAscii(*pIn) || ImportCharSet::Is822SpecialChar(*pIn) || ImportCharSet::Is822CtlChar(*pIn) ||
(*pIn == ImportCharSet::cSpaceChar) || (*pIn == '*') || (*pIn == '\'') ||
(*pIn == '%')) {
// needs to be encode as %hex val
*pOut = '%'; pOut++;
ImportCharSet::ByteToHex(*pIn, pOut);
pOut += 2;
}
else {
*pOut = *pIn;
pOut++;
}
pIn++; inLen--;
}
*pOut = 0;
}
bool CMHTranslator::ConvertToFile(const uint8_t * pIn, uint32_t inLen, ImportOutFile *pOutFile, uint32_t *pProcessed)
{
uint8_t hex[2];
while (inLen) {
if (!ImportCharSet::IsUSAscii(*pIn) || ImportCharSet::Is822SpecialChar(*pIn) || ImportCharSet::Is822CtlChar(*pIn) ||
(*pIn == ImportCharSet::cSpaceChar) || (*pIn == '*') || (*pIn == '\'') ||
(*pIn == '%')) {
// needs to be encode as %hex val
if (!pOutFile->WriteByte('%'))
return false;
ImportCharSet::ByteToHex(*pIn, hex);
if (!pOutFile->WriteData(hex, 2))
return false;
}
else {
if (!pOutFile->WriteByte(*pIn))
return false;
}
pIn++; inLen--;
}
if (pProcessed)
*pProcessed = inLen;
return true;
}
bool C2047Translator::ConvertToFileQ(const uint8_t * pIn, uint32_t inLen, ImportOutFile *pOutFile, uint32_t *pProcessed)
{
if (!inLen)
return true;
int maxLineLen = 64;
int curLineLen = m_startLen;
bool startLine = true;
uint8_t hex[2];
while (inLen) {
if (startLine) {
if (!pOutFile->WriteStr(" =?"))
return false;
if (!pOutFile->WriteStr(m_charset.get()))
return false;
if (!pOutFile->WriteStr("?q?"))
return false;
curLineLen += (6 + m_charset.Length());
startLine = false;
}
if (!ImportCharSet::IsUSAscii(*pIn) || ImportCharSet::Is822SpecialChar(*pIn) || ImportCharSet::Is822CtlChar(*pIn) ||
(*pIn == ImportCharSet::cSpaceChar) || (*pIn == '?') || (*pIn == '=')) {
// needs to be encode as =hex val
if (!pOutFile->WriteByte('='))
return false;
ImportCharSet::ByteToHex(*pIn, hex);
if (!pOutFile->WriteData(hex, 2))
return false;
curLineLen += 3;
}
else {
if (!pOutFile->WriteByte(*pIn))
return false;
curLineLen++;
}
pIn++; inLen--;
if (curLineLen > maxLineLen) {
if (!pOutFile->WriteStr("?="))
return false;
if (inLen) {
if (!pOutFile->WriteStr("\x0D\x0A "))
return false;
}
startLine = true;
curLineLen = 0;
}
}
if (!startLine) {
// end the encoding!
if (!pOutFile->WriteStr("?="))
return false;
}
if (pProcessed)
*pProcessed = inLen;
return true;
}
bool C2047Translator::ConvertToFile(const uint8_t * pIn, uint32_t inLen, ImportOutFile *pOutFile, uint32_t *pProcessed)
{
if (m_useQuotedPrintable)
return ConvertToFileQ(pIn, inLen, pOutFile, pProcessed);
if (!inLen)
return true;
int maxLineLen = 64;
int curLineLen = m_startLen;
bool startLine = true;
int encodeMax;
uint8_t * pEncoded = new uint8_t[maxLineLen * 2];
while (inLen) {
if (startLine) {
if (!pOutFile->WriteStr(" =?")) {
delete [] pEncoded;
return false;
}
if (!pOutFile->WriteStr(m_charset.get())) {
delete [] pEncoded;
return false;
}
if (!pOutFile->WriteStr("?b?")) {
delete [] pEncoded;
return false;
}
curLineLen += (6 + m_charset.Length());
startLine = false;
}
encodeMax = maxLineLen - curLineLen;
encodeMax *= 3;
encodeMax /= 4;
if ((uint32_t)encodeMax > inLen)
encodeMax = (int)inLen;
// encode the line, end the line
// then continue. Update curLineLen, pIn, startLine, and inLen
UMimeEncode::ConvertBuffer(pIn, encodeMax, pEncoded, maxLineLen, maxLineLen, "\x0D\x0A");
if (!pOutFile->WriteStr((const char *)pEncoded)) {
delete [] pEncoded;
return false;
}
pIn += encodeMax;
inLen -= encodeMax;
startLine = true;
curLineLen = 0;
if (!pOutFile->WriteStr("?=")) {
delete [] pEncoded;
return false;
}
if (inLen) {
if (!pOutFile->WriteStr("\x0D\x0A ")) {
delete [] pEncoded;
return false;
}
}
}
delete [] pEncoded;
if (pProcessed)
*pProcessed = inLen;
return true;
}
uint32_t UMimeEncode::GetBufferSize(uint32_t inBytes)
{
// it takes 4 base64 bytes to represent 3 regular bytes
inBytes += 3;
inBytes /= 3;
inBytes *= 4;
// This should be plenty, but just to be safe
inBytes += 4;
// now allow for end of line characters
inBytes += ((inBytes + 39) / 40) * 4;
return inBytes;
}
static uint8_t gBase64[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
uint32_t UMimeEncode::ConvertBuffer(const uint8_t * pIn, uint32_t inLen, uint8_t * pOut, uint32_t maxLen, uint32_t firstLineLen, const char * pEolStr)
{
uint32_t pos = 0;
uint32_t len = 0;
uint32_t lineLen = 0;
uint32_t maxLine = firstLineLen;
int eolLen = 0;
if (pEolStr)
eolLen = strlen(pEolStr);
while ((pos + 2) < inLen) {
// Encode 3 bytes
*pOut = gBase64[*pIn >> 2];
pOut++; len++; lineLen++;
*pOut = gBase64[(((*pIn) & 0x3)<< 4) | (((*(pIn + 1)) & 0xF0) >> 4)];
pIn++; pOut++; len++; lineLen++;
*pOut = gBase64[(((*pIn) & 0xF) << 2) | (((*(pIn + 1)) & 0xC0) >>6)];
pIn++; pOut++; len++; lineLen++;
*pOut = gBase64[(*pIn) & 0x3F];
pIn++; pOut++; len++; lineLen++;
pos += 3;
if (lineLen >= maxLine) {
lineLen = 0;
maxLine = maxLen;
if (pEolStr) {
memcpy(pOut, pEolStr, eolLen);
pOut += eolLen;
len += eolLen;
}
}
}
if ((pos < inLen) && ((lineLen + 3) > maxLine)) {
lineLen = 0;
maxLine = maxLen;
if (pEolStr) {
memcpy(pOut, pEolStr, eolLen);
pOut += eolLen;
len += eolLen;
}
}
if (pos < inLen) {
// Get the last few bytes!
*pOut = gBase64[*pIn >> 2];
pOut++; len++;
pos++;
if (pos < inLen) {
*pOut = gBase64[(((*pIn) & 0x3)<< 4) | (((*(pIn + 1)) & 0xF0) >> 4)];
pIn++; pOut++; pos++; len++;
if (pos < inLen) {
// Should be dead code!! (Then why is it here doofus?)
*pOut = gBase64[(((*pIn) & 0xF) << 2) | (((*(pIn + 1)) & 0xC0) >>6)];
pIn++; pOut++; len++;
*pOut = gBase64[(*pIn) & 0x3F];
pos++; pOut++; len++;
}
else {
*pOut = gBase64[(((*pIn) & 0xF) << 2)];
pOut++; len++;
*pOut = '=';
pOut++; len++;
}
}
else {
*pOut = gBase64[(((*pIn) & 0x3)<< 4)];
pOut++; len++;
*pOut = '=';
pOut++; len++;
*pOut = '=';
pOut++; len++;
}
}
*pOut = 0;
return len;
}

View file

@ -0,0 +1,66 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/* 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 nsImportTranslator_h___
#define nsImportTranslator_h___
#include "mozilla/Attributes.h"
#include "nscore.h"
#include "nsStringGlue.h"
#include "nsCOMPtr.h"
class ImportOutFile;
class UMimeEncode {
public:
static uint32_t GetBufferSize(uint32_t inByes);
static uint32_t ConvertBuffer(const uint8_t * pIn, uint32_t inLen, uint8_t *pOut, uint32_t maxLen = 72, uint32_t firstLineLen = 72, const char * pEolStr = nullptr);
};
class nsImportTranslator {
public:
virtual ~nsImportTranslator() {}
virtual bool Supports8bitEncoding(void) { return false;}
virtual uint32_t GetMaxBufferSize(uint32_t inLen) { return inLen + 1;}
virtual void ConvertBuffer(const uint8_t * pIn, uint32_t inLen, uint8_t * pOut) { memcpy(pOut, pIn, inLen); pOut[inLen] = 0;}
virtual bool ConvertToFile(const uint8_t * pIn, uint32_t inLen, ImportOutFile *pOutFile, uint32_t *pProcessed = nullptr);
virtual bool FinishConvertToFile(ImportOutFile * /* pOutFile */) { return true;}
virtual void GetCharset(nsCString& charSet) { charSet = "us-ascii";}
virtual void GetLanguage(nsCString& lang) { lang = "en";}
virtual void GetEncoding(nsCString& encoding) { encoding.Truncate();}
};
// Specialized encoder, not a vaild language translator, used for Mime headers.
// rfc2231
class CMHTranslator : public nsImportTranslator {
public:
virtual uint32_t GetMaxBufferSize(uint32_t inLen) override { return (inLen * 3) + 1;}
virtual void ConvertBuffer(const uint8_t * pIn, uint32_t inLen, uint8_t * pOut) override;
virtual bool ConvertToFile(const uint8_t * pIn, uint32_t inLen, ImportOutFile *pOutFile, uint32_t *pProcessed = nullptr) override;
};
// Specialized encoder, not a vaild language translator, used for mail headers
// rfc2047
class C2047Translator : public nsImportTranslator {
public:
virtual ~C2047Translator() {}
C2047Translator(const char *pCharset, uint32_t headerLen) { m_charset = pCharset; m_startLen = headerLen; m_useQuotedPrintable = false;}
void SetUseQuotedPrintable(void) { m_useQuotedPrintable = true;}
virtual bool ConvertToFile(const uint8_t * pIn, uint32_t inLen, ImportOutFile *pOutFile, uint32_t *pProcessed = nullptr) override;
bool ConvertToFileQ(const uint8_t * pIn, uint32_t inLen, ImportOutFile *pOutFile, uint32_t *pProcessed);
protected:
bool m_useQuotedPrintable;
nsCString m_charset;
uint32_t m_startLen;
};
#endif /* nsImportTranslator_h__ */